Skip to content

Commit 5ed49b6

Browse files
committed
Upvote if resource created
1 parent 9902bc6 commit 5ed49b6

File tree

4 files changed

+151
-108
lines changed

4 files changed

+151
-108
lines changed

app/Http/Controllers/ComputerScienceResourceController.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
use Illuminate\Support\Facades\DB;
1818
use Illuminate\Support\Facades\Log;
1919
use Inertia\Inertia;
20+
use App\Services\UpvoteService;
21+
2022
use Throwable;
2123

2224
class ComputerScienceResourceController extends Controller
@@ -26,6 +28,7 @@ public function __construct(
2628
protected GeneralVotesSortingManager $generalVotesSortingManager,
2729
protected ResourceReviewService $reviewService,
2830
protected ResourceSortingManager $resourceSortingManager,
31+
protected UpvoteService $upvoteService,
2932
) {}
3033

3134
/**
@@ -110,6 +113,8 @@ public function store(StoreResourceRequest $request)
110113

111114
DB::commit();
112115

116+
$this->upvoteService->upvote('resource', $resource->id);
117+
113118
Log::info('Resource created', [
114119
'resource_id' => $resource->id,
115120
'user_id' => Auth::id(),

app/Http/Controllers/UpvoteController.php

Lines changed: 12 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -2,130 +2,37 @@
22

33
namespace App\Http\Controllers;
44

5-
use App\Services\ModelResolverService;
6-
use Illuminate\Support\Facades\Auth;
7-
use Illuminate\Support\Facades\DB;
8-
use Illuminate\Support\Facades\Log;
9-
use Illuminate\Validation\Rule;
10-
use Throwable;
5+
use App\Services\UpvoteService;
116

127
class UpvoteController extends Controller
138
{
14-
public function __construct(protected ModelResolverService $modelResolver) {}
9+
public function __construct(protected UpvoteService $upvoteService) {}
1510

1611
/**
1712
* Upvote a Model
1813
*/
1914
public function upvote($typeKey, $id)
2015
{
21-
validator(
22-
[
23-
'type_key' => $typeKey,
24-
],
25-
[
26-
'type_key' => ['required', Rule::in(config('upvotes.upvotable_keys'))],
27-
]
28-
)->validate();
16+
$result = $this->upvoteService->upvote($typeKey, $id);
2917

30-
DB::beginTransaction();
31-
try {
32-
$model = $this->modelResolver->resolve($typeKey, $id);
33-
34-
if (! $model) {
35-
Log::warning('Upvote failed: Model not found', [
36-
'user_id' => Auth::id(),
37-
'type_key' => $typeKey,
38-
'id' => $id,
39-
]);
40-
41-
return response()->json(['message' => 'Model not found'], 404);
42-
}
43-
44-
$user_id = Auth::id();
45-
$result = $model->upvote($user_id);
46-
47-
DB::commit();
48-
49-
Log::debug('User upvoted model', [
50-
'user_id' => $user_id,
51-
'type_key' => $typeKey,
52-
'id' => $id,
53-
'result' => $result,
54-
]);
55-
56-
return response()->json([
57-
'userVote' => $result['userVote'],
58-
'changeFromVote' => $result['changeFromVote'],
59-
]);
60-
} catch (Throwable $e) {
61-
DB::rollBack();
62-
Log::critical('Failed to upvote', [
63-
'error' => $e->getMessage(),
64-
'trace' => $e->getTraceAsString(),
65-
'type_key' => $typeKey,
66-
'id' => $id,
67-
'user_id' => Auth::id(),
68-
]);
69-
70-
return response()->json(['message' => 'Failed to upvote. Please try again.'], 500);
18+
if (isset($result['error'])) {
19+
return response()->json(['message' => $result['error']], $result['status']);
7120
}
21+
22+
return response()->json($result);
7223
}
7324

7425
/**
7526
* Downvote a Model (type, id)
7627
*/
7728
public function downvote($typeKey, $id)
7829
{
79-
validator(
80-
[
81-
'type_key' => $typeKey,
82-
],
83-
[
84-
'type_key' => ['required', Rule::in(config('upvotes.upvotable_keys'))],
85-
]
86-
)->validate();
30+
$result = $this->upvoteService->downvote($typeKey, $id);
8731

88-
DB::beginTransaction();
89-
try {
90-
$model = $this->modelResolver->resolve($typeKey, $id);
91-
92-
if (! $model) {
93-
Log::warning('Downvote failed: Model not found', [
94-
'user_id' => Auth::id(),
95-
'type_key' => $typeKey,
96-
'id' => $id,
97-
]);
98-
99-
return response()->json(['message' => 'Model not found'], 404);
100-
}
101-
102-
$user_id = Auth::id();
103-
$result = $model->downvote($user_id);
104-
105-
DB::commit();
106-
107-
Log::debug('User downvoted model', [
108-
'user_id' => $user_id,
109-
'type_key' => $typeKey,
110-
'id' => $id,
111-
'result' => $result,
112-
]);
113-
114-
return response()->json([
115-
'userVote' => $result['userVote'],
116-
'changeFromVote' => $result['changeFromVote'],
117-
]);
118-
} catch (Throwable $e) {
119-
DB::rollBack();
120-
Log::critical('Failed to downvote', [
121-
'error' => $e->getMessage(),
122-
'trace' => $e->getTraceAsString(),
123-
'type_key' => $typeKey,
124-
'id' => $id,
125-
'user_id' => Auth::id(),
126-
]);
127-
128-
return response()->json(['message' => 'Failed to downvote. Please try again.'], 500);
32+
if (isset($result['error'])) {
33+
return response()->json(['message' => $result['error']], $result['status']);
12934
}
35+
36+
return response()->json($result);
13037
}
13138
}

app/Services/UpvoteService.php

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
<?php
2+
3+
namespace App\Services;
4+
5+
use App\Services\ModelResolverService;
6+
use Illuminate\Support\Facades\Auth;
7+
use Illuminate\Support\Facades\DB;
8+
use Illuminate\Support\Facades\Log;
9+
use Illuminate\Validation\Rule;
10+
use Throwable;
11+
12+
class UpvoteService
13+
{
14+
public function __construct(protected ModelResolverService $modelResolver) {}
15+
16+
/**
17+
* Upvote a Model
18+
*/
19+
public function upvote($typeKey, $id)
20+
{
21+
validator(
22+
[
23+
'type_key' => $typeKey,
24+
],
25+
[
26+
'type_key' => ['required', Rule::in(config('upvotes.upvotable_keys'))],
27+
]
28+
)->validate();
29+
30+
DB::beginTransaction();
31+
try {
32+
$model = $this->modelResolver->resolve($typeKey, $id);
33+
34+
if (! $model) {
35+
Log::warning('Upvote failed: Model not found', [
36+
'user_id' => Auth::id(),
37+
'type_key' => $typeKey,
38+
'id' => $id,
39+
]);
40+
41+
return ['error' => 'Model not found', 'status' => 404];
42+
}
43+
44+
$user_id = Auth::id();
45+
$result = $model->upvote($user_id);
46+
47+
DB::commit();
48+
49+
Log::debug('User upvoted model', [
50+
'user_id' => $user_id,
51+
'type_key' => $typeKey,
52+
'id' => $id,
53+
'result' => $result,
54+
]);
55+
56+
return [
57+
'userVote' => $result['userVote'],
58+
'changeFromVote' => $result['changeFromVote'],
59+
];
60+
} catch (Throwable $e) {
61+
DB::rollBack();
62+
Log::critical('Failed to upvote', [
63+
'error' => $e->getMessage(),
64+
'trace' => $e->getTraceAsString(),
65+
'type_key' => $typeKey,
66+
'id' => $id,
67+
'user_id' => Auth::id(),
68+
]);
69+
70+
return ['error' => 'Failed to upvote. Please try again.', 'status' => 500];
71+
}
72+
}
73+
74+
/**
75+
* Downvote a Model
76+
*/
77+
public function downvote($typeKey, $id)
78+
{
79+
validator(
80+
[
81+
'type_key' => $typeKey,
82+
],
83+
[
84+
'type_key' => ['required', Rule::in(config('upvotes.upvotable_keys'))],
85+
]
86+
)->validate();
87+
88+
DB::beginTransaction();
89+
try {
90+
$model = $this->modelResolver->resolve($typeKey, $id);
91+
92+
if (! $model) {
93+
Log::warning('Downvote failed: Model not found', [
94+
'user_id' => Auth::id(),
95+
'type_key' => $typeKey,
96+
'id' => $id,
97+
]);
98+
99+
return ['error' => 'Model not found', 'status' => 404];
100+
}
101+
102+
$user_id = Auth::id();
103+
$result = $model->downvote($user_id);
104+
105+
DB::commit();
106+
107+
Log::debug('User downvoted model', [
108+
'user_id' => $user_id,
109+
'type_key' => $typeKey,
110+
'id' => $id,
111+
'result' => $result,
112+
]);
113+
114+
return [
115+
'userVote' => $result['userVote'],
116+
'changeFromVote' => $result['changeFromVote'],
117+
];
118+
} catch (Throwable $e) {
119+
DB::rollBack();
120+
Log::critical('Failed to downvote', [
121+
'error' => $e->getMessage(),
122+
'trace' => $e->getTraceAsString(),
123+
'type_key' => $typeKey,
124+
'id' => $id,
125+
'user_id' => Auth::id(),
126+
]);
127+
128+
return ['error' => 'Failed to downvote. Please try again.', 'status' => 500];
129+
}
130+
}
131+
}

resources/js/Components/Form/TagSelector.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,8 @@ onMounted(async () => {
241241
@keydown="onKeydown"
242242
@focus="showDropdown = true"
243243
@blur="onBlur"
244-
placeholder="add tags..."
245-
class="w-full px-4 py-3 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary transition-all"
244+
placeholder="Add tags..."
245+
class="w-full px-3 py-2 text-md border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary transition-all"
246246
:class="{
247247
'rounded-b-none border-b-0':
248248
showDropdown &&
@@ -279,7 +279,7 @@ onMounted(async () => {
279279
:key="tag.name"
280280
@mousedown.prevent="selectTag(tag.name)"
281281
@mouseenter="highlightedIndex = index"
282-
class="flex items-center justify-between px-4 py-3 cursor-pointer transition-colors"
282+
class="flex items-center justify-between px-3 py-1.5 cursor-pointer transition-colors"
283283
:class="{
284284
'bg-secondary text-primaryDark':
285285
highlightedIndex === index,

0 commit comments

Comments
 (0)