diff --git a/app/Http/Controllers/ServersController.php b/app/Http/Controllers/ServersController.php index aeac5b5..721212e 100644 --- a/app/Http/Controllers/ServersController.php +++ b/app/Http/Controllers/ServersController.php @@ -25,4 +25,64 @@ public function index(Request $request): Response 'servers' => Server::all(), ]); } + + /** + * Store a new server request. + */ + public function store(Request $request): Response + { + $validated = $request->validate([ + 'name' => ['required', 'max:50', 'unique:servers,name'], + 'address' => ['required', 'url'], + 'owner_id' => ['nullable', 'exists:users,id'], + 'public' => ['required'], + ]); + + $validated['public'] = $validated['public'] === 'on' ? true : false; + + $server= Server::create($validated); + + return Inertia::render('Servers/Edit', [ + 'server' => $server, + 'alert' => [ + 'type' => 'success', + 'message' => 'Your new server has been created.', + ], + ]); + } + + /** + * View a server already on the system. + */ + public function view(Request $request, int $id): Response + { + return Inertia::render('Servers/Edit', [ + 'server' => Server::findOrFail($id), + ]); + } + + /** + * Store a new server request. + */ + public function update(Request $request, int $id): Response + { + $validated = $request->validate([ + 'name' => ['required', 'max:50'], + 'address' => ['required', 'url'], + 'owner_id' => ['nullable', 'exists:users,id'], + 'public' => ['required'], + ]); + + $validated['public'] = $validated['public'] === 'on' ? true : false; + + $server = Server::findOrFail($id)->forceFill($validated)->saveOrFail(); + + return Inertia::render('Servers/Edit', [ + 'server' => $server, + 'alert' => [ + 'type' => 'success', + 'message' => 'Server details have been changed.', + ], + ]); + } } diff --git a/app/Models/Server.php b/app/Models/Server.php index f2474b3..d956eaa 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -20,9 +20,9 @@ class Server extends Model * Rules to validate when modifying data. */ public static array $validationRules = [ - 'owner_id' => 'required|int', + 'owner_id' => 'nullable|int|exists:users,id', 'public' => 'nullable|bool', - 'name' => 'required|string|min:3|max:30', + 'name' => 'required|string|min:3|max:30|unique:servers,name', 'address' => 'required|string', // /[A-Za-z]+://[A-Za-z0-9]+\\.[A-Za-z][A-Za-z][A-Za-z]:[0-9]+/i ]; } diff --git a/database/migrations/2024_10_21_153409_create_servers_table.php b/database/migrations/2024_10_21_153409_create_servers_table.php index 186a0ff..af4edb9 100644 --- a/database/migrations/2024_10_21_153409_create_servers_table.php +++ b/database/migrations/2024_10_21_153409_create_servers_table.php @@ -13,7 +13,7 @@ public function up(): void { Schema::create('servers', function (Blueprint $table) { $table->id(); - $table->unsignedInteger('owner_id'); + $table->unsignedInteger('owner_id')->nullable(); $table->boolean('public')->default(false); $table->string('name'); $table->string('address'); diff --git a/resources/js/Components/Alert.tsx b/resources/js/Components/Alert.tsx new file mode 100644 index 0000000..b4ab8d9 --- /dev/null +++ b/resources/js/Components/Alert.tsx @@ -0,0 +1,47 @@ +import colors from 'tailwindcss/colors'; + +export type AlertType = 'success' | 'info' | 'warning' | 'danger'; + +interface Props { + message: string; + type: AlertType; +} + +function getAlertStyle({ type }: { type: AlertType }): string { + let color: string = colors.white; + + switch (type) { + case 'success': + color = colors.green[500]; + break; + case 'info': + color = colors.blue[500]; + break; + case 'warning': + color = colors.orange[500]; + break; + case 'danger': + color = colors.red[500]; + break; + } + + return color +} + +export default function Alert({ message, type }: Props) { + const color = getAlertStyle({ type }); + + + return ( +
+
+
+ {type} + {message} +
+
+
+ ) +} \ No newline at end of file diff --git a/resources/js/Layouts/AuthenticatedLayout.tsx b/resources/js/Layouts/AuthenticatedLayout.tsx index 70b4a13..ff9caf9 100644 --- a/resources/js/Layouts/AuthenticatedLayout.tsx +++ b/resources/js/Layouts/AuthenticatedLayout.tsx @@ -1,3 +1,4 @@ +import Alert from '@/Components/Alert'; import ApplicationLogo from '@/Components/ApplicationLogo'; import Dropdown from '@/Components/Dropdown'; import NavLink from '@/Components/NavLink'; @@ -12,6 +13,7 @@ export default function Authenticated({ children, }: PropsWithChildren<{ header?: ReactNode; title?: string }>) { const user = usePage().props.auth.user; + const alert = usePage().props.alert; const [showingNavigationDropdown, setShowingNavigationDropdown] = useState(false); @@ -19,6 +21,7 @@ export default function Authenticated({ return (
+ {alert && }