From 9dcc6b4e125f0f3fb9b59784e1a8f2bc12adc572 Mon Sep 17 00:00:00 2001 From: Alex Lingris Date: Thu, 8 Jan 2026 18:13:17 +0200 Subject: [PATCH] edit delete schemas --- front/js/entry/LoginEntry/LoginEntry.svelte | 53 ++++++++++++++++ .../SchemaEditEntry/SchemaEditEntry.svelte | 61 +++++++++++++++---- front/js/entry/VerifyEntry/VerifyEntry.svelte | 35 +++++++++++ front/js/layouts/AccountLayout.svelte | 16 +++++ front/js/main.js | 8 +-- front/js/svelte/Channel.svelte | 27 ++++---- front/package-lock.json | 7 +++ src/Core/Auth/AuthModule.php | 22 +++++++ src/Core/Channel/ChannelModule.php | 12 ++++ src/Core/Data/Channel.php | 6 ++ src/Core/Repository/FieldRepo.php | 5 ++ src/Core/Repository/SchemaRepo.php | 12 ++++ src/Core/Schema/Data/Schema.php | 2 - src/Core/Schema/SchemaModule.php | 2 - src/Http/Controller/AuthController.php | 38 +++++------- src/Http/Controller/FieldController.php | 10 +-- src/Http/Controller/HomeController.php | 5 +- src/Http/Controller/SchemaController.php | 60 ++++++++++++++---- src/Http/Middleware/GuestMiddleware.php | 10 ++- src/Http/web.php | 8 +++ src/Svelte/Svelte.php | 25 ++------ 21 files changed, 317 insertions(+), 107 deletions(-) create mode 100644 front/js/entry/LoginEntry/LoginEntry.svelte create mode 100644 front/js/entry/VerifyEntry/VerifyEntry.svelte create mode 100644 front/js/layouts/AccountLayout.svelte create mode 100644 src/Core/Auth/AuthModule.php create mode 100644 src/Core/Channel/ChannelModule.php create mode 100644 src/Core/Data/Channel.php diff --git a/front/js/entry/LoginEntry/LoginEntry.svelte b/front/js/entry/LoginEntry/LoginEntry.svelte new file mode 100644 index 0000000..f25a174 --- /dev/null +++ b/front/js/entry/LoginEntry/LoginEntry.svelte @@ -0,0 +1,53 @@ + + + +{#snippet body()} +
+ {#if message} + + {:else} +
+
+ + +
+ +
+ +
+
+ {/if} +
+{/snippet} diff --git a/front/js/entry/SchemaEditEntry/SchemaEditEntry.svelte b/front/js/entry/SchemaEditEntry/SchemaEditEntry.svelte index 4804168..7682e4e 100644 --- a/front/js/entry/SchemaEditEntry/SchemaEditEntry.svelte +++ b/front/js/entry/SchemaEditEntry/SchemaEditEntry.svelte @@ -1,6 +1,7 @@ @@ -54,8 +73,26 @@ Developers will use this to reference the field + + + + {#snippet text()} + Delete schema + {/snippet} + {/snippet} diff --git a/front/js/entry/VerifyEntry/VerifyEntry.svelte b/front/js/entry/VerifyEntry/VerifyEntry.svelte new file mode 100644 index 0000000..c777b0c --- /dev/null +++ b/front/js/entry/VerifyEntry/VerifyEntry.svelte @@ -0,0 +1,35 @@ + + + +{#snippet body()} +
+
+
+

Login as {data.email}

+
+ +
+ +
+
+
+{/snippet} diff --git a/front/js/layouts/AccountLayout.svelte b/front/js/layouts/AccountLayout.svelte new file mode 100644 index 0000000..d06251f --- /dev/null +++ b/front/js/layouts/AccountLayout.svelte @@ -0,0 +1,16 @@ + + +
+

+ {channel.name ?? "Lucent Setup"} +

+
+
+ {@render body()} +
diff --git a/front/js/main.js b/front/js/main.js index 5a7bc1e..02733a5 100644 --- a/front/js/main.js +++ b/front/js/main.js @@ -3,8 +3,8 @@ import * as Turbo from "@hotwired/turbo"; import { mount, unmount } from "svelte"; import "../css/app.css"; import Register from "./svelte/account/Register.svelte"; -import Login from "./svelte/account/Login.svelte"; -import Verify from "./svelte/account/Verify.svelte"; +import LoginEntry from "./entry/LoginEntry/LoginEntry.svelte"; +import VerifyEntry from "./entry/VerifyEntry/VerifyEntry.svelte"; import Profile from "./svelte/account/Profile.svelte"; import SetupIndex from "./svelte/setup/Index.svelte"; import Members from "./svelte/members/Members.svelte"; @@ -27,8 +27,8 @@ const entryComponents = { homeIndex: HomeEntry, buildReport: BuildReport, register: Register, - login: Login, - verify: Verify, + login: LoginEntry, + verify: VerifyEntry, profile: Profile, setup: SetupIndex, schemas: SchemaEntry, diff --git a/front/js/svelte/Channel.svelte b/front/js/svelte/Channel.svelte index fa0216b..0d55838 100644 --- a/front/js/svelte/Channel.svelte +++ b/front/js/svelte/Channel.svelte @@ -3,7 +3,7 @@ import RecordNotFound from "./records/NotFound.svelte"; import RecordEdit from "./records/Edit.svelte"; import ContentIndex from "./content/Index.svelte"; - import {setContext} from "svelte"; + import { setContext } from "svelte"; import Navbar from "./layout/Navbar.svelte"; import HomeIndex from "./home/Index.svelte"; import BuildReport from "./build/Report.svelte"; @@ -28,24 +28,21 @@ export let axios; export let readableSchemas; - setContext("axios", axios); setContext("channel", channel); - setContext("readableSchemas", channel.schemas.filter((s) => readableSchemas.includes(s.name))); + setContext( + "readableSchemas", + channel.schemas.filter((s) => readableSchemas.includes(s.name)), + ); setContext("user", user); - -
- -
-
- -
-
- - - diff --git a/front/package-lock.json b/front/package-lock.json index 06ddce8..337989a 100644 --- a/front/package-lock.json +++ b/front/package-lock.json @@ -1128,6 +1128,7 @@ "integrity": "sha512-a+uxqQ9j6Lxmq4plbGaNdM9hgDCZyxAv/yvuyF5iWoA2H5icZkqD3rdK155ZQgFLX2lc3NvahHG4OgKpYqYPiQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^5.0.0", "deepmerge": "^4.3.1", @@ -1174,6 +1175,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -4322,6 +4324,7 @@ "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.8.tgz", "integrity": "sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ==", "dev": true, + "peer": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -4362,6 +4365,7 @@ "integrity": "sha512-ynjfCHD3nP2el70kN5Pmg37sSi0EjOm9FgHYQdC4giWG/hzO3AatzXXJJgP305uIhGQxSufJLuYWtkY8uK/8RA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", @@ -4424,6 +4428,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -4461,6 +4466,7 @@ "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", @@ -4554,6 +4560,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, diff --git a/src/Core/Auth/AuthModule.php b/src/Core/Auth/AuthModule.php new file mode 100644 index 0000000..c346427 --- /dev/null +++ b/src/Core/Auth/AuthModule.php @@ -0,0 +1,22 @@ +runningInConsole()) { + return config("lucent.systemUserId"); + } elseif (request()->segment(1) !== "lucent") { + return config("lucent.systemUserId"); + } else { + return Session::get("user.id"); + } + } + + public static function isLoggedIn(): bool + { + return !empty(static::getCurrentUserId()); + } +} diff --git a/src/Core/Channel/ChannelModule.php b/src/Core/Channel/ChannelModule.php new file mode 100644 index 0000000..7ce5473 --- /dev/null +++ b/src/Core/Channel/ChannelModule.php @@ -0,0 +1,12 @@ +where("id", $fieldId)->delete(); } + + public static function deleteBySchemaId(string $schemaId): void + { + DB::table(self::TABLE_NAME)->where("schema_id", $schemaId)->delete(); + } } diff --git a/src/Core/Repository/SchemaRepo.php b/src/Core/Repository/SchemaRepo.php index 051636b..d0ab56f 100644 --- a/src/Core/Repository/SchemaRepo.php +++ b/src/Core/Repository/SchemaRepo.php @@ -33,4 +33,16 @@ class SchemaRepo { DB::table(self::TABLE_NAME)->insert(SchemaModule::toDb($schema)); } + + public static function update(Schema $schema): void + { + DB::table(self::TABLE_NAME) + ->where("id", $schema->id) + ->update(SchemaModule::toDb($schema)); + } + + public static function delete(string $schemaId): void + { + DB::table(self::TABLE_NAME)->where("id", $schemaId)->delete(); + } } diff --git a/src/Core/Schema/Data/Schema.php b/src/Core/Schema/Data/Schema.php index b4f42bb..29d41f5 100644 --- a/src/Core/Schema/Data/Schema.php +++ b/src/Core/Schema/Data/Schema.php @@ -7,13 +7,11 @@ class Schema * @param string $alias * @param string $name * @param int $revisions - * @param Field[] $fields */ public function __construct( public string $id, public string $alias, public string $name, public int $revisions, - public array $fields, ) {} } diff --git a/src/Core/Schema/SchemaModule.php b/src/Core/Schema/SchemaModule.php index 2544333..253e1da 100644 --- a/src/Core/Schema/SchemaModule.php +++ b/src/Core/Schema/SchemaModule.php @@ -12,7 +12,6 @@ class SchemaModule alias: $data["alias"], name: $data["label"], revisions: $data["revisions"], - fields: array_map(FieldModule::fromArray(...), $data["fields"]), ); } @@ -23,7 +22,6 @@ class SchemaModule alias: data_get($data, "alias"), name: data_get($data, "name"), revisions: data_get($data, "revisions"), - fields: [], ); } diff --git a/src/Http/Controller/AuthController.php b/src/Http/Controller/AuthController.php index 0de07ab..298e32d 100644 --- a/src/Http/Controller/AuthController.php +++ b/src/Http/Controller/AuthController.php @@ -10,6 +10,7 @@ use Illuminate\Http\Request; use Illuminate\Http\Response; use Lucent\Account\AccountService; use Lucent\Account\AuthService; +use Lucent\Core\Data\Channel; use Lucent\Channel\ChannelService; use Lucent\LucentException; use Lucent\Svelte\Svelte; @@ -18,39 +19,33 @@ use Lucent\Util\Form\ResponseFormError; use function Lucent\Response\fail; use function Lucent\Response\ok; - class AuthController { public function __construct( - private readonly AuthService $authService, + private readonly AuthService $authService, private readonly AccountService $accountService, private readonly ChannelService $channelService, - private readonly Session $session, - private readonly Svelte $svelte, - ) - { - - } + private readonly Session $session, + private readonly Svelte $svelte, + ) {} public function register(Request $request): View|RedirectResponse { if ($this->accountService->countUsers() > 0) { - return redirect($this->channelService->channel->lucentUrl . "/login"); + return redirect( + $this->channelService->channel->lucentUrl . "/login", + ); } - return $this->svelte->render( layout: "account", view: "register", title: "Create an account", - ); } - public function postRegister(Request $request): Response { - if ($this->accountService->countUsers() > 0) { abort(400); } @@ -70,44 +65,43 @@ class AuthController public function login() { if ($this->accountService->countUsers() == 0) { - return redirect($this->channelService->channel->lucentUrl . "/register"); + return redirect(Channel::get()->url . "/register"); } - return view("lucent::auth.login"); + return Svelte::view("login", "Login", []); } public function postLogin(Request $request) { $this->authService->sendLoginEmail($request->input("email")); - return view("lucent::auth.login-success"); + return []; } public function verify(Request $request): View { - return view("lucent::auth.verify", [ + return Svelte::view("verify", "Verify", [ "email" => $request->input("email"), "token" => $request->input("token"), ]); - } public function postVerify(Request $request) { try { - $this->authService->login($request->input("email"), $request->input("token")); + $this->authService->login( + $request->input("email"), + $request->input("token"), + ); } catch (LucentException $th) { return ResponseFormError::fromException($th); } return []; } - public function logout(): RedirectResponse { $this->session->flush(); return redirect($this->channelService->channel->lucentUrl . "/login"); } - - } diff --git a/src/Http/Controller/FieldController.php b/src/Http/Controller/FieldController.php index cd87197..d43c5db 100644 --- a/src/Http/Controller/FieldController.php +++ b/src/Http/Controller/FieldController.php @@ -2,20 +2,16 @@ namespace Lucent\Http\Controller; -use App\Http\Controllers\Controller; use Illuminate\Http\Request; -use Lucent\Account\AccountService; -use Lucent\Account\AuthService; use Lucent\Core\Repository\FieldRepo; use Lucent\Core\Repository\SchemaRepo; use Lucent\Core\Schema\Data\Field; use Lucent\Core\Schema\Data\FieldProp\FieldProp; -use Lucent\Core\Schema\Data\Schema; use Lucent\Id\Id; use Lucent\Svelte\Svelte; use Illuminate\Support\Facades\Validator; -class FieldController extends Controller +class FieldController { public function __construct(private readonly Svelte $svelte) {} @@ -36,7 +32,7 @@ class FieldController extends Controller // $fieldProps = FieldProp::fromType($fieldType); - return $this->svelte->render( + return Svelte::view( view: "fieldCreate", title: "Create Field", data: [ @@ -99,7 +95,7 @@ class FieldController extends Controller $schemas = SchemaRepo::all(); $schema = collect($schemas)->firstWhere("id", $field->schemaId); - return $this->svelte->render( + return Svelte::view( view: "fieldEdit", title: "Edit Field", data: [ diff --git a/src/Http/Controller/HomeController.php b/src/Http/Controller/HomeController.php index fef1a26..66697cd 100644 --- a/src/Http/Controller/HomeController.php +++ b/src/Http/Controller/HomeController.php @@ -14,14 +14,13 @@ use function Lucent\Response\ok; class HomeController extends Controller { public function __construct( - private readonly Svelte $svelte, private readonly AccountService $accountService, private readonly Query $query, ) {} - public function home(): View + public function home() { - return $this->svelte->render(view: "homeIndex", title: "Records"); + return Svelte::view("homeIndex", "Records", []); } public function records(Request $request): Response diff --git a/src/Http/Controller/SchemaController.php b/src/Http/Controller/SchemaController.php index 94bc1b3..d7bdff9 100644 --- a/src/Http/Controller/SchemaController.php +++ b/src/Http/Controller/SchemaController.php @@ -2,10 +2,7 @@ namespace Lucent\Http\Controller; -use App\Http\Controllers\Controller; use Illuminate\Http\Request; -use Lucent\Account\AccountService; -use Lucent\Account\AuthService; use Lucent\Core\Repository\SchemaRepo; use Lucent\Core\Repository\FieldRepo; use Lucent\Core\Schema\Data\Schema; @@ -13,20 +10,14 @@ use Lucent\Id\Id; use Lucent\Svelte\Svelte; use Illuminate\Support\Facades\Validator; -class SchemaController extends Controller +class SchemaController { - public function __construct( - private readonly AuthService $authService, - private readonly AccountService $accountService, - private readonly Svelte $svelte, - ) {} - public function home() { $schemas = SchemaRepo::all(); $fields = FieldRepo::all(); - return $this->svelte->render( + return Svelte::view( view: "schemas", title: "Schemas", data: [ @@ -51,7 +42,6 @@ class SchemaController extends Controller alias: $request->input("alias"), name: $request->input("name"), revisions: 0, - fields: [], ); SchemaRepo::insert($schema); @@ -71,7 +61,7 @@ class SchemaController extends Controller return response()->json(["errors" => ["Schema not found"]], 404); } - return $this->svelte->render( + return Svelte::view( view: "schemaEdit", title: "Edit Schema", data: [ @@ -79,4 +69,48 @@ class SchemaController extends Controller ], ); } + + public function postUpdate(Request $request) + { + $validator = Validator::make($request->all(), [ + "name" => "required|string|max:30|min:2|", + "alias" => "required|alpha_dash:ascii|max:30|min:2|", + ]); + if ($validator->fails()) { + return response()->json(["errors" => $validator->errors()], 422); + } + + $schema = SchemaRepo::findOne($request->input("id")); + + if (empty($schema)) { + return response()->json(["errors" => ["Schema not found"]], 404); + } + + $schema = new Schema( + id: $schema->id, + alias: $request->input("alias"), + name: $request->input("name"), + revisions: $request->input("revisions"), + ); + + SchemaRepo::update($schema); + + return response()->json( + ["message" => "Schema created successfully"], + 201, + ); + } + public function postDelete(Request $request) + { + $schemaId = $request->input("schemaId"); + $schema = SchemaRepo::findOne($schemaId); + + if (empty($schema)) { + return response()->json(["errors" => ["Schema not found"]], 404); + } + + SchemaRepo::delete($schemaId); + FieldRepo::deleteBySchemaId($schemaId); + return response()->json([], 200); + } } diff --git a/src/Http/Middleware/GuestMiddleware.php b/src/Http/Middleware/GuestMiddleware.php index 54db01a..9c3df0a 100644 --- a/src/Http/Middleware/GuestMiddleware.php +++ b/src/Http/Middleware/GuestMiddleware.php @@ -4,18 +4,16 @@ namespace Lucent\Http\Middleware; use Closure; use Illuminate\Http\Request; -use Lucent\Account\AuthService; +use Lucent\Core\Auth\AuthModule; readonly class GuestMiddleware { - public function __construct(private AuthService $authService) - { - } + public function __construct() {} public function handle(Request $request, Closure $next) { - if ($this->authService->isLoggedIn()) { - return redirect("/lucent"); + if (AuthModule::isLoggedIn()) { + return redirect(config("lucent.url")); } return $next($request); } diff --git a/src/Http/web.php b/src/Http/web.php index 367941f..f90130e 100644 --- a/src/Http/web.php +++ b/src/Http/web.php @@ -63,6 +63,14 @@ Route::group( Route::get("/schemas", [SchemaController::class, "home"]); Route::get("/schemas/edit/{id}", [SchemaController::class, "edit"]); Route::post("/schemas", [SchemaController::class, "postCreate"]); + Route::post("/schemas/update", [ + SchemaController::class, + "postUpdate", + ]); + Route::post("/schemas/delete", [ + SchemaController::class, + "postDelete", + ]); Route::get("/fields/create", [FieldController::class, "create"]); Route::get("/fields/edit/{id}", [FieldController::class, "edit"]); Route::post("/fields", [FieldController::class, "postCreate"]); diff --git a/src/Svelte/Svelte.php b/src/Svelte/Svelte.php index 163d1bb..bab885f 100644 --- a/src/Svelte/Svelte.php +++ b/src/Svelte/Svelte.php @@ -2,32 +2,18 @@ namespace Lucent\Svelte; -use Illuminate\Contracts\View\Factory; -use Illuminate\Contracts\View\View; -use Lucent\Account\AccountService; -use Lucent\Channel\ChannelService; +use Lucent\Core\Channel\ChannelModule; class Svelte { - public function __construct( - public ChannelService $channelService, - public AccountService $accountService, - ) {} - - function render( - string $view, - string $title = "", - mixed $data = [], - ): View|Factory { + public static function view(string $view, string $title, mixed $data) + { $context = []; $context["user"] = session("user"); $context["view"] = $view; $context["title"] = $title; $context["data"] = $data; - $context["channel"] = $this->channelService->channel; - $context[ - "readableSchemas" - ] = $this->accountService->currentReadableSchemas(); + $context["channel"] = ChannelModule::get(); $json = json_encode($context); $divTag = '
'; @@ -40,10 +26,7 @@ class Svelte return view("lucent::svelte", [ "svelte" => $svelte, - "view" => $view, - "data" => $data, "title" => $title, - "channel" => $this->channelService->channel, ]); } }