@tower_74/cms-app 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +102 -0
- package/package.json +49 -0
- package/src/components/AppContent.vue +21 -0
- package/src/components/AppLogoIcon.vue +24 -0
- package/src/components/AppShell.vue +37 -0
- package/src/components/AppearanceTabs.vue +37 -0
- package/src/components/AuthBar.vue +58 -0
- package/src/components/BlockEditor.vue +95 -0
- package/src/components/DeleteUser.vue +87 -0
- package/src/components/FieldBuilder.vue +105 -0
- package/src/components/Heading.vue +20 -0
- package/src/components/HeadingSmall.vue +17 -0
- package/src/components/Icon.vue +30 -0
- package/src/components/InputError.vue +13 -0
- package/src/components/MenuItemsEditor.vue +59 -0
- package/src/components/NavUser.vue +30 -0
- package/src/components/Pagination.vue +28 -0
- package/src/components/PlaceholderPattern.vue +16 -0
- package/src/components/Seo.vue +28 -0
- package/src/components/TextLink.vue +24 -0
- package/src/components/UserInfo.vue +34 -0
- package/src/components/UserMenuContent.vue +37 -0
- package/src/components/commerce/OptionsEditor.vue +55 -0
- package/src/components/commerce/VariantsEditor.vue +71 -0
- package/src/components/ui/avatar/Avatar.vue +24 -0
- package/src/components/ui/avatar/AvatarFallback.vue +11 -0
- package/src/components/ui/avatar/AvatarImage.vue +9 -0
- package/src/components/ui/avatar/index.ts +24 -0
- package/src/components/ui/breadcrumb/Breadcrumb.vue +13 -0
- package/src/components/ui/breadcrumb/BreadcrumbEllipsis.vue +18 -0
- package/src/components/ui/breadcrumb/BreadcrumbItem.vue +14 -0
- package/src/components/ui/breadcrumb/BreadcrumbLink.vue +15 -0
- package/src/components/ui/breadcrumb/BreadcrumbList.vue +14 -0
- package/src/components/ui/breadcrumb/BreadcrumbPage.vue +14 -0
- package/src/components/ui/breadcrumb/BreadcrumbSeparator.vue +17 -0
- package/src/components/ui/breadcrumb/index.ts +7 -0
- package/src/components/ui/button/Button.vue +22 -0
- package/src/components/ui/button/index.ts +31 -0
- package/src/components/ui/card/Card.vue +14 -0
- package/src/components/ui/card/CardContent.vue +14 -0
- package/src/components/ui/card/CardDescription.vue +14 -0
- package/src/components/ui/card/CardFooter.vue +14 -0
- package/src/components/ui/card/CardHeader.vue +14 -0
- package/src/components/ui/card/CardTitle.vue +14 -0
- package/src/components/ui/card/index.ts +6 -0
- package/src/components/ui/checkbox/Checkbox.vue +36 -0
- package/src/components/ui/checkbox/index.ts +1 -0
- package/src/components/ui/collapsible/Collapsible.vue +15 -0
- package/src/components/ui/collapsible/CollapsibleContent.vue +14 -0
- package/src/components/ui/collapsible/CollapsibleTrigger.vue +11 -0
- package/src/components/ui/collapsible/index.ts +3 -0
- package/src/components/ui/dialog/Dialog.vue +14 -0
- package/src/components/ui/dialog/DialogClose.vue +11 -0
- package/src/components/ui/dialog/DialogContent.vue +51 -0
- package/src/components/ui/dialog/DialogDescription.vue +21 -0
- package/src/components/ui/dialog/DialogFooter.vue +12 -0
- package/src/components/ui/dialog/DialogHeader.vue +14 -0
- package/src/components/ui/dialog/DialogScrollContent.vue +59 -0
- package/src/components/ui/dialog/DialogTitle.vue +21 -0
- package/src/components/ui/dialog/DialogTrigger.vue +11 -0
- package/src/components/ui/dialog/index.ts +9 -0
- package/src/components/ui/dropdown-menu/DropdownMenu.vue +14 -0
- package/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +42 -0
- package/src/components/ui/dropdown-menu/DropdownMenuContent.vue +40 -0
- package/src/components/ui/dropdown-menu/DropdownMenuGroup.vue +11 -0
- package/src/components/ui/dropdown-menu/DropdownMenuItem.vue +30 -0
- package/src/components/ui/dropdown-menu/DropdownMenuLabel.vue +21 -0
- package/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +14 -0
- package/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +43 -0
- package/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue +21 -0
- package/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue +14 -0
- package/src/components/ui/dropdown-menu/DropdownMenuSub.vue +14 -0
- package/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue +30 -0
- package/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +31 -0
- package/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue +13 -0
- package/src/components/ui/dropdown-menu/index.ts +16 -0
- package/src/components/ui/input/Input.vue +32 -0
- package/src/components/ui/input/index.ts +1 -0
- package/src/components/ui/label/Label.vue +22 -0
- package/src/components/ui/label/index.ts +1 -0
- package/src/components/ui/navigation-menu/NavigationMenu.vue +25 -0
- package/src/components/ui/navigation-menu/NavigationMenuContent.vue +31 -0
- package/src/components/ui/navigation-menu/NavigationMenuIndicator.vue +29 -0
- package/src/components/ui/navigation-menu/NavigationMenuItem.vue +11 -0
- package/src/components/ui/navigation-menu/NavigationMenuLink.vue +14 -0
- package/src/components/ui/navigation-menu/NavigationMenuList.vue +21 -0
- package/src/components/ui/navigation-menu/NavigationMenuTrigger.vue +24 -0
- package/src/components/ui/navigation-menu/NavigationMenuViewport.vue +29 -0
- package/src/components/ui/navigation-menu/index.ts +14 -0
- package/src/components/ui/separator/Separator.vue +31 -0
- package/src/components/ui/separator/index.ts +1 -0
- package/src/components/ui/sheet/Sheet.vue +14 -0
- package/src/components/ui/sheet/SheetClose.vue +11 -0
- package/src/components/ui/sheet/SheetContent.vue +53 -0
- package/src/components/ui/sheet/SheetDescription.vue +19 -0
- package/src/components/ui/sheet/SheetFooter.vue +12 -0
- package/src/components/ui/sheet/SheetHeader.vue +12 -0
- package/src/components/ui/sheet/SheetTitle.vue +19 -0
- package/src/components/ui/sheet/SheetTrigger.vue +11 -0
- package/src/components/ui/sheet/index.ts +29 -0
- package/src/components/ui/sidebar/Sidebar.vue +99 -0
- package/src/components/ui/sidebar/SidebarContent.vue +17 -0
- package/src/components/ui/sidebar/SidebarFooter.vue +14 -0
- package/src/components/ui/sidebar/SidebarGroup.vue +14 -0
- package/src/components/ui/sidebar/SidebarGroupAction.vue +31 -0
- package/src/components/ui/sidebar/SidebarGroupContent.vue +14 -0
- package/src/components/ui/sidebar/SidebarGroupLabel.vue +29 -0
- package/src/components/ui/sidebar/SidebarHeader.vue +14 -0
- package/src/components/ui/sidebar/SidebarInput.vue +15 -0
- package/src/components/ui/sidebar/SidebarInset.vue +22 -0
- package/src/components/ui/sidebar/SidebarMenu.vue +14 -0
- package/src/components/ui/sidebar/SidebarMenuAction.vue +41 -0
- package/src/components/ui/sidebar/SidebarMenuBadge.vue +27 -0
- package/src/components/ui/sidebar/SidebarMenuButton.vue +52 -0
- package/src/components/ui/sidebar/SidebarMenuButtonChild.vue +33 -0
- package/src/components/ui/sidebar/SidebarMenuItem.vue +14 -0
- package/src/components/ui/sidebar/SidebarMenuSkeleton.vue +22 -0
- package/src/components/ui/sidebar/SidebarMenuSub.vue +23 -0
- package/src/components/ui/sidebar/SidebarMenuSubButton.vue +42 -0
- package/src/components/ui/sidebar/SidebarMenuSubItem.vue +7 -0
- package/src/components/ui/sidebar/SidebarProvider.vue +89 -0
- package/src/components/ui/sidebar/SidebarRail.vue +34 -0
- package/src/components/ui/sidebar/SidebarSeparator.vue +15 -0
- package/src/components/ui/sidebar/SidebarTrigger.vue +20 -0
- package/src/components/ui/sidebar/index.ts +51 -0
- package/src/components/ui/sidebar/utils.ts +19 -0
- package/src/components/ui/skeleton/Skeleton.vue +14 -0
- package/src/components/ui/skeleton/index.ts +1 -0
- package/src/components/ui/tooltip/Tooltip.vue +14 -0
- package/src/components/ui/tooltip/TooltipContent.vue +39 -0
- package/src/components/ui/tooltip/TooltipProvider.vue +11 -0
- package/src/components/ui/tooltip/TooltipTrigger.vue +11 -0
- package/src/components/ui/tooltip/index.ts +4 -0
- package/src/composables/useAppearance.ts +53 -0
- package/src/composables/useInitials.ts +14 -0
- package/src/index.ts +22 -0
- package/src/layouts/AdminLayout.vue +170 -0
- package/src/layouts/AuthLayout.vue +14 -0
- package/src/layouts/PublicLayout.vue +53 -0
- package/src/layouts/auth/AuthCardLayout.vue +36 -0
- package/src/layouts/auth/AuthSimpleLayout.vue +31 -0
- package/src/layouts/auth/AuthSplitLayout.vue +40 -0
- package/src/layouts/settings/Layout.vue +56 -0
- package/src/lib/utils.ts +6 -0
- package/src/pages/Admin/Appearance/Theme.vue +58 -0
- package/src/pages/Admin/Appearance/Widgets.vue +48 -0
- package/src/pages/Admin/Commerce/Orders/Index.vue +80 -0
- package/src/pages/Admin/Commerce/Orders/Show.vue +200 -0
- package/src/pages/Admin/Commerce/Products/Edit.vue +167 -0
- package/src/pages/Admin/Commerce/Products/Index.vue +65 -0
- package/src/pages/Admin/Content/Edit.vue +170 -0
- package/src/pages/Admin/Content/Index.vue +88 -0
- package/src/pages/Admin/Content/Preview.vue +25 -0
- package/src/pages/Admin/Dashboard.vue +26 -0
- package/src/pages/Admin/Forms/Edit.vue +98 -0
- package/src/pages/Admin/Forms/Index.vue +68 -0
- package/src/pages/Admin/Forms/Submissions/Index.vue +68 -0
- package/src/pages/Admin/Forms/Submissions/Show.vue +47 -0
- package/src/pages/Admin/Media/Index.vue +75 -0
- package/src/pages/Admin/Menus/Create.vue +37 -0
- package/src/pages/Admin/Menus/Edit.vue +54 -0
- package/src/pages/Admin/Menus/Index.vue +52 -0
- package/src/pages/Admin/Settings/Index.vue +184 -0
- package/src/pages/Admin/Taxonomy/Edit.vue +83 -0
- package/src/pages/Admin/Taxonomy/Index.vue +68 -0
- package/src/pages/Admin/Users/Edit.vue +82 -0
- package/src/pages/Admin/Users/Index.vue +74 -0
- package/src/pages/Public/Cart/Index.vue +108 -0
- package/src/pages/Public/Checkout/Confirmation.vue +110 -0
- package/src/pages/Public/Checkout/Index.vue +174 -0
- package/src/pages/Public/Index.vue +54 -0
- package/src/pages/Public/Shop/Index.vue +39 -0
- package/src/pages/Public/Shop/Show.vue +46 -0
- package/src/pages/Public/Show.vue +41 -0
- package/src/pages/Setup/Complete.vue +53 -0
- package/src/pages/Setup/Index.vue +85 -0
- package/src/pages/Welcome.vue +787 -0
- package/src/pages/auth/ConfirmPassword.vue +53 -0
- package/src/pages/auth/ForgotPassword.vue +54 -0
- package/src/pages/auth/Login.vue +91 -0
- package/src/pages/auth/Register.vue +83 -0
- package/src/pages/auth/ResetPassword.vue +81 -0
- package/src/pages/auth/VerifyEmail.vue +36 -0
- package/src/pages/settings/Appearance.vue +23 -0
- package/src/pages/settings/Password.vue +120 -0
- package/src/pages/settings/Profile.vue +105 -0
- package/src/pages.ts +9 -0
- package/src/types/index.ts +42 -0
- package/src/types/ziggy.ts +12 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import InputError from '@/components/InputError.vue';
|
|
3
|
+
import { Button } from '@/components/ui/button';
|
|
4
|
+
import { Input } from '@/components/ui/input';
|
|
5
|
+
import { Label } from '@/components/ui/label';
|
|
6
|
+
import AuthLayout from '@/layouts/AuthLayout.vue';
|
|
7
|
+
import { Head, useForm } from '@inertiajs/vue3';
|
|
8
|
+
import { LoaderCircle } from 'lucide-vue-next';
|
|
9
|
+
|
|
10
|
+
const form = useForm({
|
|
11
|
+
password: '',
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
const submit = () => {
|
|
15
|
+
form.post(route('password.confirm'), {
|
|
16
|
+
onFinish: () => {
|
|
17
|
+
form.reset();
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<template>
|
|
24
|
+
<AuthLayout title="Confirm your password" description="This is a secure area of the application. Please confirm your password before continuing.">
|
|
25
|
+
<Head title="Confirm password" />
|
|
26
|
+
|
|
27
|
+
<form @submit.prevent="submit">
|
|
28
|
+
<div class="space-y-6">
|
|
29
|
+
<div class="grid gap-2">
|
|
30
|
+
<Label htmlFor="password">Password</Label>
|
|
31
|
+
<Input
|
|
32
|
+
id="password"
|
|
33
|
+
type="password"
|
|
34
|
+
class="mt-1 block w-full"
|
|
35
|
+
v-model="form.password"
|
|
36
|
+
required
|
|
37
|
+
autocomplete="current-password"
|
|
38
|
+
autofocus
|
|
39
|
+
/>
|
|
40
|
+
|
|
41
|
+
<InputError :message="form.errors.password" />
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<div class="flex items-center">
|
|
45
|
+
<Button class="w-full" :disabled="form.processing">
|
|
46
|
+
<LoaderCircle v-if="form.processing" class="h-4 w-4 animate-spin" />
|
|
47
|
+
Confirm Password
|
|
48
|
+
</Button>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
</form>
|
|
52
|
+
</AuthLayout>
|
|
53
|
+
</template>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import InputError from '@/components/InputError.vue';
|
|
3
|
+
import TextLink from '@/components/TextLink.vue';
|
|
4
|
+
import { Button } from '@/components/ui/button';
|
|
5
|
+
import { Input } from '@/components/ui/input';
|
|
6
|
+
import { Label } from '@/components/ui/label';
|
|
7
|
+
import AuthLayout from '@/layouts/AuthLayout.vue';
|
|
8
|
+
import { Head, useForm } from '@inertiajs/vue3';
|
|
9
|
+
import { LoaderCircle } from 'lucide-vue-next';
|
|
10
|
+
|
|
11
|
+
defineProps<{
|
|
12
|
+
status?: string;
|
|
13
|
+
}>();
|
|
14
|
+
|
|
15
|
+
const form = useForm({
|
|
16
|
+
email: '',
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const submit = () => {
|
|
20
|
+
form.post(route('password.email'));
|
|
21
|
+
};
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<template>
|
|
25
|
+
<AuthLayout title="Forgot password" description="Enter your email to receive a password reset link">
|
|
26
|
+
<Head title="Forgot password" />
|
|
27
|
+
|
|
28
|
+
<div v-if="status" class="mb-4 text-center text-sm font-medium text-green-600">
|
|
29
|
+
{{ status }}
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<div class="space-y-6">
|
|
33
|
+
<form @submit.prevent="submit">
|
|
34
|
+
<div class="grid gap-2">
|
|
35
|
+
<Label for="email">Email address</Label>
|
|
36
|
+
<Input id="email" type="email" name="email" autocomplete="off" v-model="form.email" autofocus placeholder="email@example.com" />
|
|
37
|
+
<InputError :message="form.errors.email" />
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
<div class="my-6 flex items-center justify-start">
|
|
41
|
+
<Button class="w-full" :disabled="form.processing">
|
|
42
|
+
<LoaderCircle v-if="form.processing" class="h-4 w-4 animate-spin" />
|
|
43
|
+
Email password reset link
|
|
44
|
+
</Button>
|
|
45
|
+
</div>
|
|
46
|
+
</form>
|
|
47
|
+
|
|
48
|
+
<div class="space-x-1 text-center text-sm text-muted-foreground">
|
|
49
|
+
<span>Or, return to</span>
|
|
50
|
+
<TextLink :href="route('login')">log in</TextLink>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
</AuthLayout>
|
|
54
|
+
</template>
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import InputError from '@/components/InputError.vue';
|
|
3
|
+
import TextLink from '@/components/TextLink.vue';
|
|
4
|
+
import { Button } from '@/components/ui/button';
|
|
5
|
+
import { Checkbox } from '@/components/ui/checkbox';
|
|
6
|
+
import { Input } from '@/components/ui/input';
|
|
7
|
+
import { Label } from '@/components/ui/label';
|
|
8
|
+
import AuthBase from '@/layouts/AuthLayout.vue';
|
|
9
|
+
import { Head, useForm } from '@inertiajs/vue3';
|
|
10
|
+
import { LoaderCircle } from 'lucide-vue-next';
|
|
11
|
+
|
|
12
|
+
defineProps<{
|
|
13
|
+
status?: string;
|
|
14
|
+
canResetPassword: boolean;
|
|
15
|
+
}>();
|
|
16
|
+
|
|
17
|
+
const form = useForm({
|
|
18
|
+
email: '',
|
|
19
|
+
password: '',
|
|
20
|
+
remember: false,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const submit = () => {
|
|
24
|
+
form.post(route('login'), {
|
|
25
|
+
onFinish: () => form.reset('password'),
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<template>
|
|
31
|
+
<AuthBase title="Log in to your account" description="Enter your email and password below to log in">
|
|
32
|
+
<Head title="Log in" />
|
|
33
|
+
|
|
34
|
+
<div v-if="status" class="mb-4 text-center text-sm font-medium text-green-600">
|
|
35
|
+
{{ status }}
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<form @submit.prevent="submit" class="flex flex-col gap-6">
|
|
39
|
+
<div class="grid gap-6">
|
|
40
|
+
<div class="grid gap-2">
|
|
41
|
+
<Label for="email">Email address</Label>
|
|
42
|
+
<Input
|
|
43
|
+
id="email"
|
|
44
|
+
type="email"
|
|
45
|
+
required
|
|
46
|
+
autofocus
|
|
47
|
+
tabindex="1"
|
|
48
|
+
autocomplete="email"
|
|
49
|
+
v-model="form.email"
|
|
50
|
+
placeholder="email@example.com"
|
|
51
|
+
/>
|
|
52
|
+
<InputError :message="form.errors.email" />
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
<div class="grid gap-2">
|
|
56
|
+
<div class="flex items-center justify-between">
|
|
57
|
+
<Label for="password">Password</Label>
|
|
58
|
+
<TextLink v-if="canResetPassword" :href="route('password.request')" class="text-sm" tabindex="5"> Forgot password? </TextLink>
|
|
59
|
+
</div>
|
|
60
|
+
<Input
|
|
61
|
+
id="password"
|
|
62
|
+
type="password"
|
|
63
|
+
required
|
|
64
|
+
tabindex="2"
|
|
65
|
+
autocomplete="current-password"
|
|
66
|
+
v-model="form.password"
|
|
67
|
+
placeholder="Password"
|
|
68
|
+
/>
|
|
69
|
+
<InputError :message="form.errors.password" />
|
|
70
|
+
</div>
|
|
71
|
+
|
|
72
|
+
<div class="flex items-center justify-between" tabindex="3">
|
|
73
|
+
<Label for="remember" class="flex items-center space-x-3">
|
|
74
|
+
<Checkbox id="remember" v-model:checked="form.remember" tabindex="4" />
|
|
75
|
+
<span>Remember me</span>
|
|
76
|
+
</Label>
|
|
77
|
+
</div>
|
|
78
|
+
|
|
79
|
+
<Button type="submit" class="mt-4 w-full" tabindex="4" :disabled="form.processing">
|
|
80
|
+
<LoaderCircle v-if="form.processing" class="h-4 w-4 animate-spin" />
|
|
81
|
+
Log in
|
|
82
|
+
</Button>
|
|
83
|
+
</div>
|
|
84
|
+
|
|
85
|
+
<div class="text-center text-sm text-muted-foreground">
|
|
86
|
+
Don't have an account?
|
|
87
|
+
<TextLink :href="route('register')" :tabindex="5">Sign up</TextLink>
|
|
88
|
+
</div>
|
|
89
|
+
</form>
|
|
90
|
+
</AuthBase>
|
|
91
|
+
</template>
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import InputError from '@/components/InputError.vue';
|
|
3
|
+
import TextLink from '@/components/TextLink.vue';
|
|
4
|
+
import { Button } from '@/components/ui/button';
|
|
5
|
+
import { Input } from '@/components/ui/input';
|
|
6
|
+
import { Label } from '@/components/ui/label';
|
|
7
|
+
import AuthBase from '@/layouts/AuthLayout.vue';
|
|
8
|
+
import { Head, useForm } from '@inertiajs/vue3';
|
|
9
|
+
import { LoaderCircle } from 'lucide-vue-next';
|
|
10
|
+
|
|
11
|
+
const form = useForm({
|
|
12
|
+
name: '',
|
|
13
|
+
email: '',
|
|
14
|
+
password: '',
|
|
15
|
+
password_confirmation: '',
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const submit = () => {
|
|
19
|
+
form.post(route('register'), {
|
|
20
|
+
onFinish: () => form.reset('password', 'password_confirmation'),
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<template>
|
|
26
|
+
<AuthBase title="Create an account" description="Enter your details below to create your account">
|
|
27
|
+
<Head title="Register" />
|
|
28
|
+
|
|
29
|
+
<form @submit.prevent="submit" class="flex flex-col gap-6">
|
|
30
|
+
<div class="grid gap-6">
|
|
31
|
+
<div class="grid gap-2">
|
|
32
|
+
<Label for="name">Name</Label>
|
|
33
|
+
<Input id="name" type="text" required autofocus tabindex="1" autocomplete="name" v-model="form.name" placeholder="Full name" />
|
|
34
|
+
<InputError :message="form.errors.name" />
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<div class="grid gap-2">
|
|
38
|
+
<Label for="email">Email address</Label>
|
|
39
|
+
<Input id="email" type="email" required tabindex="2" autocomplete="email" v-model="form.email" placeholder="email@example.com" />
|
|
40
|
+
<InputError :message="form.errors.email" />
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
<div class="grid gap-2">
|
|
44
|
+
<Label for="password">Password</Label>
|
|
45
|
+
<Input
|
|
46
|
+
id="password"
|
|
47
|
+
type="password"
|
|
48
|
+
required
|
|
49
|
+
tabindex="3"
|
|
50
|
+
autocomplete="new-password"
|
|
51
|
+
v-model="form.password"
|
|
52
|
+
placeholder="Password"
|
|
53
|
+
/>
|
|
54
|
+
<InputError :message="form.errors.password" />
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
<div class="grid gap-2">
|
|
58
|
+
<Label for="password_confirmation">Confirm password</Label>
|
|
59
|
+
<Input
|
|
60
|
+
id="password_confirmation"
|
|
61
|
+
type="password"
|
|
62
|
+
required
|
|
63
|
+
tabindex="4"
|
|
64
|
+
autocomplete="new-password"
|
|
65
|
+
v-model="form.password_confirmation"
|
|
66
|
+
placeholder="Confirm password"
|
|
67
|
+
/>
|
|
68
|
+
<InputError :message="form.errors.password_confirmation" />
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
<Button type="submit" class="mt-2 w-full" tabindex="5" :disabled="form.processing">
|
|
72
|
+
<LoaderCircle v-if="form.processing" class="h-4 w-4 animate-spin" />
|
|
73
|
+
Create account
|
|
74
|
+
</Button>
|
|
75
|
+
</div>
|
|
76
|
+
|
|
77
|
+
<div class="text-center text-sm text-muted-foreground">
|
|
78
|
+
Already have an account?
|
|
79
|
+
<TextLink :href="route('login')" class="underline underline-offset-4" tabindex="6">Log in</TextLink>
|
|
80
|
+
</div>
|
|
81
|
+
</form>
|
|
82
|
+
</AuthBase>
|
|
83
|
+
</template>
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import InputError from '@/components/InputError.vue';
|
|
3
|
+
import { Button } from '@/components/ui/button';
|
|
4
|
+
import { Input } from '@/components/ui/input';
|
|
5
|
+
import { Label } from '@/components/ui/label';
|
|
6
|
+
import AuthLayout from '@/layouts/AuthLayout.vue';
|
|
7
|
+
import { Head, useForm } from '@inertiajs/vue3';
|
|
8
|
+
import { LoaderCircle } from 'lucide-vue-next';
|
|
9
|
+
|
|
10
|
+
interface Props {
|
|
11
|
+
token: string;
|
|
12
|
+
email: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const props = defineProps<Props>();
|
|
16
|
+
|
|
17
|
+
const form = useForm({
|
|
18
|
+
token: props.token,
|
|
19
|
+
email: props.email,
|
|
20
|
+
password: '',
|
|
21
|
+
password_confirmation: '',
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const submit = () => {
|
|
25
|
+
form.post(route('password.store'), {
|
|
26
|
+
onFinish: () => {
|
|
27
|
+
form.reset('password', 'password_confirmation');
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<template>
|
|
34
|
+
<AuthLayout title="Reset password" description="Please enter your new password below">
|
|
35
|
+
<Head title="Reset password" />
|
|
36
|
+
|
|
37
|
+
<form @submit.prevent="submit">
|
|
38
|
+
<div class="grid gap-6">
|
|
39
|
+
<div class="grid gap-2">
|
|
40
|
+
<Label for="email">Email</Label>
|
|
41
|
+
<Input id="email" type="email" name="email" autocomplete="email" v-model="form.email" class="mt-1 block w-full" readonly />
|
|
42
|
+
<InputError :message="form.errors.email" class="mt-2" />
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
<div class="grid gap-2">
|
|
46
|
+
<Label for="password">Password</Label>
|
|
47
|
+
<Input
|
|
48
|
+
id="password"
|
|
49
|
+
type="password"
|
|
50
|
+
name="password"
|
|
51
|
+
autocomplete="new-password"
|
|
52
|
+
v-model="form.password"
|
|
53
|
+
class="mt-1 block w-full"
|
|
54
|
+
autofocus
|
|
55
|
+
placeholder="Password"
|
|
56
|
+
/>
|
|
57
|
+
<InputError :message="form.errors.password" />
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
<div class="grid gap-2">
|
|
61
|
+
<Label for="password_confirmation"> Confirm Password </Label>
|
|
62
|
+
<Input
|
|
63
|
+
id="password_confirmation"
|
|
64
|
+
type="password"
|
|
65
|
+
name="password_confirmation"
|
|
66
|
+
autocomplete="new-password"
|
|
67
|
+
v-model="form.password_confirmation"
|
|
68
|
+
class="mt-1 block w-full"
|
|
69
|
+
placeholder="Confirm password"
|
|
70
|
+
/>
|
|
71
|
+
<InputError :message="form.errors.password_confirmation" />
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
<Button type="submit" class="mt-4 w-full" :disabled="form.processing">
|
|
75
|
+
<LoaderCircle v-if="form.processing" class="h-4 w-4 animate-spin" />
|
|
76
|
+
Reset password
|
|
77
|
+
</Button>
|
|
78
|
+
</div>
|
|
79
|
+
</form>
|
|
80
|
+
</AuthLayout>
|
|
81
|
+
</template>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import TextLink from '@/components/TextLink.vue';
|
|
3
|
+
import { Button } from '@/components/ui/button';
|
|
4
|
+
import AuthLayout from '@/layouts/AuthLayout.vue';
|
|
5
|
+
import { Head, useForm } from '@inertiajs/vue3';
|
|
6
|
+
import { LoaderCircle } from 'lucide-vue-next';
|
|
7
|
+
|
|
8
|
+
defineProps<{
|
|
9
|
+
status?: string;
|
|
10
|
+
}>();
|
|
11
|
+
|
|
12
|
+
const form = useForm({});
|
|
13
|
+
|
|
14
|
+
const submit = () => {
|
|
15
|
+
form.post(route('verification.send'));
|
|
16
|
+
};
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<template>
|
|
20
|
+
<AuthLayout title="Verify email" description="Please verify your email address by clicking on the link we just emailed to you.">
|
|
21
|
+
<Head title="Email verification" />
|
|
22
|
+
|
|
23
|
+
<div v-if="status === 'verification-link-sent'" class="mb-4 text-center text-sm font-medium text-green-600">
|
|
24
|
+
A new verification link has been sent to the email address you provided during registration.
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
<form @submit.prevent="submit" class="space-y-6 text-center">
|
|
28
|
+
<Button :disabled="form.processing" variant="secondary">
|
|
29
|
+
<LoaderCircle v-if="form.processing" class="h-4 w-4 animate-spin" />
|
|
30
|
+
Resend verification email
|
|
31
|
+
</Button>
|
|
32
|
+
|
|
33
|
+
<TextLink :href="route('logout')" method="post" as="button" class="mx-auto block text-sm"> Log out </TextLink>
|
|
34
|
+
</form>
|
|
35
|
+
</AuthLayout>
|
|
36
|
+
</template>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { Head } from '@inertiajs/vue3';
|
|
3
|
+
|
|
4
|
+
import AppearanceTabs from '@/components/AppearanceTabs.vue';
|
|
5
|
+
import HeadingSmall from '@/components/HeadingSmall.vue';
|
|
6
|
+
|
|
7
|
+
import AdminLayout from '@/layouts/AdminLayout.vue';
|
|
8
|
+
import SettingsLayout from '@/layouts/settings/Layout.vue';
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<template>
|
|
12
|
+
<AdminLayout>
|
|
13
|
+
<template #title>Settings</template>
|
|
14
|
+
<Head title="Appearance settings" />
|
|
15
|
+
|
|
16
|
+
<SettingsLayout>
|
|
17
|
+
<div class="space-y-6">
|
|
18
|
+
<HeadingSmall title="Appearance settings" description="Update your account's appearance settings" />
|
|
19
|
+
<AppearanceTabs />
|
|
20
|
+
</div>
|
|
21
|
+
</SettingsLayout>
|
|
22
|
+
</AdminLayout>
|
|
23
|
+
</template>
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import InputError from '@/components/InputError.vue';
|
|
3
|
+
import AdminLayout from '@/layouts/AdminLayout.vue';
|
|
4
|
+
import SettingsLayout from '@/layouts/settings/Layout.vue';
|
|
5
|
+
import { TransitionRoot } from '@headlessui/vue';
|
|
6
|
+
import { Head, useForm } from '@inertiajs/vue3';
|
|
7
|
+
import { ref } from 'vue';
|
|
8
|
+
|
|
9
|
+
import HeadingSmall from '@/components/HeadingSmall.vue';
|
|
10
|
+
import { Button } from '@/components/ui/button';
|
|
11
|
+
import { Input } from '@/components/ui/input';
|
|
12
|
+
import { Label } from '@/components/ui/label';
|
|
13
|
+
|
|
14
|
+
interface Props {
|
|
15
|
+
className?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
defineProps<Props>();
|
|
19
|
+
|
|
20
|
+
const passwordInput = ref<HTMLInputElement>();
|
|
21
|
+
const currentPasswordInput = ref<HTMLInputElement>();
|
|
22
|
+
|
|
23
|
+
const form = useForm({
|
|
24
|
+
current_password: '',
|
|
25
|
+
password: '',
|
|
26
|
+
password_confirmation: '',
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const updatePassword = () => {
|
|
30
|
+
form.put(route('password.update'), {
|
|
31
|
+
preserveScroll: true,
|
|
32
|
+
onSuccess: () => form.reset(),
|
|
33
|
+
onError: (errors: any) => {
|
|
34
|
+
if (errors.password) {
|
|
35
|
+
form.reset('password', 'password_confirmation');
|
|
36
|
+
if (passwordInput.value instanceof HTMLInputElement) {
|
|
37
|
+
passwordInput.value.focus();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (errors.current_password) {
|
|
42
|
+
form.reset('current_password');
|
|
43
|
+
if (currentPasswordInput.value instanceof HTMLInputElement) {
|
|
44
|
+
currentPasswordInput.value.focus();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
</script>
|
|
51
|
+
|
|
52
|
+
<template>
|
|
53
|
+
<AdminLayout>
|
|
54
|
+
<template #title>Settings</template>
|
|
55
|
+
<Head title="Profile settings" />
|
|
56
|
+
|
|
57
|
+
<SettingsLayout>
|
|
58
|
+
<div class="space-y-6">
|
|
59
|
+
<HeadingSmall title="Update password" description="Ensure your account is using a long, random password to stay secure" />
|
|
60
|
+
|
|
61
|
+
<form @submit.prevent="updatePassword" class="space-y-6">
|
|
62
|
+
<div class="grid gap-2">
|
|
63
|
+
<Label for="current_password">Current Password</Label>
|
|
64
|
+
<Input
|
|
65
|
+
id="current_password"
|
|
66
|
+
ref="currentPasswordInput"
|
|
67
|
+
v-model="form.current_password"
|
|
68
|
+
type="password"
|
|
69
|
+
class="mt-1 block w-full"
|
|
70
|
+
autocomplete="current-password"
|
|
71
|
+
placeholder="Current password"
|
|
72
|
+
/>
|
|
73
|
+
<InputError :message="form.errors.current_password" />
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<div class="grid gap-2">
|
|
77
|
+
<Label for="password">New password</Label>
|
|
78
|
+
<Input
|
|
79
|
+
id="password"
|
|
80
|
+
ref="passwordInput"
|
|
81
|
+
v-model="form.password"
|
|
82
|
+
type="password"
|
|
83
|
+
class="mt-1 block w-full"
|
|
84
|
+
autocomplete="new-password"
|
|
85
|
+
placeholder="New password"
|
|
86
|
+
/>
|
|
87
|
+
<InputError :message="form.errors.password" />
|
|
88
|
+
</div>
|
|
89
|
+
|
|
90
|
+
<div class="grid gap-2">
|
|
91
|
+
<Label for="password_confirmation">Confirm password</Label>
|
|
92
|
+
<Input
|
|
93
|
+
id="password_confirmation"
|
|
94
|
+
v-model="form.password_confirmation"
|
|
95
|
+
type="password"
|
|
96
|
+
class="mt-1 block w-full"
|
|
97
|
+
autocomplete="new-password"
|
|
98
|
+
placeholder="Confirm password"
|
|
99
|
+
/>
|
|
100
|
+
<InputError :message="form.errors.password_confirmation" />
|
|
101
|
+
</div>
|
|
102
|
+
|
|
103
|
+
<div class="flex items-center gap-4">
|
|
104
|
+
<Button :disabled="form.processing">Save password</Button>
|
|
105
|
+
|
|
106
|
+
<TransitionRoot
|
|
107
|
+
:show="form.recentlySuccessful"
|
|
108
|
+
enter="transition ease-in-out"
|
|
109
|
+
enter-from="opacity-0"
|
|
110
|
+
leave="transition ease-in-out"
|
|
111
|
+
leave-to="opacity-0"
|
|
112
|
+
>
|
|
113
|
+
<p class="text-sm text-neutral-600">Saved</p>
|
|
114
|
+
</TransitionRoot>
|
|
115
|
+
</div>
|
|
116
|
+
</form>
|
|
117
|
+
</div>
|
|
118
|
+
</SettingsLayout>
|
|
119
|
+
</AdminLayout>
|
|
120
|
+
</template>
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { TransitionRoot } from '@headlessui/vue';
|
|
3
|
+
import { Head, Link, useForm, usePage } from '@inertiajs/vue3';
|
|
4
|
+
|
|
5
|
+
import DeleteUser from '@/components/DeleteUser.vue';
|
|
6
|
+
import HeadingSmall from '@/components/HeadingSmall.vue';
|
|
7
|
+
import InputError from '@/components/InputError.vue';
|
|
8
|
+
import { Button } from '@/components/ui/button';
|
|
9
|
+
import { Input } from '@/components/ui/input';
|
|
10
|
+
import { Label } from '@/components/ui/label';
|
|
11
|
+
import AdminLayout from '@/layouts/AdminLayout.vue';
|
|
12
|
+
import SettingsLayout from '@/layouts/settings/Layout.vue';
|
|
13
|
+
import { type SharedData, type User } from '@/types';
|
|
14
|
+
|
|
15
|
+
interface Props {
|
|
16
|
+
mustVerifyEmail: boolean;
|
|
17
|
+
status?: string;
|
|
18
|
+
className?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
defineProps<Props>();
|
|
22
|
+
|
|
23
|
+
const page = usePage<SharedData>();
|
|
24
|
+
const user = page.props.auth.user as User;
|
|
25
|
+
|
|
26
|
+
const form = useForm({
|
|
27
|
+
name: user.name,
|
|
28
|
+
email: user.email,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const submit = () => {
|
|
32
|
+
form.patch(route('profile.update'), {
|
|
33
|
+
preserveScroll: true,
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
<template>
|
|
39
|
+
<AdminLayout>
|
|
40
|
+
<template #title>Settings</template>
|
|
41
|
+
<Head title="Profile settings" />
|
|
42
|
+
|
|
43
|
+
<SettingsLayout>
|
|
44
|
+
<div class="flex flex-col space-y-6">
|
|
45
|
+
<HeadingSmall title="Profile information" description="Update your name and email address" />
|
|
46
|
+
|
|
47
|
+
<form @submit.prevent="submit" class="space-y-6">
|
|
48
|
+
<div class="grid gap-2">
|
|
49
|
+
<Label for="name">Name</Label>
|
|
50
|
+
<Input id="name" class="mt-1 block w-full" v-model="form.name" required autocomplete="name" placeholder="Full name" />
|
|
51
|
+
<InputError class="mt-2" :message="form.errors.name" />
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
<div class="grid gap-2">
|
|
55
|
+
<Label for="email">Email address</Label>
|
|
56
|
+
<Input
|
|
57
|
+
id="email"
|
|
58
|
+
type="email"
|
|
59
|
+
class="mt-1 block w-full"
|
|
60
|
+
v-model="form.email"
|
|
61
|
+
required
|
|
62
|
+
autocomplete="username"
|
|
63
|
+
placeholder="Email address"
|
|
64
|
+
/>
|
|
65
|
+
<InputError class="mt-2" :message="form.errors.email" />
|
|
66
|
+
</div>
|
|
67
|
+
|
|
68
|
+
<div v-if="mustVerifyEmail && !user.email_verified_at">
|
|
69
|
+
<p class="mt-2 text-sm text-neutral-800">
|
|
70
|
+
Your email address is unverified.
|
|
71
|
+
<Link
|
|
72
|
+
:href="route('verification.send')"
|
|
73
|
+
method="post"
|
|
74
|
+
as="button"
|
|
75
|
+
class="focus:outline-hidden rounded-md text-sm text-neutral-600 underline hover:text-neutral-900 focus:ring-2 focus:ring-offset-2"
|
|
76
|
+
>
|
|
77
|
+
Click here to re-send the verification email.
|
|
78
|
+
</Link>
|
|
79
|
+
</p>
|
|
80
|
+
|
|
81
|
+
<div v-if="status === 'verification-link-sent'" class="mt-2 text-sm font-medium text-green-600">
|
|
82
|
+
A new verification link has been sent to your email address.
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
|
|
86
|
+
<div class="flex items-center gap-4">
|
|
87
|
+
<Button :disabled="form.processing">Save</Button>
|
|
88
|
+
|
|
89
|
+
<TransitionRoot
|
|
90
|
+
:show="form.recentlySuccessful"
|
|
91
|
+
enter="transition ease-in-out"
|
|
92
|
+
enter-from="opacity-0"
|
|
93
|
+
leave="transition ease-in-out"
|
|
94
|
+
leave-to="opacity-0"
|
|
95
|
+
>
|
|
96
|
+
<p class="text-sm text-neutral-600">Saved.</p>
|
|
97
|
+
</TransitionRoot>
|
|
98
|
+
</div>
|
|
99
|
+
</form>
|
|
100
|
+
</div>
|
|
101
|
+
|
|
102
|
+
<DeleteUser />
|
|
103
|
+
</SettingsLayout>
|
|
104
|
+
</AdminLayout>
|
|
105
|
+
</template>
|
package/src/pages.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { DefineComponent } from 'vue';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Every Inertia page shipped by the CMS app shell. The glob is resolved relative to
|
|
5
|
+
* this file (packages/cms-app/src), so it captures the package's own pages. Client
|
|
6
|
+
* sites layer their own pages on top via {@link resolveCmsPage} in ./index.ts — keys
|
|
7
|
+
* from both globs share the `./pages/Name.vue` shape, so a same-named local page wins.
|
|
8
|
+
*/
|
|
9
|
+
export const cmsPages = import.meta.glob<DefineComponent>('./pages/**/*.vue');
|