Skip to content

Commit 1f448ed

Browse files
committed
店舗詳細ページ作成 その1
1 parent ad56631 commit 1f448ed

File tree

4 files changed

+219
-40
lines changed

4 files changed

+219
-40
lines changed

app/Http/Controllers/PostController.php

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ public function index(Request $request)
1919
$userId = 1;
2020
$this->post->setPagerInfo($request->input('page_id'));
2121

22-
$shopDetails = $this->post->getShopData();
22+
$shopData = $this->post->convShopData();
2323
$favorites = $this->post->getFavorites($userId);
2424
$pagerInfo = $this->post->getPagerInfo();
25-
25+
2626
$posts = [
27-
'shopDetails' => $shopDetails,
27+
'shopData' => $shopData,
2828
'favorites' => $favorites,
2929
'pagerInfo' => $pagerInfo,
3030
];
@@ -34,9 +34,15 @@ public function index(Request $request)
3434

3535
public function show()
3636
{
37-
$id = 1;
38-
$post = $this->post->getShopDetail($id);
39-
dd($post);
40-
return View('posts.show');
37+
$id = 10;
38+
$shopDetail = $this->post->convShopDetailData($id);
39+
$images = $this->post->getShopImages($id);
40+
41+
$post = [
42+
'shopDetail' => $shopDetail,
43+
'images' => $images,
44+
];
45+
46+
return View('posts.show', ['post' => $post]);
4147
}
4248
}

app/Services/PostService.php

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ public function getPagerInfo() {
2323
}
2424

2525
/**
26-
* 店舗情報を取得する
26+
* 店舗一覧情報をView用に変換する
2727
* @return array<int, object>
2828
*/
29-
public function getShopData(): array
29+
public function convShopData(): array
3030
{
3131
// 店舗情報を取得する
3232
$shopInfo = $this->getShopInfo();
@@ -53,6 +53,31 @@ public function getShopData(): array
5353
return $shopInfo;
5454
}
5555

56+
public function convShopDetailData($shopId)
57+
{
58+
// 店舗詳細情報を取得する
59+
$shopDetail = $this->getShopDetail($shopId);
60+
61+
// タグを全種類取得する
62+
$tags = $this->getAllTags();
63+
64+
// 以下、タグ名を追加する処理
65+
$tagIds = explode(',', $shopDetail['tags']);
66+
67+
// タグリストの初期化
68+
$tagList = [];
69+
70+
foreach ($tagIds as $tagId) {
71+
if (isset($tags[$tagId])) {
72+
$tagList = $tags[$tagId];
73+
}
74+
}
75+
76+
$shopDetail['tags'] = $tagList;
77+
78+
return $shopDetail;
79+
}
80+
5681
/**
5782
* 店舗情報をDBから取得する
5883
* @return array<int, object>
@@ -123,11 +148,11 @@ private function pager(array $shopData): array
123148
}
124149

125150
/**
126-
* 投稿詳細店舗
151+
* 店舗詳細を取得
127152
* @param $shopId 店舗id
128153
* @return array 店舗情報
129154
*/
130-
public function getShopDetail(int $shopId): array
155+
public function getShopDetail(int $shopId)
131156
{
132157
$sql = 'SELECT posts.id, posts.shopname, posts.tags,'.PHP_EOL;
133158
$sql .= 'ROUND(AVG(rating)::numeric, 1) AS avg_rating, post_details.address'.PHP_EOL;
@@ -140,6 +165,19 @@ public function getShopDetail(int $shopId): array
140165
$sql .= 'GROUP BY posts.id, posts.shopname, posts.tags, posts.deleted_flg, post_details.address'.PHP_EOL;
141166
$sql .= 'ORDER BY avg_rating DESC'.PHP_EOL;
142167

168+
$result = DB::select($sql, ['shopId' => $shopId]);
169+
170+
return !empty($result) ? (array) current($result) : [];
171+
}
172+
173+
public function getShopImages($shopId)
174+
{
175+
$sql = 'SELECT images.image_url'.PHP_EOL;
176+
$sql .= 'FROM posts'.PHP_EOL;
177+
$sql .= ' INNER JOIN images'.PHP_EOL;
178+
$sql .= ' ON posts.id = images.post_id'.PHP_EOL;
179+
$sql .= ' WHERE posts.id = :shopId'.PHP_EOL;
180+
143181
return DB::select($sql, ['shopId' => $shopId]);
144182
}
145183
}

resources/views/posts/index.blade.php

Lines changed: 56 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,98 +7,126 @@
77
<style>
88
body {
99
font-family: Arial, sans-serif;
10-
margin: 20px;
11-
background-color: #f8f9fa;
10+
margin: 20px;
11+
background-color: #f1f3f5;
1212
}
13+
1314
h1 {
1415
text-align: center;
1516
color: #333;
17+
font-size: 28px;
18+
}
19+
20+
h2 a {
21+
display: inline-block;
22+
font-size: 20px;
23+
font-weight: bold;
24+
color: #007bff;
25+
text-decoration: none;
26+
padding: 6px 12px;
27+
border-radius: 5px;
28+
background-color: #f0f0f0;
29+
transition: background-color 0.3s;
30+
}
31+
32+
h2 a:hover {
33+
background-color: #e2e6ea;
1634
}
35+
1736
.container {
1837
max-width: 800px;
1938
margin: 0 auto;
2039
}
40+
2141
.post {
2242
display: flex;
2343
align-items: center;
2444
background: #fff;
25-
border-radius: 8px;
26-
padding: 15px;
27-
margin-bottom: 15px;
28-
box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.1);
45+
border-radius: 5px;
46+
padding: 12px;
47+
margin-bottom: 12px;
48+
box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
2949
}
50+
3051
.post img {
31-
width: 120px;
32-
height: 120px;
52+
width: 100px;
53+
height: 100px;
3354
object-fit: cover;
34-
border-radius: 8px;
35-
margin-right: 15px;
55+
border-radius: 5px;
56+
margin-right: 12px;
3657
}
58+
3759
.post-content {
3860
flex: 1;
3961
}
62+
4063
.post h2 {
41-
margin: 0 0 5px;
42-
color: #007bff;
43-
font-size: 20px;
64+
margin: 0 0 8px;
65+
font-size: 18px;
66+
color: #343a40;
4467
}
68+
4569
.post p {
4670
margin: 5px 0;
47-
font-size: 16px;
48-
color: #555;
71+
font-size: 14px;
72+
color: #495057;
4973
}
50-
/* タグのスタイル */
74+
5175
.tags {
5276
display: flex;
5377
flex-wrap: wrap;
5478
gap: 5px;
55-
margin-top: 5px;
79+
margin-top: 8px;
5680
}
81+
5782
.tag {
58-
background-color: #007bff;
83+
background-color: #6c757d;
5984
color: white;
6085
padding: 3px 8px;
6186
border-radius: 12px;
6287
font-size: 12px;
6388
}
64-
/* いいね(ハート) */
89+
6590
.likes {
66-
font-size: 18px;
67-
color: red;
91+
font-size: 16px;
92+
color: #e74c3c;
6893
display: flex;
6994
align-items: center;
7095
gap: 5px;
7196
}
72-
/* ページネーション */
97+
7398
.pagination {
7499
display: flex;
75100
justify-content: center;
76101
margin-top: 20px;
77102
}
103+
78104
.pagination a,
79105
.pagination span {
80-
margin: 0 5px;
81-
padding: 8px 12px;
106+
margin: 0 4px;
107+
padding: 6px 10px;
82108
text-decoration: none;
83-
background: #007bff;
109+
background-color: #007bff;
84110
color: #fff;
85111
border-radius: 5px;
112+
font-size: 14px;
86113
}
114+
87115
.pagination .active {
88-
background: #0056b3;
116+
background-color: #0056b3;
89117
}
90118
</style>
91119
</head>
92120
<body>
93121
<div class="container">
94122
<h1>投稿一覧</h1>
95-
@foreach ($posts['shopDetails'] as $post)
123+
@foreach ($posts['shopData'] as $post)
96124
<div class="post">
97125
@if($post->image_url)
98126
<img src="{{ $post->image_url }}" alt="画像">
99127
@endif
100128
<div class="post-content">
101-
<h2>{{ $post->shopname }}</h2>
129+
<h2><a href="/show/{{ $post->id }}">{{ $post->shopname }}</a></h2>
102130
<p>評価: <strong>{{ number_format($post->avg_rating, 1) }}</strong> ⭐</p>
103131

104132
<!-- タグ表示 -->
Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,108 @@
1-
<h1>詳細確認</h1>
1+
<!DOCTYPE html>
2+
<html lang="ja">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<meta name="csrf-token" content="{{ csrf_token() }}">
7+
<title>投稿詳細</title>
8+
9+
<link rel="stylesheet" href="{{ mix('css/app.css') }}">
10+
<script src="{{ mix('js/app.js') }}" defer></script>
11+
<style>
12+
body {
13+
font-family: Arial, sans-serif;
14+
margin: 20px;
15+
background-color: #f8f9fa;
16+
}
17+
h1 {
18+
text-align: center;
19+
color: #333;
20+
}
21+
.container {
22+
max-width: 500px;
23+
margin: 0 auto;
24+
}
25+
.post {
26+
background: #fff;
27+
border-radius: 8px;
28+
padding: 20px;
29+
box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.1);
30+
}
31+
.post img {
32+
/* width: 100%; */
33+
max-height: 300px;
34+
object-fit: cover;
35+
border-radius: 8px;
36+
margin-bottom: 15px;
37+
}
38+
.post h2 {
39+
color: #007bff;
40+
font-size: 24px;
41+
}
42+
.post p {
43+
font-size: 16px;
44+
color: #555;
45+
margin: 5px 0;
46+
}
47+
.tags {
48+
display: flex;
49+
flex-wrap: wrap;
50+
gap: 5px;
51+
margin-top: 10px;
52+
}
53+
.tag {
54+
background-color: #007bff;
55+
color: white;
56+
padding: 3px 8px;
57+
border-radius: 12px;
58+
font-size: 12px;
59+
}
60+
.likes {
61+
font-size: 18px;
62+
color: red;
63+
display: flex;
64+
align-items: center;
65+
gap: 5px;
66+
margin-top: 10px;
67+
}
68+
.back-link {
69+
display: block;
70+
text-align: center;
71+
margin-top: 20px;
72+
text-decoration: none;
73+
background: #007bff;
74+
color: white;
75+
padding: 10px;
76+
border-radius: 5px;
77+
}
78+
</style>
79+
</head>
80+
<body>
81+
<div class="container">
82+
<h1>投稿詳細</h1>
83+
<div class="post">
84+
@if(!empty($post['images']))
85+
<div class="slick-slider">
86+
@foreach($post['images'] as $image)
87+
<div><img src="{{ $image->image_url }}" alt="画像"></div>
88+
@endforeach
89+
</div>
90+
@endif
91+
<h2>{{ $post['shopDetail']['shopname'] }}</h2>
92+
<p>評価: <strong>{{ number_format($post['shopDetail']['avg_rating'], 1) }}</strong> ⭐</p>
93+
<p>住所: {{ $post['shopDetail']['address'] }}</p>
94+
95+
@if (!empty($post['shopDetail']->tags))
96+
<div class="tags">
97+
@foreach ($post['shopDetail']->tags as $tag)
98+
<span class="tag">{{ $tag->name }}</span>
99+
@endforeach
100+
</div>
101+
@endif
102+
103+
<p class="likes">❤️</p>
104+
</div>
105+
<a href="/" class="back-link">一覧に戻る</a>
106+
</div>
107+
</body>
108+
</html>

0 commit comments

Comments
 (0)