Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions app/Http/Controllers/ComputerScienceResourceController.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,22 @@ class ComputerScienceResourceController extends Controller
{
public function __construct(
protected ComputerScienceResourceService $resourceService,
protected ComputerScienceResourceFilter $filterService
) {}

/**
* Display a listing of the resource.
*/
public function index(Request $request, ComputerScienceResourceFilter $filterService)
public function index(Request $request)
{
$query = ComputerScienceResource::query();

// Apply all filters and sorting
$filters = $request->query();
$query = $filterService->applyFilters($query, $filters);
$query = $this->filterService->applyFilters($query, $filters);

// Paginate with appended query params
$resources = $query->paginate(10)->appends($request->query());
$resources = $query->paginate(20)->appends($request->query());

$news = NewsPost::limit(10)->get();

Expand Down
6 changes: 3 additions & 3 deletions app/Http/Controllers/ResourceEditsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace App\Http\Controllers;

use App\Http\Requests\StoreResourceEdit;
use App\Http\Requests\StoreResourceEditRequest;
use App\Models\ComputerScienceResource;
use App\Models\ResourceEdits;
use App\Services\ResourceEditsService;
Expand Down Expand Up @@ -36,7 +36,7 @@ public function create(string $slug)
/**
* Store the edits request.
*/
public function store(ComputerScienceResource $computerScienceResource, StoreResourceEdit $request)
public function store(ComputerScienceResource $computerScienceResource, StoreResourceEditRequest $request)
{
$validatedData = $request->validated();
$proposedChanges = $validatedData['proposed_changes'] ?? [];
Expand Down Expand Up @@ -95,7 +95,7 @@ public function merge(ResourceEditsService $editsService, ResourceEdits $resourc

// Go through each property in proposed_changes, and if it exists. then set the value
$changes = $resourceEdits->proposed_changes;
$proposedFields = ['name', 'description', 'page_url', 'platforms', 'difficulty', 'pricing'];
$proposedFields = ['name', 'description', 'page_url', 'platforms', 'difficulties', 'pricing'];
foreach ($proposedFields as $field) {
if (array_key_exists($field, $changes)) {
$resource->$field = $changes[$field];
Expand Down
6 changes: 3 additions & 3 deletions app/Http/Controllers/ResourceReviewController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace App\Http\Controllers;

use App\Http\Requests\StoreResourceReview;
use App\Http\Requests\StoreResourceReviewRequest;
use App\Models\ComputerScienceResource;
use App\Models\ResourceReview;
use Illuminate\Support\Facades\Auth;
Expand All @@ -11,7 +11,7 @@
class ResourceReviewController extends Controller
{
// Store the review on the resource
public function store(StoreResourceReview $request, ComputerScienceResource $computerScienceResource)
public function store(StoreResourceReviewRequest $request, ComputerScienceResource $computerScienceResource)
{
// Validate the request data
$validatedData = $request->validated();
Expand Down Expand Up @@ -61,7 +61,7 @@ public function store(StoreResourceReview $request, ComputerScienceResource $com
return response()->json($review);
}

public function update(StoreResourceReview $request, ComputerScienceResource $computerScienceResource)
public function update(StoreResourceReviewRequest $request, ComputerScienceResource $computerScienceResource)
{
// Validate the request data
$validatedData = $request->validated();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\Rule;

class StoreResourceEdit extends FormRequest
class StoreResourceEditRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
Expand All @@ -30,14 +30,16 @@ public function rules(): array

'proposed_changes.name' => ['nullable', 'string', 'max:100'],
'proposed_changes.description' => ['nullable', 'string', 'max:10000'],
'proposed_changes.platforms' => ['nullable', 'array'],
'proposed_changes.platforms' => ['nullable', 'array', 'min:1'],
'proposed_changes.platforms.*' => ['required', 'distinct', 'string', Rule::in(config('computerScienceResource.platforms'))],
'proposed_changes.page_url' => ['nullable', 'string', 'url:http,https', 'max:255'],
'proposed_changes.difficulty' => ['nullable', 'string', Rule::in(config('computerScienceResource.difficulties'))],
'proposed_changes.difficulties' => ['nullable', 'array', 'min:1'],
'proposed_changes.difficulties.*' => ['required', 'distinct', 'string', Rule::in(config('computerScienceResource.difficulties'))],
'proposed_changes.pricing' => ['nullable', 'string', Rule::in(config('computerScienceResource.pricings'))],
'proposed_changes.image_file' => ['nullable', 'image', 'max:500'], // 500 kilobytes
'proposed_changes.topic_tags' => ['nullable', 'array', 'min:2'],
'proposed_changes.topic_tags.*' => ['required', 'distinct', 'string', 'max:50', 'regex:'.config('computerScienceResource.tags_regex')],

'proposed_changes.image_file' => ['nullable', 'image', 'max:500'], // 500 kilobytes
'proposed_changes.general_tags' => ['nullable', 'array'],
'proposed_changes.general_tags.*' => ['required', 'distinct', 'string', 'max:50', 'regex:'.config('computerScienceResource.tags_regex')],
'proposed_changes.programming_language_tags' => ['nullable', 'array'],
Expand Down
3 changes: 2 additions & 1 deletion app/Http/Requests/StoreResourceRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ public function rules(): array
'platforms' => ['required', 'array', 'min:1'],
'platforms.*' => ['required', 'distinct', 'string', Rule::in(config('computerScienceResource.platforms'))],
'page_url' => ['required', 'string', 'url:http,https', 'max:255'],
'difficulty' => ['required', 'string', Rule::in(config('computerScienceResource.difficulties'))],
'difficulties' => ['required', 'array', 'min:1'],
'difficulties.*' => ['required', 'distinct', 'string', Rule::in(config('computerScienceResource.difficulties'))],
'pricing' => ['required', 'string', Rule::in(config('computerScienceResource.pricings'))],
'topic_tags' => ['required', 'array', 'min:2'],
'topic_tags.*' => ['required', 'distinct', 'string', 'max:50', 'regex:'.config('computerScienceResource.tags_regex')],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;

class StoreResourceReview extends FormRequest
class StoreResourceReviewRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
Expand Down
2 changes: 1 addition & 1 deletion app/Http/Resources/ComputerScienceResourceResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public function toArray(Request $request): array
'page_url' => $this->page_url,
'image_path' => $this->image_path,
'platforms' => $this->platforms,
'difficulty' => $this->difficulty,
'difficulties' => $this->difficulties,
'pricing' => $this->pricing,
'topic_tags' => $this->topic_tags,
'programming_language_tags' => $this->programming_language_tags,
Expand Down
8 changes: 8 additions & 0 deletions app/Models/ComputerScienceResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,14 @@ protected function platforms(): Attribute
);
}

protected function difficulties(): Attribute
{
return Attribute::make(
get: fn ($value) => explode(',', $value),
set: fn ($value) => implode(',', $value)
);
}

/**
* Accessor to get topic tags.
*/
Expand Down
15 changes: 10 additions & 5 deletions app/Services/ComputerScienceResourceFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ public function validate(array $request)
'description' => ['nullable', 'string', 'max:1000'],
'platforms' => ['nullable', 'array'],
'platforms.*' => ['required', 'distinct', 'string', Rule::in(config('computerScienceResource.platforms'))],
'difficulty' => ['nullable', 'array'],
'difficulty.*' => ['required', 'distinct', 'string', Rule::in(config('computerScienceResource.difficulties'))],
'difficulties' => ['nullable', 'array'],
'difficulties.*' => ['required', 'distinct', 'string', Rule::in(config('computerScienceResource.difficulties'))],
'pricing' => ['nullable', 'array'],
'pricing.*' => ['required', 'distinct', 'string', Rule::in(config('computerScienceResource.pricings'))],
'topics_tags' => ['nullable', 'array'],
Expand Down Expand Up @@ -84,9 +84,14 @@ public function applyFilters($query, array $filters)
});
}

// Filter by difficulty
if (! empty($filters['difficulty'])) {
$query->whereIn('difficulty', (array) $filters['difficulty']);
// Filter by difficulties
if (! empty($filters['difficulties'])) {
$query->where(function ($q) use ($filters) {
foreach ($filters['difficulties'] as $difficulty) {
$q->orWhereRaw('FIND_IN_SET(?, difficulties)', [$difficulty]);

}
});
}

// Filter by pricing
Expand Down
2 changes: 1 addition & 1 deletion app/Services/ComputerScienceResourceService.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public function createResource(array $validatedData): ComputerScienceResource
'description' => $validatedData['description'],
'page_url' => $validatedData['page_url'],
'platforms' => $validatedData['platforms'],
'difficulty' => $validatedData['difficulty'],
'difficulties' => $validatedData['difficulties'],
'pricing' => $validatedData['pricing'],
]);

Expand Down
2 changes: 1 addition & 1 deletion database/factories/ComputerScienceResourceFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function definition(): array
'image_path' => $imagePath,
'page_url' => fake()->url(),
'platforms' => fake()->randomElements($platforms, rand(1, 3)),
'difficulty' => fake()->randomElement($difficulties),
'difficulties' => fake()->randomElements($difficulties, rand(1, 3)),
'pricing' => fake()->randomElement($pricings),
];
}
Expand Down
2 changes: 1 addition & 1 deletion database/factories/ResourceEditsFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function definition(): array
'image_path' => $imagePath,
'page_url' => $this->faker->url(),
'platforms' => $this->faker->randomElements($platforms, rand(1, 3)),
'difficulty' => $this->faker->randomElement($difficulties),
'difficulties' => $this->faker->randomElements($difficulties, rand(1, 3)),
'pricing' => $this->faker->randomElement($pricings),
'topic_tags' => ['data-structures', 'algorithms'],
'programming_language_tags' => ['python'],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;

return new class extends Migration
{
public function up(): void
{
// Rename column and change type
DB::statement("
ALTER TABLE computer_science_resources
CHANGE difficulty difficulties SET(
'general',
'introduction',
'practical',
'advanced',
'academic'
) NOT NULL
");
}

public function down(): void
{
// Rollback: rename back and revert type
DB::statement("
ALTER TABLE computer_science_resources
CHANGE difficulties difficulty ENUM(
'general',
'introduction',
'practical',
'advanced',
'academic'
) NOT NULL
");
}
};
24 changes: 12 additions & 12 deletions resources/js/Components/Resources/FilterBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ const description = ref("");

// multi-select filters
const selectedPlatforms = ref([]);
const selectedDifficulty = ref([]);
const selectedPricing = ref([]);
const selectedDifficulties = ref([]);
const selectedPricings = ref([]);
const selectedTopics = ref([]);
const selectedProgrammingLanguages = ref([]);
const selectedGeneralTags = ref([]);
Expand Down Expand Up @@ -56,8 +56,8 @@ onMounted(() => {
description.value = urlParams.get("description") || "";

selectedPlatforms.value = extractIndexedArray(urlParams, "platforms");
selectedDifficulty.value = extractIndexedArray(urlParams, "difficulty");
selectedPricing.value = extractIndexedArray(urlParams, "pricing");
selectedDifficulties.value = extractIndexedArray(urlParams, "difficulties");
selectedPricings.value = extractIndexedArray(urlParams, "pricing");
selectedTopics.value = extractIndexedArray(urlParams, "topics_tags");
selectedProgrammingLanguages.value = extractIndexedArray(
urlParams,
Expand Down Expand Up @@ -138,11 +138,11 @@ function search() {
platforms: selectedPlatforms.value.length
? selectedPlatforms.value
: undefined,
difficulty: selectedDifficulty.value.length
? selectedDifficulty.value
difficulties: selectedDifficulties.value.length
? selectedDifficulties.value
: undefined,
pricing: selectedPricing.value.length
? selectedPricing.value
pricing: selectedPricings.value.length
? selectedPricings.value
: undefined,
topics_tags: selectedTopics.value.length
? selectedTopics.value
Expand Down Expand Up @@ -182,8 +182,8 @@ function resetFilters() {

// Arrays
selectedPlatforms.value = [];
selectedDifficulty.value = [];
selectedPricing.value = [];
selectedDifficulties.value = [];
selectedPricings.value = [];
selectedTopics.value = [];
selectedProgrammingLanguages.value = [];
selectedGeneralTags.value = [];
Expand Down Expand Up @@ -271,7 +271,7 @@ function resetFilters() {
Difficulty
</label>
<MultiSelect
v-model="selectedDifficulty"
v-model="selectedDifficulties"
:options="difficultiesObject"
optionLabel="label"
optionValue="value"
Expand All @@ -287,7 +287,7 @@ function resetFilters() {
Pricing
</label>
<MultiSelect
v-model="selectedPricing"
v-model="selectedPricings"
:options="pricingsObject"
optionLabel="label"
optionValue="value"
Expand Down
Loading
Loading