Skip to content

Commit f3f4c89

Browse files
committed
feat: username mods - beautified. Admin/User sidebar mods
1 parent e56d623 commit f3f4c89

File tree

6 files changed

+190
-85
lines changed

6 files changed

+190
-85
lines changed

app/Repositories/UserRepository.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,18 @@ public function create(array $data, $role) : false|User
108108
// set an appropriate (user)name if not provided
109109
if (!isset($data['name']) || empty($data['name'])) {
110110
if (isset($data['first_name'])) {
111-
$data['name'] = Str::slug($data['first_name'] . '-' . Str::random(5));
111+
$data['name'] = Str::slug($data['first_name']);
112112
} else if (isset($data['email'])) {
113-
$data['name'] = Str::slug(explode('@', $data['email'])[0] . '-' . Str::random(5));
113+
$data['name'] = Str::slug(explode('@', $data['email'])[0]);
114114
} else {
115115
$data['name'] = Str::slug(Str::random(10));
116116
}
117+
118+
// check if username exists. if exists, append random str
119+
$existingUsername = User::where('name', $data['name'])->first();
120+
if($existingUsername) {
121+
$data['name'] = $data['name'] . '-' . Str::random(3);
122+
}
117123
}
118124

119125
$user = User::create($data);
Lines changed: 72 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,110 @@
11
<script lang="ts">
2-
import { inertia, page } from '@inertiajs/svelte'
2+
import { inertia, page, useForm } from '@inertiajs/svelte'
3+
import { Icon, Input, ThemeSwitcher } from '.'
4+
import { createEventDispatcher } from 'svelte'
5+
6+
const dispatch = createEventDispatcher()
7+
8+
function handleClick() {
9+
dispatch('click')
10+
}
11+
12+
$: auth = $page.props.auth?.user
13+
14+
let form = useForm()
15+
16+
function handleLogout(e) {
17+
e.preventDefault()
18+
19+
$form.post(route('logout'))
20+
}
321
422
type NavItem = {
523
title: string
624
route: string
25+
icon: string
726
}
827
928
const navItems: NavItem[] = [
1029
{
1130
title: 'Dashboard',
1231
route: route('admin.dashboard'),
32+
icon: 'home',
1333
},
1434
{
1535
title: 'Configurations',
1636
route: route('admin.settings.configurations'),
37+
icon: 'user',
1738
},
1839
{
1940
title: 'Reset System',
2041
route: route('admin.settings.reset-system'),
42+
icon: 'bug',
43+
},
44+
{
45+
title: ' My Profile',
46+
route: route('user.profile'),
47+
icon: 'user',
2148
},
2249
{
2350
title: 'Go Home',
2451
route: '/',
52+
icon: 'arrow-back',
2553
},
2654
]
27-
28-
function drawerClose(): void {
29-
// drawerStore.close()
30-
}
3155
</script>
3256

33-
<nav class="list-nav">
57+
<div class="">
58+
<!-- <img src={$page.props.siteLogo} alt={$page.props.siteName} /> -->
59+
<h3 class="text-2xl font-normal underline underline-offset-8">{$page.props.siteName}</h3>
60+
<br />
61+
<div class="flex gap-5 items-center">
62+
<img src={auth.avatar_url} alt="avatar" class="bg-gray-200 rounded-full w-14 h-14" />
63+
<div class="flex-1">
64+
<h4 class="font-semibold text-xl text-gray-800 dark:text-gray-200">{auth.full_name}</h4>
65+
<p class="text-gray-500">@{auth.name}</p>
66+
</div>
67+
</div>
68+
<br />
69+
<Input name="search" placeholder="Search" prefixIcon="search" color="default" />
70+
</div>
71+
72+
<nav class="overflow-y-auto">
3473
<ul>
3574
{#each navItems as item}
3675
<li>
3776
<a
38-
class="!rounded hover:rounded focus:rounded"
39-
class:bg-primary-active-token={item.route.endsWith($page.url)}
77+
class="nav-item"
78+
class:active={item.route.endsWith($page.url)}
4079
href={item.route}
4180
use:inertia
42-
on:click={drawerClose}
43-
>{item.title}
81+
on:click={handleClick}
82+
>
83+
<Icon name={item.icon} classes="text-xl text-gray-600 dark:text-gray-400" />
84+
{item.title}
4485
</a>
4586
</li>
4687
{/each}
4788
</ul>
89+
<br />
90+
<ul>
91+
<li class="pl-4">
92+
<ThemeSwitcher />
93+
</li>
94+
<li>
95+
<a href=":;" class="nav-item" on:click|preventDefault={handleLogout}>
96+
<Icon name="exit" classes="text-xl text-gray-600 dark:text-gray-400" />
97+
Logout</a
98+
>
99+
</li>
100+
</ul>
48101
</nav>
102+
103+
<style lang="css">
104+
.nav-item {
105+
@apply no-underline hover:no-underline px-3 py-2 rounded hover:bg-gray-200 dark:hover:bg-gray-700 flex gap-2 items-center text-gray-900 dark:text-gray-200 text-lg;
106+
}
107+
.nav-item.active {
108+
@apply bg-gray-200 dark:bg-gray-700 border-l-4 border-gray-300 dark:border-gray-600;
109+
}
110+
</style>

resources/ts/Components/UserSidebar.svelte

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
<li>
6666
<a
6767
class="nav-item"
68-
class:bg-primary-active-token={item.route.endsWith($page.url)}
68+
class:active={item.route.endsWith($page.url)}
6969
href={item.route}
7070
use:inertia
7171
on:click={handleClick}
@@ -94,4 +94,7 @@
9494
.nav-item {
9595
@apply no-underline hover:no-underline px-3 py-2 rounded hover:bg-gray-200 dark:hover:bg-gray-700 flex gap-2 items-center text-gray-900 dark:text-gray-200 text-lg;
9696
}
97+
.nav-item.active {
98+
@apply bg-gray-200 dark:bg-gray-700 border-l-4 border-gray-300 dark:border-gray-600;
99+
}
97100
</style>
Lines changed: 93 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,114 @@
11
<script lang="ts">
22
import MainLayout from './MainLayout.svelte'
3-
import { page, inertia, useForm } from '@inertiajs/svelte'
3+
import { page } from '@inertiajs/svelte'
4+
import { Button, Icon, ThemeSwitcher } from '@/Components'
5+
import { onMount } from 'svelte'
6+
import { slide } from 'svelte/transition'
7+
import { quintOut } from 'svelte/easing'
48
import AdminSidebar from '@/Components/AdminSidebar.svelte'
59
610
$: auth = $page.props.auth.user
711
8-
let form = useForm()
12+
let isMobile = false
13+
let isDrawerShown = false
14+
let x = 0
915
10-
function handleLogout(e) {
11-
e.preventDefault()
12-
13-
$form.post(route('logout'))
16+
$: if (x > 768) {
17+
isMobile = false
18+
} else {
19+
isMobile = true
1420
}
1521
16-
function drawerOpen(): void {
17-
// drawerStore.open({})
22+
onMount(() => {
23+
isMobile = window.innerWidth < 768
24+
})
25+
26+
function closeDrawer() {
27+
isDrawerShown = false
1828
}
1929
</script>
2030

21-
<MainLayout>
22-
<AppShell
23-
slotSidebarLeft="bg-surface-500/5 w-0 lg:w-64"
24-
regionPage="overflow-y-auto relative h-screen scrollbar-hidden"
25-
>
26-
<svelte:fragment slot="header">
27-
<div class="bg-surface-100-800-token">
28-
<div class="container">
29-
<AppBar background="bg-transparent">
30-
<svelte:fragment slot="lead">
31-
<button class="lg:hidden btn btn-sm mr-4" on:click={drawerOpen}>
32-
<span>
33-
<svg viewBox="0 0 100 80" class="fill-token w-4 h-4">
34-
<rect width="100" height="20" />
35-
<rect y="30" width="100" height="20" />
36-
<rect y="60" width="100" height="20" />
37-
</svg>
38-
</span>
39-
</button>
40-
<a href={route('admin.dashboard')} use:inertia>
41-
<strong class="text-xl uppercase">{$page.props.siteName}</strong>
42-
</a>
43-
</svelte:fragment>
31+
<svelte:window bind:innerWidth={x} />
4432

45-
<svelte:fragment slot="trail">
46-
<LightSwitch />
47-
48-
<form on:submit|preventDefault={handleLogout}>
49-
<button type="submit" class="btn btn-sm variant-ghost-surface"> Logout </button>
50-
</form>
33+
<MainLayout>
34+
<div class="user-dashboard flex flex-wrap relative">
35+
<!-- desktop -->
36+
<div class="hidden md:block md:w-72 h-full bg-gray-100 dark:bg-gray-800">
37+
<div class="p-5 pt-6">
38+
<AdminSidebar on:click={closeDrawer} />
39+
</div>
40+
</div>
5141

52-
<span class="hidden lg:block">
53-
<a class="btn btn-sm variant-ghost-surface" href={route('admin.profile')} use:inertia>
54-
Profile
55-
</a>
56-
</span>
57-
</svelte:fragment>
58-
</AppBar>
42+
<!-- mobile -->
43+
{#if isMobile && isDrawerShown}
44+
<div
45+
class="md:hidden absolute w-full h-full z-20"
46+
in:slide={{ axis: 'x', duration: 300, easing: quintOut }}
47+
>
48+
<div class="relative">
49+
<div class="w-[100vw] h-[100vh] bg-gray-800/50 dark:bg-gray-600/50" on:click={closeDrawer}>
50+
<div class="absolute top-5 right-5">
51+
<Icon name="x-circle" classes="text-3xl text-white" />
52+
</div>
53+
</div>
54+
<div class="w-72 z-20 h-full bg-gray-100 dark:bg-gray-800 absolute top-0 left-0">
55+
<div class="p-5 pt-6">
56+
<AdminSidebar on:click={closeDrawer} />
57+
</div>
58+
</div>
5959
</div>
6060
</div>
61-
</svelte:fragment>
62-
63-
<!-- sidebar -->
64-
<Drawer regionDrawer="mt-16 w-56 pb-16">
65-
<AdminSidebar />
66-
</Drawer>
61+
{/if}
6762

68-
<svelte:fragment slot="sidebarLeft">
69-
<div id="sidebar-left" class="hidden lg:block">
70-
<div class="overflow-y-auto h-screen">
71-
<AdminSidebar />
63+
<div class="w-full md:flex-1 bg-white dark:bg-gray-900">
64+
<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between">
65+
<h3 class="text-xl font-semibold">
66+
{$page.props.title}
67+
</h3>
68+
<div />
69+
<div class="flex gap-2 items-center">
70+
<Icon name="bell" classes="text-2xl text-gray-600 dark:text-gray-300" />
71+
<Icon name="message" classes="text-2xl text-gray-600 dark:text-gray-300" />
72+
<div class="hidden md:block">
73+
<ThemeSwitcher />
74+
</div>
75+
<div class="hidden md:block">
76+
<Button size="sm">Share</Button>
77+
</div>
78+
<div class="hidden md:block">
79+
<Button size="sm" color="secondary">Create</Button>
80+
</div>
81+
<button
82+
type="button"
83+
class="inline-flex items-center p-2 text-sm rounded-lg md:hidden lg:hover:bg-primary-100 focus:outline-none focus:ring-2 focus:ring-primary-200"
84+
aria-controls="navbar-sticky"
85+
aria-expanded="false"
86+
on:click={() => (isDrawerShown = !isDrawerShown)}
87+
>
88+
<span class="sr-only">Open main menu</span>
89+
<svg
90+
class="w-6 h-6"
91+
aria-hidden="true"
92+
fill="currentColor"
93+
viewBox="0 0 20 20"
94+
xmlns="http://www.w3.org/2000/svg"
95+
><path
96+
fill-rule="evenodd"
97+
d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 15a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z"
98+
clip-rule="evenodd"
99+
/></svg
100+
>
101+
</button>
72102
</div>
73103
</div>
74-
</svelte:fragment>
75104

76-
<!-- content -->
77-
<slot />
78-
<div class="my-4" />
79-
</AppShell>
105+
<slot />
106+
</div>
107+
</div>
80108
</MainLayout>
109+
110+
<style lang="css">
111+
.user-dashboard {
112+
@apply bg-gray-100 dark:bg-gray-800 min-h-screen;
113+
}
114+
</style>

resources/ts/Pages/Auth/Login.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,9 @@
107107

108108
{#if canRegister}
109109
<br />
110-
<p>
110+
<p class="text-right">
111111
Don't have an account yet?
112-
<a href={route('register')}>Register here</a>
112+
<a href={route('register')} class="underline">Register here</a>
113113
</p>
114114
{/if}
115115
</div>

resources/ts/Pages/Auth/Register.svelte

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,17 @@
3737
<p class="text-center">Fill in the form below</p>
3838
<br />
3939
<form on:submit|preventDefault={handleSubmit}>
40+
<Input
41+
name="email"
42+
label="Email"
43+
oneLine
44+
hasError={$form.errors.email}
45+
type="email"
46+
placeholder="[email protected]"
47+
bind:value={$form.email}
48+
required
49+
/>
50+
4051
<Input
4152
name="username"
4253
label="Username"
@@ -68,17 +79,6 @@
6879
bind:value={$form.password_confirmation}
6980
/>
7081

71-
<Input
72-
name="email"
73-
label="Email"
74-
oneLine
75-
hasError={$form.errors.email}
76-
type="email"
77-
placeholder="[email protected]"
78-
bind:value={$form.email}
79-
required
80-
/>
81-
8282
<Input
8383
name="phone"
8484
label="Phone"

0 commit comments

Comments
 (0)