Skip to content

Commit fafa486

Browse files
committed
feat: adde admin and user profile pages
1 parent c0166ba commit fafa486

File tree

11 files changed

+255
-9
lines changed

11 files changed

+255
-9
lines changed

resources/ts/Components/Icon.svelte

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
return 'bx bxs-star'
2121
case 'star-empty':
2222
return 'bx bx-star'
23+
case 'arrow-up':
24+
return 'bx bx-up-arrow-alt'
25+
case 'arrow-down':
26+
return 'bx bx-down-arrow-alt'
2327
}
2428
2529
return `bx bx-${name}`

resources/ts/Layouts/AdminDashboardLayout.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
<div class="flex-1 flex flex-col min-h-0">
3838
<div class="flex items-center h-16 flex-shrink-0 px-4 bg-gray-900">
3939
<!-- <img class="h-8 w-auto" src={$page.props.siteLogo} alt={$page.props.siteName} /> -->
40-
<h3 class="text-2xl text-white font-semibold">{$page.props.siteName}</h3>
40+
<h3 class="text-2xl text-white font-semibold">{$page.props.siteName} - Admin</h3>
4141
</div>
4242
<div class="flex-1 flex flex-col overflow-y-auto bg-gray-800 dark:border-r dark:border-gray-700">
4343
<AdminSidebar on:click={closeDrawer} />
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<script lang="ts">
2+
import { Icon } from '@/Components'
3+
import { numberFormatInt } from '@/helpers'
4+
5+
const title = 'Last 30 days'
6+
7+
type Stat = {
8+
title: string
9+
previous: string
10+
current: string
11+
is_increase: boolean
12+
percentage: number
13+
}
14+
15+
const stats: Stat[] = [
16+
{
17+
title: 'Total Subscribers',
18+
previous: numberFormatInt(70946),
19+
current: numberFormatInt(71897),
20+
is_increase: true,
21+
percentage: 12,
22+
},
23+
{
24+
title: 'Avg. Open Rate',
25+
previous: '56.14%',
26+
current: '58.16%',
27+
is_increase: true,
28+
percentage: 2.02,
29+
},
30+
{
31+
title: 'Avg. Click Rate',
32+
previous: '28.62%',
33+
current: '24.57%',
34+
is_increase: false,
35+
percentage: 4.05,
36+
},
37+
]
38+
</script>
39+
40+
<div>
41+
<h3 class="text-lg leading-6 font-medium text-gray-900 dark:text-gray-100">{title}</h3>
42+
<dl
43+
class="mt-5 grid grid-cols-1 rounded-lg bg-white dark:bg-gray-800 overflow-hidden shadow divide-y divide-gray-200 dark:divide-gray-600 md:grid-cols-3 md:divide-y-0 md:divide-x"
44+
>
45+
{#each stats as item}
46+
<div class="px-4 py-5 sm:p-6">
47+
<dt class="text-base font-normal text-gray-900 dark:text-gray-100">{item.title}</dt>
48+
<dd class="mt-1 flex justify-between items-baseline md:block lg:flex">
49+
<div class="flex items-baseline text-2xl font-semibold text-primary-600 dark:text-primary-300">
50+
{item.current}
51+
<span class="ml-2 text-sm font-medium text-gray-500 dark:text-gray-400">
52+
from {item.previous}
53+
</span>
54+
</div>
55+
56+
<div
57+
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-sm font-medium md:mt-2 lg:mt-0"
58+
class:bg-green-100={item.is_increase}
59+
class:text-green-800={item.is_increase}
60+
class:bg-red-100={!item.is_increase}
61+
class:text-red-800={!item.is_increase}
62+
>
63+
{#if item.is_increase}
64+
<Icon name="arrow-up" classes="text-green-500 -ml-1 mr-0.5 text-xl" />
65+
{:else}
66+
<Icon name="arrow-down" classes="text-red-500 -ml-1 mr-0.5 text-xl" />
67+
{/if}
68+
<span class="sr-only"> {item.is_increase ? 'Increased' : 'Decreased'} by </span>
69+
{item.percentage}%
70+
</div>
71+
</dd>
72+
</div>
73+
{/each}
74+
</dl>
75+
</div>
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
<script>
1+
<script lang="ts">
22
import { Title } from '@/Components'
33
import { page } from '@inertiajs/svelte'
4+
5+
export let title: string | null = $page.props.title
46
</script>
57

68
<Title bgColor="bg-gray-100 dark:bg-gray-900"
79
><slot>
8-
{$page.props.title}
10+
{title}
911
</slot></Title
1012
>

resources/ts/Pages/Admin/Components/ContactMessages.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@
4949
}
5050
</script>
5151

52-
<h4 class="mb-4">Contact Messages</h4>
53-
<div class="card p-4">
52+
<h3 class="text-lg leading-6 mb-3 font-medium text-gray-900 dark:text-gray-100">Contact Messages</h3>
53+
<div class="">
5454
{#if messages.length > 0}
5555
<SimpleTable {headers} hasFooter>
5656
{#each messages as item}

resources/ts/Pages/Admin/Dashboard.svelte

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import { onMount } from 'svelte'
66
import ContactMessages from './Components/ContactMessages.svelte'
77
import AdminTitle from './Components/AdminTitle.svelte'
8+
import AdminStats from './Components/AdminStats.svelte'
89
910
let ready = false
1011
onMount(() => (ready = true))
@@ -13,8 +14,9 @@
1314
<div class="">
1415
{#if ready}
1516
<div in:fly={{ y: -70, duration: 300, easing: quintOut }}>
16-
<br />
1717
<AdminTitle>Admin Dashboard</AdminTitle>
18+
<AdminStats />
19+
<br />
1820
<ContactMessages />
1921
</div>
2022
{/if}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,72 @@
11
<script lang="ts">
2+
import { page } from '@inertiajs/svelte'
3+
import type { User } from '@/types'
24
import AdminTitle from '../Components/AdminTitle.svelte'
5+
import { fromNow } from '@/helpers'
6+
7+
let auth = $page.props.auth.user as User
8+
9+
type ProfileItem = {
10+
text: string
11+
value: string | null | undefined
12+
}
13+
14+
const infos: ProfileItem[] = [
15+
{
16+
text: 'Full Name',
17+
value: auth?.full_name,
18+
},
19+
{
20+
text: 'Email',
21+
value: auth.email,
22+
},
23+
{
24+
text: 'Phone',
25+
value: auth.phone ?? '-',
26+
},
27+
{
28+
text: 'Role',
29+
value: auth.role,
30+
},
31+
{
32+
text: 'Status',
33+
value: auth.status,
34+
},
35+
{
36+
text: 'Last login',
37+
value: fromNow(auth.last_login_at_w3c),
38+
},
39+
{
40+
text: 'Verified',
41+
value: fromNow(auth.verified_at_w3c),
42+
},
43+
{
44+
text: 'Joined on',
45+
value: fromNow(auth.created_at_w3c),
46+
},
47+
{
48+
text: 'Last updated on',
49+
value: fromNow(auth.updated_at_w3c),
50+
},
51+
]
352
</script>
453

554
<div class="">
655
<AdminTitle />
56+
<div>
57+
<div>
58+
<h3 class="text-lg leading-6 font-medium text-gray-900 dark:text-gray-100">Main Profile</h3>
59+
<p class="mt-1 max-w-2xl text-sm text-gray-500">Personal details about you.</p>
60+
</div>
61+
<div class="mt-5 border-t border-gray-200 dark:border-gray-800">
62+
<dl class="sm:divide-y sm:divide-gray-200">
63+
{#each infos as item}
64+
<div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4">
65+
<dt class="text-sm font-medium text-gray-500">{item.text}</dt>
66+
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{item.value}</dd>
67+
</div>
68+
{/each}
69+
</dl>
70+
</div>
71+
</div>
772
</div>
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
<script>
1+
<script lang="ts">
22
import { Title } from '@/Components'
33
import { page } from '@inertiajs/svelte'
4+
5+
export let title: string | null = $page.props.title
46
</script>
57

68
<Title bgColor="bg-gray-100 dark:bg-gray-900"
79
><slot>
8-
{$page.props.title}
10+
{title}
911
</slot></Title
1012
>
Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,74 @@
11
<script lang="ts">
2+
import { page } from '@inertiajs/svelte'
3+
import type { User } from '@/types'
4+
import { fromNow } from '@/helpers'
25
import UserTitle from '../Components/UserTitle.svelte'
6+
7+
let auth = $page.props.auth.user as User
8+
9+
type ProfileItem = {
10+
text: string
11+
value: string | null | undefined
12+
}
13+
14+
const infos: ProfileItem[] = [
15+
{
16+
text: 'Full Name',
17+
value: auth?.full_name,
18+
},
19+
{
20+
text: 'Email',
21+
value: auth.email,
22+
},
23+
{
24+
text: 'Phone',
25+
value: auth.phone ?? '-',
26+
},
27+
{
28+
text: 'Role',
29+
value: auth.role,
30+
},
31+
{
32+
text: 'Status',
33+
value: auth.status,
34+
},
35+
{
36+
text: 'Last login',
37+
value: fromNow(auth.last_login_at_w3c),
38+
},
39+
{
40+
text: 'Verified',
41+
value: fromNow(auth.verified_at_w3c),
42+
},
43+
{
44+
text: 'Joined on',
45+
value: fromNow(auth.created_at_w3c),
46+
},
47+
{
48+
text: 'Last updated on',
49+
value: fromNow(auth.updated_at_w3c),
50+
},
51+
]
352
</script>
453

554
<div class="">
6-
<UserTitle>Profile</UserTitle>
55+
<UserTitle title="My Profile" />
56+
<div>
57+
<div>
58+
<h3 class="text-lg leading-6 font-medium text-gray-900 dark:text-gray-100">Main Profile</h3>
59+
<p class="mt-1 max-w-2xl text-sm text-gray-500">Personal details about you.</p>
60+
</div>
61+
<div class="mt-5 border-t border-gray-200 dark:border-gray-800">
62+
<dl class="sm:divide-y sm:divide-gray-200 dark:sm:divide-gray-700">
63+
{#each infos as item}
64+
<div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4">
65+
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400">{item.text}</dt>
66+
<dd class="mt-1 text-sm text-gray-900 dark:text-gray-100 sm:mt-0 sm:col-span-2">
67+
{item.value}
68+
</dd>
69+
</div>
70+
{/each}
71+
</dl>
72+
</div>
73+
</div>
774
</div>

resources/ts/helpers.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Swal from 'sweetalert2';
22
import dayjs from 'dayjs';
3+
import numeral from 'numeral'
34
import relativeTime from "dayjs/plugin/relativeTime";
45
dayjs.extend(relativeTime);
56

0 commit comments

Comments
 (0)