This commit is contained in:
User
2024-12-31 20:17:35 -05:00
parent 3a1d4cc40a
commit 9777e46316
10 changed files with 13376 additions and 58 deletions

13101
app/Helper/ZhConversion.php Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -2,17 +2,18 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Helper\ZhConversion;
use App\Models\Author; use App\Models\Author;
use App\Models\Chapter; use App\Models\Chapter;
use App\Models\Comic; use App\Models\Comic;
use App\Models\Image; use App\Models\Image;
use App\Remote\CopyManga; use App\Remote\CopyManga;
use App\Remote\ImageFetcher; use App\Remote\ImageFetcher;
use Exception;
use GuzzleHttp\Exception\GuzzleException; use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Contracts\Routing\ResponseFactory; use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Foundation\Application; use Illuminate\Foundation\Application;
use Illuminate\Http\Client\ConnectionException;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse; use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
@@ -24,19 +25,42 @@ use Inertia\Response;
class ComicController extends Controller class ComicController extends Controller
{ {
public function __construct(private readonly CopyManga $copyManga) public function __construct(private readonly CopyManga $copyManga, private readonly ZhConversion $zhConversion)
{ {
} }
public function favourites(Request $request) protected function scToZh(mixed $string): mixed
{ {
$favourites = $request->user()->favourites()->with(['authors'])->orderBy('upstream_updated_at', 'desc')->get(); if (gettype($string) !== 'string') {
$string = serialize($string);
return unserialize(str_replace(array_keys($this->zhConversion::ZH_TO_HANT), array_values($this->zhConversion::ZH_TO_HANT), $string));
}
return str_replace(array_keys($this->zhConversion::ZH_TO_HANT), array_values($this->zhConversion::ZH_TO_HANT), $string);
}
/**
* Show user favourites
*
* @param Request $request
* @return Response
*/
public function favourites(Request $request): Response
{
$favourites = $this->scToZh($request->user()->favourites()->with(['authors'])->orderBy('upstream_updated_at', 'desc')->get());
return Inertia::render('Comic/Favourites', [ return Inertia::render('Comic/Favourites', [
'favourites' => $favourites, 'favourites' => $favourites,
]); ]);
} }
/**
* Toggle user favourites
*
* @param Request $request
* @return JsonResponse
* @throws GuzzleException
*/
public function postFavourite(Request $request): JsonResponse public function postFavourite(Request $request): JsonResponse
{ {
try { try {
@@ -68,6 +92,14 @@ class ComicController extends Controller
return response()->json($request->user()->favourites()->get(['pathword'])->pluck('pathword')); return response()->json($request->user()->favourites()->get(['pathword'])->pluck('pathword'));
} }
/**
* Show image via proxy
*
* @param Request $request
* @param string $url
* @return ResponseFactory|Application|IlluminateHttpResponse
* @throws ConnectionException
*/
public function image(Request $request, string $url): ResponseFactory|Application|IlluminateHttpResponse public function image(Request $request, string $url): ResponseFactory|Application|IlluminateHttpResponse
{ {
// TODO: Ref check and make it require auth // TODO: Ref check and make it require auth
@@ -121,7 +153,7 @@ class ComicController extends Controller
} }
/** /**
* * Index / Tags for comic listing
* *
* @param Request $request * @param Request $request
* @return Response * @return Response
@@ -138,11 +170,19 @@ class ComicController extends Controller
$this->comicsUpsert($comics); $this->comicsUpsert($comics);
return Inertia::render('Comic/Index', [ return Inertia::render('Comic/Index', [
'comics' => $comics, 'comics' => $this->scToZh($comics),
'offset' => $request->header('offset', 0) 'offset' => $request->header('offset', 0)
]); ]);
} }
/**
* Author for comic listing
*
* @param Request $request
* @param string $author
* @return Response
* @throws GuzzleException
*/
public function author(Request $request, string $author): Response public function author(Request $request, string $author): Response
{ {
$params = []; $params = [];
@@ -152,11 +192,19 @@ class ComicController extends Controller
$this->comicsUpsert($comics); $this->comicsUpsert($comics);
return Inertia::render('Comic/Index', [ return Inertia::render('Comic/Index', [
'comics' => $comics, 'comics' => $this->scToZh($comics),
'offset' => $request->header('offset', 0) 'offset' => $request->header('offset', 0)
]); ]);
} }
/**
* Search for comic listing
*
* @param Request $request
* @param string $search
* @return Response
* @throws GuzzleException
*/
public function search(Request $request, string $search): Response public function search(Request $request, string $search): Response
{ {
$comics = $this->copyManga->search($search, 30, $request->header('offset', 0)); $comics = $this->copyManga->search($search, 30, $request->header('offset', 0));
@@ -164,13 +212,25 @@ class ComicController extends Controller
// Search API is limited, no upsert // Search API is limited, no upsert
return Inertia::render('Comic/Index', [ return Inertia::render('Comic/Index', [
'comics' => $comics, 'comics' => $this->scToZh($comics),
'offset' => $request->header('offset', 0) 'offset' => $request->header('offset', 0)
]); ]);
} }
public function chapters(Request $request, string $pathword = ''): Response /**
* Show comic details and chapters
*
* @param Request $request
* @param string $pathword
* @return RedirectResponse|Response
* @throws GuzzleException
*/
public function chapters(Request $request, string $pathword = ''): RedirectResponse|Response
{ {
if ($pathword === 'installHook.js.map') {
return to_route('comics.index');
}
$comic = $this->copyManga->comic($pathword); $comic = $this->copyManga->comic($pathword);
$chapters = $this->copyManga->chapters($pathword, 200, $request->header('offset', 0), [], $request->get('group', 'default')); $chapters = $this->copyManga->chapters($pathword, 200, $request->header('offset', 0), [], $request->get('group', 'default'));
@@ -228,13 +288,22 @@ class ComicController extends Controller
->distinct()->select('chapter_uuid')->get()->pluck('chapter_uuid'); ->distinct()->select('chapter_uuid')->get()->pluck('chapter_uuid');
return Inertia::render('Comic/Chapters', [ return Inertia::render('Comic/Chapters', [
'comic' => $comic, 'comic' => $this->scToZh($comic),
'chapters' => $chapters, 'chapters' => $this->scToZh($chapters),
'histories' => $histories, 'histories' => $histories,
'offset' => $request->header('offset', 0) 'offset' => $request->header('offset', 0)
]); ]);
} }
/**
* Read a chapter, showing images
*
* @param Request $request
* @param string $pathword
* @param string $uuid
* @return Response
* @throws GuzzleException
*/
public function read(Request $request, string $pathword = '', string $uuid = ''): Response public function read(Request $request, string $pathword = '', string $uuid = ''): Response
{ {
$comic = $this->copyManga->comic($pathword); $comic = $this->copyManga->comic($pathword);
@@ -277,11 +346,17 @@ class ComicController extends Controller
$request->user()->readingHistories()->attach($chapterObj->id, ['comic_id' => $comicObj->id]); $request->user()->readingHistories()->attach($chapterObj->id, ['comic_id' => $comicObj->id]);
return Inertia::render('Comic/Read', [ return Inertia::render('Comic/Read', [
'comic' => $comic, 'comic' => $this->scToZh($comic),
'chapter' => $chapter, 'chapter' => $this->scToZh($chapter),
]); ]);
} }
/**
* Show user read histories
*
* @param Request $request
* @return Response
*/
public function histories(Request $request): Response public function histories(Request $request): Response
{ {
// Get history // Get history
@@ -289,10 +364,16 @@ class ComicController extends Controller
->select(['reading_histories.id as hid', 'reading_histories.created_at as read_at', 'chapters.comic_id', 'chapters.name'])->paginate(50)->toArray(); ->select(['reading_histories.id as hid', 'reading_histories.created_at as read_at', 'chapters.comic_id', 'chapters.name'])->paginate(50)->toArray();
return Inertia::render('Comic/Histories', [ return Inertia::render('Comic/Histories', [
'histories' => $histories 'histories' => $this->scToZh($histories)
]); ]);
} }
/**
* Delete user read histories by submitting ids
*
* @param Request $request
* @return RedirectResponse
*/
public function destroyHistories(Request $request): RedirectResponse public function destroyHistories(Request $request): RedirectResponse
{ {
if (!is_array($request->get('ids')) && $request->get('ids') === 'all') { if (!is_array($request->get('ids')) && $request->get('ids') === 'all') {
@@ -304,10 +385,17 @@ class ComicController extends Controller
return redirect()->route('comics.histories'); return redirect()->route('comics.histories');
} }
/**
* Fetch tags
*
* @return JsonResponse
* @throws GuzzleException
*/
public function tags() public function tags()
{ {
// TODO // TODO
$tags = $this->copyManga->tags(); $tags = $this->scToZh($this->copyManga->tags());
Cache::forever('tags', $tags); Cache::forever('tags', $tags);
return response()->json($tags); return response()->json($tags);

View File

@@ -0,0 +1,29 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Foundation\Application;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
use Inertia\Inertia;
use Inertia\Response;
class PagesController
{
/**
* @param Request $request
* @param string $path
* @return ResponseFactory|Application|\Illuminate\Http\Response|Response
*/
public function show(Request $request, string $path = '')
{
if (!File::exists(resource_path("js/Pages/Pages/$path.jsx"))) {
return response('Page not found', 404);
}
return Inertia::render("Pages/{$path}");
}
}

BIN
bun.lockb

Binary file not shown.

78
composer.lock generated
View File

@@ -2562,16 +2562,16 @@
}, },
{ {
"name": "nikic/php-parser", "name": "nikic/php-parser",
"version": "v5.3.1", "version": "v5.4.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/nikic/PHP-Parser.git", "url": "https://github.com/nikic/PHP-Parser.git",
"reference": "8eea230464783aa9671db8eea6f8c6ac5285794b" "reference": "447a020a1f875a434d62f2a401f53b82a396e494"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8eea230464783aa9671db8eea6f8c6ac5285794b", "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/447a020a1f875a434d62f2a401f53b82a396e494",
"reference": "8eea230464783aa9671db8eea6f8c6ac5285794b", "reference": "447a020a1f875a434d62f2a401f53b82a396e494",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2614,9 +2614,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/nikic/PHP-Parser/issues", "issues": "https://github.com/nikic/PHP-Parser/issues",
"source": "https://github.com/nikic/PHP-Parser/tree/v5.3.1" "source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0"
}, },
"time": "2024-10-08T18:51:32+00:00" "time": "2024-12-30T11:07:19+00:00"
}, },
{ {
"name": "nunomaduro/termwind", "name": "nunomaduro/termwind",
@@ -4345,16 +4345,16 @@
}, },
{ {
"name": "symfony/finder", "name": "symfony/finder",
"version": "v7.2.0", "version": "v7.2.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/finder.git", "url": "https://github.com/symfony/finder.git",
"reference": "6de263e5868b9a137602dd1e33e4d48bfae99c49" "reference": "87a71856f2f56e4100373e92529eed3171695cfb"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/6de263e5868b9a137602dd1e33e4d48bfae99c49", "url": "https://api.github.com/repos/symfony/finder/zipball/87a71856f2f56e4100373e92529eed3171695cfb",
"reference": "6de263e5868b9a137602dd1e33e4d48bfae99c49", "reference": "87a71856f2f56e4100373e92529eed3171695cfb",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -4389,7 +4389,7 @@
"description": "Finds files and directories via an intuitive fluent interface", "description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/finder/tree/v7.2.0" "source": "https://github.com/symfony/finder/tree/v7.2.2"
}, },
"funding": [ "funding": [
{ {
@@ -4405,20 +4405,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-10-23T06:56:12+00:00" "time": "2024-12-30T19:00:17+00:00"
}, },
{ {
"name": "symfony/http-foundation", "name": "symfony/http-foundation",
"version": "v7.2.0", "version": "v7.2.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/http-foundation.git", "url": "https://github.com/symfony/http-foundation.git",
"reference": "e88a66c3997859532bc2ddd6dd8f35aba2711744" "reference": "62d1a43796ca3fea3f83a8470dfe63a4af3bc588"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/e88a66c3997859532bc2ddd6dd8f35aba2711744", "url": "https://api.github.com/repos/symfony/http-foundation/zipball/62d1a43796ca3fea3f83a8470dfe63a4af3bc588",
"reference": "e88a66c3997859532bc2ddd6dd8f35aba2711744", "reference": "62d1a43796ca3fea3f83a8470dfe63a4af3bc588",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -4467,7 +4467,7 @@
"description": "Defines an object-oriented layer for the HTTP specification", "description": "Defines an object-oriented layer for the HTTP specification",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/http-foundation/tree/v7.2.0" "source": "https://github.com/symfony/http-foundation/tree/v7.2.2"
}, },
"funding": [ "funding": [
{ {
@@ -4483,20 +4483,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-11-13T18:58:46+00:00" "time": "2024-12-30T19:00:17+00:00"
}, },
{ {
"name": "symfony/http-kernel", "name": "symfony/http-kernel",
"version": "v7.2.1", "version": "v7.2.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/http-kernel.git", "url": "https://github.com/symfony/http-kernel.git",
"reference": "d8ae58eecae44c8e66833e76cc50a4ad3c002d97" "reference": "3c432966bd8c7ec7429663105f5a02d7e75b4306"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/d8ae58eecae44c8e66833e76cc50a4ad3c002d97", "url": "https://api.github.com/repos/symfony/http-kernel/zipball/3c432966bd8c7ec7429663105f5a02d7e75b4306",
"reference": "d8ae58eecae44c8e66833e76cc50a4ad3c002d97", "reference": "3c432966bd8c7ec7429663105f5a02d7e75b4306",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -4581,7 +4581,7 @@
"description": "Provides a structured process for converting a Request into a Response", "description": "Provides a structured process for converting a Request into a Response",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/http-kernel/tree/v7.2.1" "source": "https://github.com/symfony/http-kernel/tree/v7.2.2"
}, },
"funding": [ "funding": [
{ {
@@ -4597,7 +4597,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-12-11T12:09:10+00:00" "time": "2024-12-31T14:59:40+00:00"
}, },
{ {
"name": "symfony/mailer", "name": "symfony/mailer",
@@ -5863,16 +5863,16 @@
}, },
{ {
"name": "symfony/translation", "name": "symfony/translation",
"version": "v7.2.0", "version": "v7.2.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/translation.git", "url": "https://github.com/symfony/translation.git",
"reference": "dc89e16b44048ceecc879054e5b7f38326ab6cc5" "reference": "e2674a30132b7cc4d74540d6c2573aa363f05923"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/translation/zipball/dc89e16b44048ceecc879054e5b7f38326ab6cc5", "url": "https://api.github.com/repos/symfony/translation/zipball/e2674a30132b7cc4d74540d6c2573aa363f05923",
"reference": "dc89e16b44048ceecc879054e5b7f38326ab6cc5", "reference": "e2674a30132b7cc4d74540d6c2573aa363f05923",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -5938,7 +5938,7 @@
"description": "Provides tools to internationalize your application", "description": "Provides tools to internationalize your application",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/translation/tree/v7.2.0" "source": "https://github.com/symfony/translation/tree/v7.2.2"
}, },
"funding": [ "funding": [
{ {
@@ -5954,7 +5954,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-11-12T20:47:56+00:00" "time": "2024-12-07T08:18:10+00:00"
}, },
{ {
"name": "symfony/translation-contracts", "name": "symfony/translation-contracts",
@@ -7059,16 +7059,16 @@
}, },
{ {
"name": "laravel/pint", "name": "laravel/pint",
"version": "v1.18.3", "version": "v1.19.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/pint.git", "url": "https://github.com/laravel/pint.git",
"reference": "cef51821608239040ab841ad6e1c6ae502ae3026" "reference": "8169513746e1bac70c85d6ea1524d9225d4886f0"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/pint/zipball/cef51821608239040ab841ad6e1c6ae502ae3026", "url": "https://api.github.com/repos/laravel/pint/zipball/8169513746e1bac70c85d6ea1524d9225d4886f0",
"reference": "cef51821608239040ab841ad6e1c6ae502ae3026", "reference": "8169513746e1bac70c85d6ea1524d9225d4886f0",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -7079,10 +7079,10 @@
"php": "^8.1.0" "php": "^8.1.0"
}, },
"require-dev": { "require-dev": {
"friendsofphp/php-cs-fixer": "^3.65.0", "friendsofphp/php-cs-fixer": "^3.66.0",
"illuminate/view": "^10.48.24", "illuminate/view": "^10.48.25",
"larastan/larastan": "^2.9.11", "larastan/larastan": "^2.9.12",
"laravel-zero/framework": "^10.4.0", "laravel-zero/framework": "^10.48.25",
"mockery/mockery": "^1.6.12", "mockery/mockery": "^1.6.12",
"nunomaduro/termwind": "^1.17.0", "nunomaduro/termwind": "^1.17.0",
"pestphp/pest": "^2.36.0" "pestphp/pest": "^2.36.0"
@@ -7121,7 +7121,7 @@
"issues": "https://github.com/laravel/pint/issues", "issues": "https://github.com/laravel/pint/issues",
"source": "https://github.com/laravel/pint" "source": "https://github.com/laravel/pint"
}, },
"time": "2024-11-26T15:34:00+00:00" "time": "2024-12-30T16:20:10+00:00"
}, },
{ {
"name": "laravel/sail", "name": "laravel/sail",

View File

@@ -12,7 +12,7 @@
"@vitejs/plugin-react": "^4.3.4", "@vitejs/plugin-react": "^4.3.4",
"autoprefixer": "^10.4.20", "autoprefixer": "^10.4.20",
"axios": "^1.7.9", "axios": "^1.7.9",
"concurrently": "^9.1.1", "concurrently": "^9.1.2",
"laravel-vite-plugin": "^1.1.1", "laravel-vite-plugin": "^1.1.1",
"postcss": "^8.4.49", "postcss": "^8.4.49",
"react": "^18.3.1", "react": "^18.3.1",

View File

@@ -0,0 +1,49 @@
import { Head } from '@inertiajs/react';
import AppLayout from '@/Layouts/AppLayout.jsx';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
export default function Installation({ auth }) {
return (
<AppLayout auth={ auth }>
<Head>
<title>Installation</title>
</Head>
<div className="p-3 pt-1">
<Card className="w-[90%] m-3 mx-auto">
<CardHeader>
<CardTitle>Installation</CardTitle>
<CardDescription>Updated: 31 Dec 2024</CardDescription>
</CardHeader>
<CardContent>
<ul>
<li>Requirements</li>
<li className="ml-6 pt-2">
<ul>
<li>PHP 8.2+</li>
<li>Composer</li>
<li>Bun (Tested) / Other js runtime</li>
<li>Database (Sqlite / MySQL / MariaDB were tested)</li>
</ul>
</li>
</ul>
<p className="pt-2">Steps for installation</p>
<ol className="list-decimal ml-6 pt-2">
<li>Clone the git repo <span className="rounded-md border m-1 p-1 font-mono text-sm shadow-sm">https://ds19910209@bitbucket.org/pokebeacon/cv4.git</span></li>
<li>Install PHP dependencies <span className="rounded-md border m-1 p-1 font-mono text-sm shadow-sm">composer install</span></li>
<li>Clone .env.example file to .env</li>
<li>Edit any items in .env if needed</li>
<li>Generate Encryption key <span className="rounded-md border m-1 p-1 font-mono text-sm shadow-sm">php artisan key:generate</span></li>
<li>Generate Database tables <span className="rounded-md border m-1 p-1 font-mono text-sm shadow-sm">php artisan migrate</span></li>
<li>Install JS dependencies <span className="rounded-md border m-1 p-1 font-mono text-sm shadow-sm">bun install</span></li>
<li>Build frontend JS files <span className="rounded-md border m-1 p-1 font-mono text-sm shadow-sm">bun run build</span></li>
<li>Visit <span className="rounded-md border m-1 p-1 font-mono text-sm shadow-sm">http://[url]/tags</span> to fetch initial dataset</li>
<li>It should be running?</li>
</ol>
</CardContent>
</Card>
</div>
</AppLayout>
);
}

View File

@@ -0,0 +1,29 @@
import { Head } from '@inertiajs/react';
import AppLayout from '@/Layouts/AppLayout.jsx';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
export default function Updates({ auth }) {
return (
<AppLayout auth={ auth }>
<Head>
<title>Updates</title>
</Head>
<div className="p-3 pt-1">
<Card className="w-[90%] m-3 mx-auto">
<CardHeader>
<CardTitle>0.0.2</CardTitle>
<CardDescription>Release: 31 Dec 2024</CardDescription>
</CardHeader>
<CardContent>
<ul>
<li>Pages for update notes / installation</li>
<li>SC to ZH Conversion on the fly</li>
</ul>
</CardContent>
</Card>
</div>
</AppLayout>
);
}

View File

@@ -1,7 +1,7 @@
import { useState } from 'react'; import { useState } from 'react';
import { Link, router, usePage } from '@inertiajs/react'; import { Link, router, usePage } from '@inertiajs/react';
import { BadgeCheck, ChevronsUpDown, Star, History, ChevronDown, LogOut, Search, Book, TableOfContents } from 'lucide-react'; import { BadgeCheck, ChevronsUpDown, Star, History, ChevronDown, LogOut, Search, Book, TableOfContents, House, HardDriveDownload } from 'lucide-react';
import { Avatar, AvatarFallback } from '@/components/ui/avatar'; import { Avatar, AvatarFallback } from '@/components/ui/avatar';
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible'; import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible';
@@ -57,7 +57,7 @@ export function AppSidebar({ auth }) {
</div> </div>
<div className="flex flex-col gap-0.5 leading-none"> <div className="flex flex-col gap-0.5 leading-none">
<span className="font-semibold">Comic</span> <span className="font-semibold">Comic</span>
<span>0.0.1</span> <span>0.0.2</span>
</div> </div>
</Link> </Link>
</SidebarMenuButton> </SidebarMenuButton>
@@ -80,8 +80,24 @@ export function AppSidebar({ auth }) {
<SidebarMenuItem> <SidebarMenuItem>
<SidebarMenuButton asChild> <SidebarMenuButton asChild>
<Link href={ route('comics.index')}> <Link href={ route('comics.index')}>
<House />
<span>Index</span>
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton asChild>
<Link href={ route('pages.show', ['Installation'])}>
<HardDriveDownload />
<span>Installation</span>
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton asChild>
<Link href={ route('pages.show', ['Updates'])}>
<TableOfContents /> <TableOfContents />
<span>Manual</span> <span>Updates and notes</span>
</Link> </Link>
</SidebarMenuButton> </SidebarMenuButton>
</SidebarMenuItem> </SidebarMenuItem>

View File

@@ -1,6 +1,7 @@
<?php <?php
use App\Http\Controllers\ComicController; use App\Http\Controllers\ComicController;
use App\Http\Controllers\PagesController;
use App\Http\Controllers\ProfileController; use App\Http\Controllers\ProfileController;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
use Inertia\Inertia; use Inertia\Inertia;
@@ -29,6 +30,11 @@ Route::controller(ComicController::class)->middleware('auth')->name('comics.')->
Route::patch('/histories', 'destroyHistories')->name('destroyHistories'); // Only patch accept params Route::patch('/histories', 'destroyHistories')->name('destroyHistories'); // Only patch accept params
}); });
Route::controller(PagesController::class)->middleware('auth')->name('pages.')->group(function () {
Route::get('/pages/{path?}', 'show')->name('show');
});
Route::get('/dashboard', function () { Route::get('/dashboard', function () {
return Inertia::render('Dashboard'); return Inertia::render('Dashboard');
})->middleware(['auth', 'verified'])->name('dashboard'); })->middleware(['auth', 'verified'])->name('dashboard');