Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
5b34ae2
Fix1
AllanKoder Aug 26, 2025
f8755fc
Create page in progress
AllanKoder Aug 26, 2025
2b54e09
Guidelines
AllanKoder Aug 26, 2025
10d3491
Tests
AllanKoder Aug 26, 2025
1a6ab77
Apply automatic changes
AllanKoder Aug 26, 2025
2ceb37c
Mobile friendly
AllanKoder Aug 26, 2025
5f00f8d
Merge branch 'fixes' of https://github.com/AllanKoder/ComputerScience…
AllanKoder Aug 26, 2025
ee344f6
Tests n Stuff
AllanKoder Aug 26, 2025
fadb260
Apply automatic changes
AllanKoder Aug 26, 2025
17a3605
loading commentable
AllanKoder Aug 26, 2025
28ddd70
Merge branch 'fixes' of https://github.com/AllanKoder/ComputerScience…
AllanKoder Aug 26, 2025
cce5023
Tags
AllanKoder Aug 26, 2025
5cda79a
Tags, different lanes, needs migration and reset
AllanKoder Aug 27, 2025
41fb010
Apply automatic changes
AllanKoder Aug 27, 2025
5600f14
Tests
AllanKoder Aug 27, 2025
dc6f04c
Merge branch 'fixes' of https://github.com/AllanKoder/ComputerScience…
AllanKoder Aug 27, 2025
cd4a786
More Fixes
AllanKoder Aug 27, 2025
056ac35
Fixed Filterbar
AllanKoder Aug 27, 2025
2bc9b1e
Resource edits
AllanKoder Aug 27, 2025
90c066e
Apply automatic changes
AllanKoder Aug 27, 2025
dbc0078
Prefetch
AllanKoder Aug 27, 2025
748d936
Merge branch 'fixes' of https://github.com/AllanKoder/ComputerScience…
AllanKoder Aug 27, 2025
daa7c57
Tag Upgrade
AllanKoder Aug 27, 2025
9902bc6
Good enough software
AllanKoder Aug 28, 2025
5ed49b6
Upvote if resource created
AllanKoder Aug 28, 2025
ee57014
Apply automatic changes
AllanKoder Aug 28, 2025
f7a4bc3
More fixes
AllanKoder Aug 28, 2025
b4abfc3
Merge branch 'fixes' of https://github.com/AllanKoder/ComputerScience…
AllanKoder Aug 28, 2025
db613d5
Apply automatic changes
AllanKoder Aug 28, 2025
32f007c
Tags
AllanKoder Aug 28, 2025
dda08e0
Merge branch 'fixes' of https://github.com/AllanKoder/ComputerScience…
AllanKoder Aug 28, 2025
8892290
Admin Panel
AllanKoder Aug 28, 2025
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,052 changes: 5,903 additions & 1,149 deletions _ide_helper.php

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion app/Events/TagFrequencyChanged.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ class TagFrequencyChanged
/**
* Create a new event instance.
*/
public function __construct(public ?array $oldTags, public ?array $newTags) {}
public function __construct(
public string $tagType,
public array $oldTags,
public array $newTags
) {}

/**
* Get the channels the event should broadcast on.
Expand Down
73 changes: 71 additions & 2 deletions app/Filament/Admin/Resources/ComputerScienceResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@
use App\Filament\Admin\Resources\ComputerScienceResource\Pages;
use App\Filament\Admin\Resources\UserResource\RelationManagers\UserRelationManager;
use App\Models\ComputerScienceResource as ModelsComputerScienceResource;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Actions\BulkAction;
use Filament\Tables\Actions\DeleteAction;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;

class ComputerScienceResource extends Resource
{
Expand All @@ -24,6 +29,51 @@ public static function getEloquentQuery(): Builder

protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';

public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('name')
->required()
->maxLength(255),

Forms\Components\Textarea::make('description')
->maxLength(65535)
->columnSpanFull(),

Forms\Components\TextInput::make('slug')
->maxLength(255),

Forms\Components\Select::make('user_id')
->relationship('user', 'name')
->required(),

Forms\Components\TagsInput::make('topic_tags')
->label('Topic Tags')
->disabled()
->helperText('These are computed from relationships'),

Forms\Components\TagsInput::make('programming_language_tags')
->label('Programming Language Tags')
->disabled()
->helperText('These are computed from relationships'),

Forms\Components\TagsInput::make('general_tags')
->label('General Tags')
->disabled()
->helperText('These are computed from relationships'),

// Editable date fields
Forms\Components\DateTimePicker::make('created_at')
->label('Created Date')
->seconds(false),

Forms\Components\DateTimePicker::make('updated_at')
->label('Updated Date')
->seconds(false),
]);
}

public static function table(Table $table): Table
{
return $table
Expand All @@ -35,7 +85,7 @@ public static function table(Table $table): Table
TextColumn::make('name')->searchable()
->description(fn (ModelsComputerScienceResource $resource): string => $resource->description)->wrap(),
TextColumn::make('topic_tags')
->label('Topics')
->label('topics_tags')
->badge()
->color('primary')
->getStateUsing(fn ($record) => $record->topic_tags),
Expand All @@ -57,10 +107,29 @@ public static function table(Table $table): Table
])
->actions([
Tables\Actions\EditAction::make(),
// Custom delete action that uses model delete() method
DeleteAction::make()
->action(function (ModelsComputerScienceResource $record) {
// This calls the model's delete() method, triggering all events
$record->delete();
}),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
// Custom bulk delete action that uses model delete() method
BulkAction::make('delete')
->label('Delete selected')
->icon('heroicon-o-trash')
->color('danger')
->requiresConfirmation()
->action(function (Collection $records) {
// Loop through each record and call delete() individually
// This ensures all model events and custom logic are triggered
$records->each(function ($record) {
$record->delete();
});
})
->deselectRecordsAfterCompletion(),
]),
]);
}
Expand Down
22 changes: 12 additions & 10 deletions app/Http/Controllers/ComputerScienceResourceController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace App\Http\Controllers;

use App\Events\TagFrequencyChanged;
use App\Http\Requests\StoreResourceRequest;
use App\Models\ComputerScienceResource;
use App\Models\NewsPost;
Expand All @@ -13,6 +12,7 @@
use App\Services\ResourceReviewService;
use App\Services\SortingManagers\GeneralVotesSortingManager;
use App\Services\SortingManagers\ResourceSortingManager;
use App\Services\UpvoteService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
Expand All @@ -27,6 +27,7 @@ public function __construct(
protected GeneralVotesSortingManager $generalVotesSortingManager,
protected ResourceReviewService $reviewService,
protected ResourceSortingManager $resourceSortingManager,
protected UpvoteService $upvoteService,
) {}

/**
Expand Down Expand Up @@ -109,11 +110,10 @@ public function store(StoreResourceRequest $request)
$resource->general_tags = $validatedData['general_tags'];
}

// Dispatch tag frequency change event
TagFrequencyChanged::dispatch(null, $resource->tagCounter());

DB::commit();

$this->upvoteService->upvote('resource', $resource->id);

Log::info('Resource created', [
'resource_id' => $resource->id,
'user_id' => Auth::id(),
Expand All @@ -122,8 +122,9 @@ public function store(StoreResourceRequest $request)
'platforms' => $resource->platforms,
]);

return redirect(route('resources.show', ['slug' => $resource->slug]))
->with('success', 'Created Resource Succesfully!');
session()->flash('success', 'Created Resource!');

return response()->json($resource);
} catch (Throwable $e) {
DB::rollBack();
Log::critical('Failed to create resource', [
Expand All @@ -133,7 +134,7 @@ public function store(StoreResourceRequest $request)
'data' => $validatedData,
]);

return back()->withErrors(['error' => 'Failed to create resource. Please try again.']);
return response()->json([], 500);
}
}

Expand Down Expand Up @@ -168,14 +169,15 @@ public function show(Request $request, string $slug, string $tab = 'reviews')
if ($tab === 'reviews') {
$userReview = null;
if ($userId = Auth::id()) {
$userReview = ResourceReview::where('user_id', $userId)->first();
$userReview = ResourceReview::whereBelongsTo($computerScienceResource)
->firstWhere('user_id', $userId);
}

$data['userReview'] = $userReview;

$data['reviews'] = Inertia::defer(
function () use ($computerScienceResource, $sortBy, $request) {
$query = ResourceReview::where('computer_science_resource_id', $computerScienceResource->id);
$query = ResourceReview::whereBelongsTo($computerScienceResource);
$query = $this->generalVotesSortingManager->applySort($query, $sortBy, ResourceReview::class);

return $query->with('user')->paginate(10)->appends($request->query());
Expand All @@ -184,7 +186,7 @@ function () use ($computerScienceResource, $sortBy, $request) {
} elseif ($tab === 'edits') {
$data['resourceEdits'] = Inertia::defer(
function () use ($computerScienceResource, $sortBy, $request) {
$query = ResourceEdits::where('computer_science_resource_id', $computerScienceResource->id);
$query = ResourceEdits::whereBelongsTo($computerScienceResource);
$query = $this->generalVotesSortingManager->applySort($query, $sortBy, ResourceEdits::class);

return $query->with('user')->paginate(10)->appends($request->query());
Expand Down
13 changes: 3 additions & 10 deletions app/Http/Controllers/ResourceEditsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace App\Http\Controllers;

use App\Events\TagFrequencyChanged;
use App\Http\Requests\StoreResourceEdit;
use App\Models\ComputerScienceResource;
use App\Models\ResourceEdits;
Expand Down Expand Up @@ -69,7 +68,7 @@ public function store(ComputerScienceResource $computerScienceResource, StoreRes
]);

return redirect()->route('resource_edits.show', ['slug' => $resourceEdit->slug])
->with('success', 'The proposed edits were created. Others can now view it.');
->with('success', 'Edits Created!');
}

/**
Expand All @@ -95,7 +94,7 @@ public function show(string $slug)
{
$resourceEdits = ResourceEdits::where('slug', $slug)->firstOrFail();

$resourceEdits->load('resource');
$resourceEdits->load('computerScienceResource');
$resourceEdits->load('user');

return Inertia::render('ResourceEdits/Show', [
Expand All @@ -112,7 +111,6 @@ public function merge(ResourceEditsService $editsService, ResourceEdits $resourc
DB::beginTransaction();
try {
$resource = ComputerScienceResource::findOrFail($resourceEdits->computer_science_resource_id);
$oldTagCounter = $resource->tagCounter();

// Go through each property in proposed_changes, and if it exists. then set the value
$changes = $resourceEdits->proposed_changes;
Expand Down Expand Up @@ -151,11 +149,6 @@ public function merge(ResourceEditsService $editsService, ResourceEdits $resourc
}
}

// Get the new tag counter
$newTags = collect($allTags)->flatten()->countBy()->toArray();
// Change tag frequency
TagFrequencyChanged::dispatch($oldTagCounter, $newTags);

// Delete the edit since we successfully merged the changes
$resourceEdits->delete();

Expand All @@ -170,7 +163,7 @@ public function merge(ResourceEditsService $editsService, ResourceEdits $resourc
]);

return redirect(route('resources.show', ['slug' => $resource->slug]))
->with('success', 'Successfully merged new changed!');
->with('success', 'Successfully Merged Changes!');
} catch (Throwable $e) {
DB::rollBack();
Log::critical('Failed to merge resource edits', [
Expand Down
4 changes: 2 additions & 2 deletions app/Http/Controllers/ResourceReviewController.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public function store(StoreResourceReview $request, ComputerScienceResource $com
'review_id' => $review->id,
]);

return response()->json();
return response()->json($review);
}

public function update(StoreResourceReview $request, ComputerScienceResource $computerScienceResource)
Expand Down Expand Up @@ -106,6 +106,6 @@ public function update(StoreResourceReview $request, ComputerScienceResource $co
'review_id' => $existingReview->id,
]);

return response()->json();
return response()->json($existingReview);
}
}
15 changes: 11 additions & 4 deletions app/Http/Controllers/TagFrequencyController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,22 @@

class TagFrequencyController extends Controller
{
public function search(string $query = '')
public function search(string $type, string $query = '')
{
if (strlen($query) > 50) {
return response()->json(['message' => 'Query too long.'], 422);
return response()->json(['message' => 'Query too long'], 422);
}

$prefixed_tags = TagFrequency::where('tag', 'like', $query.'%')
if (! in_array($type, ['topics_tags', 'programming_languages_tags', 'general_tags'])) {
return response()->json(['message' => 'Not a valid type'], 422);
}

$escaped = addcslashes($query, '%_\\');

$prefixed_tags = TagFrequency::where('tag', 'like', $escaped.'%')
->where('type', $type)
->orderByDesc('count')
->limit(20)
->limit(30)
->get();

return response()->json([
Expand Down
Loading