From aea22e72af70cac1444ffc5786008df7d4e7a0e0 Mon Sep 17 00:00:00 2001 From: Nebulae Date: Wed, 8 Apr 2026 15:17:05 +0200 Subject: [PATCH] feat(wip member dashboard) --- app/Http/Controllers/DashboardController.php | 47 ++++ app/Http/Resources/MemberResource.php | 23 ++ app/Http/Resources/MembershipResource.php | 25 ++ app/Http/Resources/PackageResource.php | 22 ++ app/Http/Resources/ServiceResource.php | 24 ++ app/Models/Member.php | 6 + app/Models/Membership.php | 11 +- .../ServiceActivationRequestNotification.php | 54 +++++ ...s_active_to_services_memberships_table.php | 28 +++ .../Http/Controllers/DashboardController.ts | 141 +++++++++++ .../js/actions/App/Http/Controllers/index.ts | 2 + resources/js/pages/dashboard.tsx | 227 ++++++++++++++++-- resources/js/routes/dashboard/index.ts | 62 +++++ resources/js/routes/index.ts | 49 ++-- resources/js/types/index.d.ts | 35 +++ routes/web.php | 6 +- 16 files changed, 711 insertions(+), 51 deletions(-) create mode 100644 app/Http/Controllers/DashboardController.php create mode 100644 app/Http/Resources/MemberResource.php create mode 100644 app/Http/Resources/MembershipResource.php create mode 100644 app/Http/Resources/PackageResource.php create mode 100644 app/Http/Resources/ServiceResource.php create mode 100644 app/Notifications/ServiceActivationRequestNotification.php create mode 100644 database/migrations/2026_04_08_122045_add_is_active_to_services_memberships_table.php create mode 100644 resources/js/actions/App/Http/Controllers/DashboardController.ts create mode 100644 resources/js/routes/dashboard/index.ts diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php new file mode 100644 index 0000000..d4db61c --- /dev/null +++ b/app/Http/Controllers/DashboardController.php @@ -0,0 +1,47 @@ +user() + ->members() + ->with([ + 'lastActiveMembership.package', + 'lastActiveMembership.services', + ]) + ->first(); + + return Inertia::render('dashboard', [ + 'member' => $member ? new MemberResource($member) : null, + ]); + } + + public function requestServiceActivation(Request $request): RedirectResponse + { + $request->validate([ + 'service_identifier' => ['required', 'string'], + ]); + + $member = $request->user()->members()->first(); + + if ($member === null) { + return back()->with('flash', ['error' => 'Aucun compte membre associé.']); + } + + Notification::route('mail', config('app.admin_email')) + ->notify(new ServiceActivationRequestNotification($member, $request->string('service_identifier'))); + + return back()->with('flash', ['success' => "Votre demande d'activation a bien été envoyée."]); + } +} diff --git a/app/Http/Resources/MemberResource.php b/app/Http/Resources/MemberResource.php new file mode 100644 index 0000000..c3c72e1 --- /dev/null +++ b/app/Http/Resources/MemberResource.php @@ -0,0 +1,23 @@ + + */ + public function toArray(Request $request): array + { + return [ + 'firstname' => $this->firstname, + 'lastname' => $this->lastname, + 'email' => $this->email, + 'retzien_email' => $this->retzien_email, + 'membership' => new MembershipResource($this->whenLoaded('lastActiveMembership')), + ]; + } +} diff --git a/app/Http/Resources/MembershipResource.php b/app/Http/Resources/MembershipResource.php new file mode 100644 index 0000000..c8162d2 --- /dev/null +++ b/app/Http/Resources/MembershipResource.php @@ -0,0 +1,25 @@ + + */ + public function toArray(Request $request): array + { + return [ + 'status' => $this->status, + 'payment_status' => $this->payment_status, + 'start_date' => $this->start_date, + 'end_date' => $this->end_date, + 'amount' => $this->amount, + 'package' => new PackageResource($this->whenLoaded('package')), + 'services' => ServiceResource::collection($this->whenLoaded('services')), + ]; + } +} diff --git a/app/Http/Resources/PackageResource.php b/app/Http/Resources/PackageResource.php new file mode 100644 index 0000000..c831817 --- /dev/null +++ b/app/Http/Resources/PackageResource.php @@ -0,0 +1,22 @@ + + */ + public function toArray(Request $request): array + { + return [ + 'identifier' => $this->identifier, + 'name' => $this->name, + 'description' => $this->description, + 'price' => $this->price, + ]; + } +} diff --git a/app/Http/Resources/ServiceResource.php b/app/Http/Resources/ServiceResource.php new file mode 100644 index 0000000..ffb1728 --- /dev/null +++ b/app/Http/Resources/ServiceResource.php @@ -0,0 +1,24 @@ + + */ + public function toArray(Request $request): array + { + return [ + 'identifier' => $this->identifier, + 'name' => $this->name, + 'description' => $this->description, + 'url' => $this->url, + 'icon' => $this->icon, + 'is_active' => (bool) $this->whenPivotLoaded('services_memberships', fn () => $this->pivot->is_active), + ]; + } +} diff --git a/app/Models/Member.php b/app/Models/Member.php index 3b665b8..c6b093e 100644 --- a/app/Models/Member.php +++ b/app/Models/Member.php @@ -6,6 +6,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Database\Eloquent\Relations\HasOne; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Notifications\Notifiable; @@ -152,6 +153,11 @@ class Member extends Model return $this->hasMany(NextCloudMember::class, 'member_id'); } + public function lastActiveMembership(): HasOne + { + return $this->hasOne(Membership::class)->where('status', 'active')->latest(); + } + public function lastMembership(): ?Membership { return $this->memberships()->where('status', 'active')->first(); diff --git a/app/Models/Membership.php b/app/Models/Membership.php index 739fcc1..b47886d 100644 --- a/app/Models/Membership.php +++ b/app/Models/Membership.php @@ -5,8 +5,6 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsToMany; -use Illuminate\Database\Eloquent\Relations\HasMany; -use Illuminate\Database\Eloquent\Relations\HasOne; /** * @property int $id @@ -32,6 +30,7 @@ use Illuminate\Database\Eloquent\Relations\HasOne; * @property-read \App\Models\Package $package * @property-read \Illuminate\Database\Eloquent\Collection $services * @property-read int|null $services_count + * * @method static \Illuminate\Database\Eloquent\Builder|Membership newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|Membership newQuery() * @method static \Illuminate\Database\Eloquent\Builder|Membership query() @@ -53,6 +52,7 @@ use Illuminate\Database\Eloquent\Relations\HasOne; * @method static \Illuminate\Database\Eloquent\Builder|Membership whereStatus($value) * @method static \Illuminate\Database\Eloquent\Builder|Membership whereUpdatedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|Membership whereValidationDate($value) + * * @mixin \Eloquent */ class Membership extends Model @@ -71,10 +71,9 @@ class Membership extends Model 'note_public', 'note_private', 'dolibarr_id', - 'dolibarr_user_id' + 'dolibarr_user_id', ]; - public static function getAttributeLabel(string $attribute): string { return __("memberships.fields.$attribute"); @@ -97,7 +96,7 @@ class Membership extends Model public function services(): BelongsToMany { - return $this->belongsToMany(Service::class, 'services_memberships', 'membership_id', 'service_id'); + return $this->belongsToMany(Service::class, 'services_memberships', 'membership_id', 'service_id') + ->withPivot('is_active'); } - } diff --git a/app/Notifications/ServiceActivationRequestNotification.php b/app/Notifications/ServiceActivationRequestNotification.php new file mode 100644 index 0000000..894905b --- /dev/null +++ b/app/Notifications/ServiceActivationRequestNotification.php @@ -0,0 +1,54 @@ + + */ + public function via(object $notifiable): array + { + return ['mail']; + } + + public function toMail(object $notifiable): MailMessage + { + $template = NotificationTemplate::findByIdentifier('service_activation_request'); + + $vars = [ + 'member_name' => $this->member->full_name, + 'member_email' => $this->member->email ?? '', + 'service_identifier' => $this->serviceIdentifier, + 'app_name' => config('app.name'), + ]; + + return (new MailMessage) + ->subject($template->renderSubject($vars)) + ->view('notifications.mail-template', [ + 'body' => $template->renderBody($vars), + ]); + } + + /** + * @return array + */ + public function toArray(object $notifiable): array + { + return []; + } +} diff --git a/database/migrations/2026_04_08_122045_add_is_active_to_services_memberships_table.php b/database/migrations/2026_04_08_122045_add_is_active_to_services_memberships_table.php new file mode 100644 index 0000000..88bd8f9 --- /dev/null +++ b/database/migrations/2026_04_08_122045_add_is_active_to_services_memberships_table.php @@ -0,0 +1,28 @@ +boolean('is_active')->default(false)->after('membership_id'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('services_memberships', function (Blueprint $table) { + $table->dropColumn('is_active'); + }); + } +}; diff --git a/resources/js/actions/App/Http/Controllers/DashboardController.ts b/resources/js/actions/App/Http/Controllers/DashboardController.ts new file mode 100644 index 0000000..8ab7764 --- /dev/null +++ b/resources/js/actions/App/Http/Controllers/DashboardController.ts @@ -0,0 +1,141 @@ +import { queryParams, type RouteQueryOptions, type RouteDefinition, type RouteFormDefinition } from './../../../../wayfinder' +/** +* @see \App\Http\Controllers\DashboardController::index +* @see app/Http/Controllers/DashboardController.php:15 +* @route '/dashboard' +*/ +export const index = (options?: RouteQueryOptions): RouteDefinition<'get'> => ({ + url: index.url(options), + method: 'get', +}) + +index.definition = { + methods: ["get","head"], + url: '/dashboard', +} satisfies RouteDefinition<["get","head"]> + +/** +* @see \App\Http\Controllers\DashboardController::index +* @see app/Http/Controllers/DashboardController.php:15 +* @route '/dashboard' +*/ +index.url = (options?: RouteQueryOptions) => { + return index.definition.url + queryParams(options) +} + +/** +* @see \App\Http\Controllers\DashboardController::index +* @see app/Http/Controllers/DashboardController.php:15 +* @route '/dashboard' +*/ +index.get = (options?: RouteQueryOptions): RouteDefinition<'get'> => ({ + url: index.url(options), + method: 'get', +}) + +/** +* @see \App\Http\Controllers\DashboardController::index +* @see app/Http/Controllers/DashboardController.php:15 +* @route '/dashboard' +*/ +index.head = (options?: RouteQueryOptions): RouteDefinition<'head'> => ({ + url: index.url(options), + method: 'head', +}) + +/** +* @see \App\Http\Controllers\DashboardController::index +* @see app/Http/Controllers/DashboardController.php:15 +* @route '/dashboard' +*/ +const indexForm = (options?: RouteQueryOptions): RouteFormDefinition<'get'> => ({ + action: index.url(options), + method: 'get', +}) + +/** +* @see \App\Http\Controllers\DashboardController::index +* @see app/Http/Controllers/DashboardController.php:15 +* @route '/dashboard' +*/ +indexForm.get = (options?: RouteQueryOptions): RouteFormDefinition<'get'> => ({ + action: index.url(options), + method: 'get', +}) + +/** +* @see \App\Http\Controllers\DashboardController::index +* @see app/Http/Controllers/DashboardController.php:15 +* @route '/dashboard' +*/ +indexForm.head = (options?: RouteQueryOptions): RouteFormDefinition<'get'> => ({ + action: index.url({ + [options?.mergeQuery ? 'mergeQuery' : 'query']: { + _method: 'HEAD', + ...(options?.query ?? options?.mergeQuery ?? {}), + } + }), + method: 'get', +}) + +index.form = indexForm + +/** +* @see \App\Http\Controllers\DashboardController::requestServiceActivation +* @see app/Http/Controllers/DashboardController.php:30 +* @route '/dashboard/service-activation' +*/ +export const requestServiceActivation = (options?: RouteQueryOptions): RouteDefinition<'post'> => ({ + url: requestServiceActivation.url(options), + method: 'post', +}) + +requestServiceActivation.definition = { + methods: ["post"], + url: '/dashboard/service-activation', +} satisfies RouteDefinition<["post"]> + +/** +* @see \App\Http\Controllers\DashboardController::requestServiceActivation +* @see app/Http/Controllers/DashboardController.php:30 +* @route '/dashboard/service-activation' +*/ +requestServiceActivation.url = (options?: RouteQueryOptions) => { + return requestServiceActivation.definition.url + queryParams(options) +} + +/** +* @see \App\Http\Controllers\DashboardController::requestServiceActivation +* @see app/Http/Controllers/DashboardController.php:30 +* @route '/dashboard/service-activation' +*/ +requestServiceActivation.post = (options?: RouteQueryOptions): RouteDefinition<'post'> => ({ + url: requestServiceActivation.url(options), + method: 'post', +}) + +/** +* @see \App\Http\Controllers\DashboardController::requestServiceActivation +* @see app/Http/Controllers/DashboardController.php:30 +* @route '/dashboard/service-activation' +*/ +const requestServiceActivationForm = (options?: RouteQueryOptions): RouteFormDefinition<'post'> => ({ + action: requestServiceActivation.url(options), + method: 'post', +}) + +/** +* @see \App\Http\Controllers\DashboardController::requestServiceActivation +* @see app/Http/Controllers/DashboardController.php:30 +* @route '/dashboard/service-activation' +*/ +requestServiceActivationForm.post = (options?: RouteQueryOptions): RouteFormDefinition<'post'> => ({ + action: requestServiceActivation.url(options), + method: 'post', +}) + +requestServiceActivation.form = requestServiceActivationForm + +const DashboardController = { index, requestServiceActivation } + +export default DashboardController \ No newline at end of file diff --git a/resources/js/actions/App/Http/Controllers/index.ts b/resources/js/actions/App/Http/Controllers/index.ts index 496bed8..223f3a1 100644 --- a/resources/js/actions/App/Http/Controllers/index.ts +++ b/resources/js/actions/App/Http/Controllers/index.ts @@ -1,9 +1,11 @@ import Auth from './Auth' +import DashboardController from './DashboardController' import Settings from './Settings' import Forms from './Forms' const Controllers = { Auth: Object.assign(Auth, Auth), + DashboardController: Object.assign(DashboardController, DashboardController), Settings: Object.assign(Settings, Settings), Forms: Object.assign(Forms, Forms), } diff --git a/resources/js/pages/dashboard.tsx b/resources/js/pages/dashboard.tsx index 9905b77..7d2fb27 100644 --- a/resources/js/pages/dashboard.tsx +++ b/resources/js/pages/dashboard.tsx @@ -1,35 +1,220 @@ -import { PlaceholderPattern } from '@/components/ui/placeholder-pattern'; import AppLayout from '@/layouts/app-layout'; -import { dashboard } from '@/routes'; -import { type BreadcrumbItem } from '@/types'; -import { Head } from '@inertiajs/react'; +import { type BreadcrumbItem, type DashboardMember, type DashboardService, type PageProps } from '@/types'; +import { Head, router, usePage } from '@inertiajs/react'; +import DashboardController from '@/actions/App/Http/Controllers/DashboardController'; +import { ExternalLink, KeyRound, Loader2 } from 'lucide-react'; +import { Button } from '@/components/ui/button'; +import { FlashMessage } from '@/components/flash-message'; +import { useEffect, useState } from 'react'; +import { cn } from '@/lib/utils'; const breadcrumbs: BreadcrumbItem[] = [ { - title: 'Tableau de Bord', - href: dashboard().url, + title: 'Tableau de bord', + href: DashboardController.index().url, }, ]; +const ACTIVATION_REQUESTED_KEY = 'service_activation_requested'; + +function getRequestedServices(): string[] { + try { + return JSON.parse(localStorage.getItem(ACTIVATION_REQUESTED_KEY) ?? '[]'); + } catch { + return []; + } +} + +function markServiceRequested(identifier: string): void { + const current = getRequestedServices(); + if (!current.includes(identifier)) { + localStorage.setItem(ACTIVATION_REQUESTED_KEY, JSON.stringify([...current, identifier])); + } +} + +function WelcomeCard({ member }: { member: DashboardMember }) { + const membership = member.membership; + + return ( +
+

Bienvenue

+

+ {member.firstname} {member.lastname} +

+

{member.retzien_email || member.email}

+ + {membership ? ( +
+ + {membership.package?.name ?? 'Adhésion'} + + + {membership.status === 'active' ? 'Actif' : 'En attente'} + + {membership.end_date && ( + + Valide jusqu'au {new Date(membership.end_date).toLocaleDateString('fr-FR')} + + )} +
+ ) : ( +

Aucune adhésion active.

+ )} +
+ ); +} + +function NoMemberCard() { + return ( +
+ +

Pas encore membre ?

+

+ Votre compte n'est pas encore associé à une adhésion. Rejoignez l'association pour accéder aux services. +

+ +
+ ); +} + +function ServiceCard({ service, onRequest }: { service: DashboardService; onRequest: (identifier: string) => void }) { + const [alreadyRequested, setAlreadyRequested] = useState(() => + getRequestedServices().includes(service.identifier), + ); + + function handleRequest() { + markServiceRequested(service.identifier); + setAlreadyRequested(true); + onRequest(service.identifier); + } + + return ( +
+
+
+

{service.name}

+ {service.description && ( +

{service.description}

+ )} +
+ + {service.is_active ? 'Actif' : 'Inactif'} + +
+ + {service.is_active ? ( + + Accéder au service + + ) : ( + + )} +
+ ); +} + export default function Dashboard() { + const { flash, member } = usePage().props; + const [showFlash, setShowFlash] = useState(!!flash); + const [submitting, setSubmitting] = useState(false); + + useEffect(() => { + if (flash) { + setShowFlash(true); + const timer = setTimeout(() => setShowFlash(false), 5000); + return () => clearTimeout(timer); + } + }, [flash]); + + function handleActivationRequest(identifier: string) { + setSubmitting(true); + router.post( + DashboardController.requestServiceActivation().url, + { service_identifier: identifier }, + { + preserveScroll: true, + onFinish: () => setSubmitting(false), + }, + ); + } + + const membership = member?.membership ?? null; + const services = membership?.services ?? []; + return ( -
-
-
- -
-
- -
-
- -
-
-
- -
+ +
+ {showFlash && flash && } + + {member ? ( + <> + + + {services.length > 0 && ( +
+

Vos services

+ {submitting && ( +
+ Envoi en cours… +
+ )} +
+ {services.map((service) => ( + + ))} +
+
+ )} + + {services.length === 0 && membership && ( +
+ Aucun service associé à votre adhésion pour le moment. +
+ )} + + {!membership && ( +
+ Votre demande d'adhésion est en cours de traitement. +
+ )} + + ) : ( + + )}
); diff --git a/resources/js/routes/dashboard/index.ts b/resources/js/routes/dashboard/index.ts new file mode 100644 index 0000000..fdfd47a --- /dev/null +++ b/resources/js/routes/dashboard/index.ts @@ -0,0 +1,62 @@ +import { queryParams, type RouteQueryOptions, type RouteDefinition, type RouteFormDefinition } from './../../wayfinder' +/** +* @see \App\Http\Controllers\DashboardController::serviceActivation +* @see app/Http/Controllers/DashboardController.php:30 +* @route '/dashboard/service-activation' +*/ +export const serviceActivation = (options?: RouteQueryOptions): RouteDefinition<'post'> => ({ + url: serviceActivation.url(options), + method: 'post', +}) + +serviceActivation.definition = { + methods: ["post"], + url: '/dashboard/service-activation', +} satisfies RouteDefinition<["post"]> + +/** +* @see \App\Http\Controllers\DashboardController::serviceActivation +* @see app/Http/Controllers/DashboardController.php:30 +* @route '/dashboard/service-activation' +*/ +serviceActivation.url = (options?: RouteQueryOptions) => { + return serviceActivation.definition.url + queryParams(options) +} + +/** +* @see \App\Http\Controllers\DashboardController::serviceActivation +* @see app/Http/Controllers/DashboardController.php:30 +* @route '/dashboard/service-activation' +*/ +serviceActivation.post = (options?: RouteQueryOptions): RouteDefinition<'post'> => ({ + url: serviceActivation.url(options), + method: 'post', +}) + +/** +* @see \App\Http\Controllers\DashboardController::serviceActivation +* @see app/Http/Controllers/DashboardController.php:30 +* @route '/dashboard/service-activation' +*/ +const serviceActivationForm = (options?: RouteQueryOptions): RouteFormDefinition<'post'> => ({ + action: serviceActivation.url(options), + method: 'post', +}) + +/** +* @see \App\Http\Controllers\DashboardController::serviceActivation +* @see app/Http/Controllers/DashboardController.php:30 +* @route '/dashboard/service-activation' +*/ +serviceActivationForm.post = (options?: RouteQueryOptions): RouteFormDefinition<'post'> => ({ + action: serviceActivation.url(options), + method: 'post', +}) + +serviceActivation.form = serviceActivationForm + +const dashboard = { + serviceActivation: Object.assign(serviceActivation, serviceActivation), +} + +export default dashboard \ No newline at end of file diff --git a/resources/js/routes/index.ts b/resources/js/routes/index.ts index 9a24c73..6db2c91 100644 --- a/resources/js/routes/index.ts +++ b/resources/js/routes/index.ts @@ -137,7 +137,7 @@ logoutForm.post = (options?: RouteQueryOptions): RouteFormDefinition<'post'> => logout.form = logoutForm /** -* @see routes/web.php:6 +* @see routes/web.php:7 * @route '/welcome' */ export const home = (options?: RouteQueryOptions): RouteDefinition<'get'> => ({ @@ -151,7 +151,7 @@ home.definition = { } satisfies RouteDefinition<["get","head"]> /** -* @see routes/web.php:6 +* @see routes/web.php:7 * @route '/welcome' */ home.url = (options?: RouteQueryOptions) => { @@ -159,7 +159,7 @@ home.url = (options?: RouteQueryOptions) => { } /** -* @see routes/web.php:6 +* @see routes/web.php:7 * @route '/welcome' */ home.get = (options?: RouteQueryOptions): RouteDefinition<'get'> => ({ @@ -168,7 +168,7 @@ home.get = (options?: RouteQueryOptions): RouteDefinition<'get'> => ({ }) /** -* @see routes/web.php:6 +* @see routes/web.php:7 * @route '/welcome' */ home.head = (options?: RouteQueryOptions): RouteDefinition<'head'> => ({ @@ -177,7 +177,7 @@ home.head = (options?: RouteQueryOptions): RouteDefinition<'head'> => ({ }) /** -* @see routes/web.php:6 +* @see routes/web.php:7 * @route '/welcome' */ const homeForm = (options?: RouteQueryOptions): RouteFormDefinition<'get'> => ({ @@ -186,7 +186,7 @@ const homeForm = (options?: RouteQueryOptions): RouteFormDefinition<'get'> => ({ }) /** -* @see routes/web.php:6 +* @see routes/web.php:7 * @route '/welcome' */ homeForm.get = (options?: RouteQueryOptions): RouteFormDefinition<'get'> => ({ @@ -195,7 +195,7 @@ homeForm.get = (options?: RouteQueryOptions): RouteFormDefinition<'get'> => ({ }) /** -* @see routes/web.php:6 +* @see routes/web.php:7 * @route '/welcome' */ homeForm.head = (options?: RouteQueryOptions): RouteFormDefinition<'get'> => ({ @@ -211,7 +211,7 @@ homeForm.head = (options?: RouteQueryOptions): RouteFormDefinition<'get'> => ({ home.form = homeForm /** -* @see routes/web.php:10 +* @see routes/web.php:11 * @route '/' */ export const maintenance = (options?: RouteQueryOptions): RouteDefinition<'get'> => ({ @@ -225,7 +225,7 @@ maintenance.definition = { } satisfies RouteDefinition<["get","head"]> /** -* @see routes/web.php:10 +* @see routes/web.php:11 * @route '/' */ maintenance.url = (options?: RouteQueryOptions) => { @@ -233,7 +233,7 @@ maintenance.url = (options?: RouteQueryOptions) => { } /** -* @see routes/web.php:10 +* @see routes/web.php:11 * @route '/' */ maintenance.get = (options?: RouteQueryOptions): RouteDefinition<'get'> => ({ @@ -242,7 +242,7 @@ maintenance.get = (options?: RouteQueryOptions): RouteDefinition<'get'> => ({ }) /** -* @see routes/web.php:10 +* @see routes/web.php:11 * @route '/' */ maintenance.head = (options?: RouteQueryOptions): RouteDefinition<'head'> => ({ @@ -251,7 +251,7 @@ maintenance.head = (options?: RouteQueryOptions): RouteDefinition<'head'> => ({ }) /** -* @see routes/web.php:10 +* @see routes/web.php:11 * @route '/' */ const maintenanceForm = (options?: RouteQueryOptions): RouteFormDefinition<'get'> => ({ @@ -260,7 +260,7 @@ const maintenanceForm = (options?: RouteQueryOptions): RouteFormDefinition<'get' }) /** -* @see routes/web.php:10 +* @see routes/web.php:11 * @route '/' */ maintenanceForm.get = (options?: RouteQueryOptions): RouteFormDefinition<'get'> => ({ @@ -269,7 +269,7 @@ maintenanceForm.get = (options?: RouteQueryOptions): RouteFormDefinition<'get'> }) /** -* @see routes/web.php:10 +* @see routes/web.php:11 * @route '/' */ maintenanceForm.head = (options?: RouteQueryOptions): RouteFormDefinition<'get'> => ({ @@ -285,7 +285,8 @@ maintenanceForm.head = (options?: RouteQueryOptions): RouteFormDefinition<'get'> maintenance.form = maintenanceForm /** -* @see routes/web.php:15 +* @see \App\Http\Controllers\DashboardController::dashboard +* @see app/Http/Controllers/DashboardController.php:15 * @route '/dashboard' */ export const dashboard = (options?: RouteQueryOptions): RouteDefinition<'get'> => ({ @@ -299,7 +300,8 @@ dashboard.definition = { } satisfies RouteDefinition<["get","head"]> /** -* @see routes/web.php:15 +* @see \App\Http\Controllers\DashboardController::dashboard +* @see app/Http/Controllers/DashboardController.php:15 * @route '/dashboard' */ dashboard.url = (options?: RouteQueryOptions) => { @@ -307,7 +309,8 @@ dashboard.url = (options?: RouteQueryOptions) => { } /** -* @see routes/web.php:15 +* @see \App\Http\Controllers\DashboardController::dashboard +* @see app/Http/Controllers/DashboardController.php:15 * @route '/dashboard' */ dashboard.get = (options?: RouteQueryOptions): RouteDefinition<'get'> => ({ @@ -316,7 +319,8 @@ dashboard.get = (options?: RouteQueryOptions): RouteDefinition<'get'> => ({ }) /** -* @see routes/web.php:15 +* @see \App\Http\Controllers\DashboardController::dashboard +* @see app/Http/Controllers/DashboardController.php:15 * @route '/dashboard' */ dashboard.head = (options?: RouteQueryOptions): RouteDefinition<'head'> => ({ @@ -325,7 +329,8 @@ dashboard.head = (options?: RouteQueryOptions): RouteDefinition<'head'> => ({ }) /** -* @see routes/web.php:15 +* @see \App\Http\Controllers\DashboardController::dashboard +* @see app/Http/Controllers/DashboardController.php:15 * @route '/dashboard' */ const dashboardForm = (options?: RouteQueryOptions): RouteFormDefinition<'get'> => ({ @@ -334,7 +339,8 @@ const dashboardForm = (options?: RouteQueryOptions): RouteFormDefinition<'get'> }) /** -* @see routes/web.php:15 +* @see \App\Http\Controllers\DashboardController::dashboard +* @see app/Http/Controllers/DashboardController.php:15 * @route '/dashboard' */ dashboardForm.get = (options?: RouteQueryOptions): RouteFormDefinition<'get'> => ({ @@ -343,7 +349,8 @@ dashboardForm.get = (options?: RouteQueryOptions): RouteFormDefinition<'get'> => }) /** -* @see routes/web.php:15 +* @see \App\Http\Controllers\DashboardController::dashboard +* @see app/Http/Controllers/DashboardController.php:15 * @route '/dashboard' */ dashboardForm.head = (options?: RouteQueryOptions): RouteFormDefinition<'get'> => ({ diff --git a/resources/js/types/index.d.ts b/resources/js/types/index.d.ts index c089995..f3d2816 100644 --- a/resources/js/types/index.d.ts +++ b/resources/js/types/index.d.ts @@ -74,12 +74,47 @@ export interface Service { illustration: string; } +export interface DashboardService { + identifier: string; + name: string; + description: string | null; + url: string; + icon: string | null; + is_active: boolean; +} + +export interface DashboardPackage { + identifier: string; + name: string; + description: string | null; + price: string; +} + +export interface DashboardMembership { + status: string; + payment_status: string; + start_date: string | null; + end_date: string | null; + amount: string; + package: DashboardPackage | null; + services: DashboardService[]; +} + +export interface DashboardMember { + firstname: string | null; + lastname: string | null; + email: string; + retzien_email: string; + membership: DashboardMembership | null; +} + export interface PageProps { flash?: FlashMessages; auth?: Auth; plans?: Plans[]; services?: MembershipService[]; captcha_question?: string; + member?: DashboardMember | null; [key: string]: unknown; } diff --git a/routes/web.php b/routes/web.php index 3e5c6a3..9bdb602 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,5 +1,6 @@ name('maintenance'); Route::middleware(['auth', 'verified'])->group(function () { - Route::get('dashboard', function () { - return Inertia::render('dashboard'); - })->name('dashboard'); + Route::get('dashboard', [DashboardController::class, 'index'])->name('dashboard'); + Route::post('dashboard/service-activation', [DashboardController::class, 'requestServiceActivation'])->name('dashboard.service-activation'); }); require __DIR__.'/settings.php';