Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: sign-in by credentials #194

Merged
merged 2 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions apps/food/app/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,12 @@ export default defineAppConfig({
undo: 'lucide:undo-2',
basket: 'lucide:shopping-basket',
maintenance: 'lucide:traffic-cone',
dashboard: 'lucide:layout-dashboard',
image: 'lucide:image',
box: 'lucide:box',
users: 'lucide:users',
list: 'lucide:layout-list',
checkouts: 'lucide:copy-check',
options: 'lucide:cog',
},
})
5 changes: 5 additions & 0 deletions apps/food/app/assets/css/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,9 @@ body {
.button-gradient {
background-color: #86efac;
background-image: linear-gradient(to bottom right, #fef3c7, #86efac);
}

.button-gradient-command-center {
background-color: #60a5fa;
background-image: linear-gradient(to bottom right, #dbeafe, #a5b4fc);
}
43 changes: 43 additions & 0 deletions apps/food/app/components/CommandCenter/Header.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<template>
<div class="w-full h-full px-4 flex flex-row flex-nowrap justify-between content-center items-center border-b border-gray-100">
<div class="mr-2 2xl:hidden flex justify-center items-center justify-items-center h-full hover:scale-110 transition duration-200">
<button
aria-label="Close Navigation"
:data-active="isNavbarOpened"
class="hidden data-[active=true]:flex items-center"
@click="isNavbarOpened = false"
>
<Icon :name="icons.close" class="w-10 h-10" />
</button>
<button
aria-label="Open Navigation"
:data-active="!isNavbarOpened"
class="hidden data-[active=true]:flex items-center"
@click="isNavbarOpened = true"
>
<Icon :name="icons.menu" class="w-10 h-10" />
</button>
</div>

<div class="mr-auto">
<div class="flex flex-row gap-2 items-center">
<Icon :name="icons.search" class="w-8 h-8" />
<input type="text" placeholder="Найти что-нибудь">
</div>
</div>

<div class="hidden md:flex flex-row gap-4 items-center">
<NuxtLink
to="/"
class="px-5 py-3 w-full flex flex-row gap-2 justify-center items-center text-base font-normal cursor-pointer rounded-2xl bg-gray-200 active:scale-95 hover:bg-gray-300 lg:hover:scale-95 lg:active:scale-90 duration-200"
>
<Icon :name="icons.undo" size="20" /> К веб-сайту
</NuxtLink>
</div>
</div>
</template>

<script setup lang="ts">
const { icons } = useAppConfig()
const { isNavbarOpened } = useCommandCenter()
</script>
68 changes: 68 additions & 0 deletions apps/food/app/components/CommandCenter/Navigation.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<template>
<nav
:data-active="isNavbarOpened"
class="z-10 w-0 invisible 2xl:visible 2xl:w-72 fixed top-16 data-[active=true]:w-full data-[active=true]:visible md:data-[active=true]:w-72"
>
<div class="w-full bg-gray-50 px-4 pt-4 border-r border-gray-100">
<div class="h-[calc(100vh-64px)] overflow-y-auto flex flex-col justify-between">
<div class="mb-32">
<div class="flex flex-row items-center pb-2">
<div class="font-semibold text-xl">
Командный центр
</div>
</div>

<CommandCenterNavigationButton v-for="(item, index) in menu" :key="index" :label="item.label" :link="item.link" :icon="item.icon" />
</div>

<div class="mb-8 px-2 py-3 border rounded-2xl flex flex-row gap-2 items-center">
<img
:src="userAvatar"
width="40"
height="40"
alt=""
class="w-12 h-12 rounded-full cursor-pointer hover:scale-95 duration-200"
@click="() => {}"
>
<div>
<p>Админ</p>
</div>
</div>
</div>
</div>
</nav>
</template>

<script setup lang="ts">
const { isNavbarOpened } = useCommandCenter()
const { icons } = useAppConfig()
const menu = [
{
label: 'Панель управления',
link: '/command-center',
icon: icons.dashboard,
},
{
label: 'Меню',
link: '/',
icon: icons.list,
},
{
label: 'Заявки',
link: '/',
icon: icons.checkouts,
},
{
label: 'Клиенты',
link: '/',
icon: icons.users,
},
{
label: 'Настройки',
link: '/',
icon: icons.options,
},
]

const userAvatar = '/burger-1.jpg'
</script>
20 changes: 20 additions & 0 deletions apps/food/app/components/CommandCenter/NavigationButton.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<template>
<NuxtLink
:to="link"
class="text-base font-normal flex flex-row items-center gap-3 w-full h-12 px-3 rounded-2xl data-[active=true]:bg-gray-200 data-[active=true]:font-medium hover:bg-gray-100 hover:scale-95 duration-200"
:data-active="path === link"
>
<Icon :name="icon" class="w-6 h-6 opacity-40" />
{{ label }}
</NuxtLink>
</template>

<script setup lang="ts">
defineProps<{
link: string
label: string
icon: string
}>()

const { path } = useRoute()
</script>
13 changes: 13 additions & 0 deletions apps/food/app/components/CommandCenter/StaffBar.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<template>
<div class="relative px-4 pt-4 pb-2">
<div class="bg-white p-4 flex justify-between items-center rounded-2xl">
<p class="grow text-lg">
Привет, админ!
</p>

<NuxtLink to="/command-center" class="button-gradient-command-center px-4 py-3 flex flex-row gap-2 flex-wrap justify-between items-center rounded-xl cursor-pointer active:scale-95 lg:hover:scale-95 lg:active:scale-90 duration-200">
Продолжить работу
</NuxtLink>
</div>
</div>
</template>
21 changes: 21 additions & 0 deletions apps/food/app/composables/useCommandCenter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
function _useCommandCenter() {
const route = useRoute()

const isNavbarOpened = ref(false)
const searchQuery = ref('')

watch(
() => route.fullPath,
() => {
isNavbarOpened.value = false
searchQuery.value = ''
},
)

return {
isNavbarOpened,
searchQuery,
}
}

export const useCommandCenter = createSharedComposable(_useCommandCenter)
13 changes: 12 additions & 1 deletion apps/food/app/layouts/commandCenter.vue
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
<template>
<slot />
<header class="z-20 h-16 bg-white fixed top-0 left-0 right-0">
<CommandCenterHeader />
</header>

<CommandCenterNavigation />

<main class="min-h-dvh relative w-auto bg-white top-16 2xl:pl-72">
<div class="min-h-[75vh] px-4 pb-10 pt-4">
<slot />
</div>
<Footer />
</main>
</template>
3 changes: 3 additions & 0 deletions apps/food/app/layouts/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
<Navigation />

<main class="relative w-auto bg-gray-100 md:pl-72 xl:pr-80 top-16">
<CommandCenterStaffBar v-if="user?.isStaff" />
<MaintenanceMessage v-if="channelData?.channel?.isActive === false" />

<div class="px-4 pb-10 pt-4">
<slot />
</div>
Expand All @@ -22,4 +24,5 @@

<script setup lang="ts">
const channelData = await useChannel()
const { user } = useUserSession()
</script>
2 changes: 0 additions & 2 deletions apps/food/app/pages/checkout/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@
</template>

<script setup lang="ts">
import CheckoutDeliveryForm from '~/components/checkout/CheckoutDeliveryForm.vue'

definePageMeta({
layout: 'checkout',
})
Expand Down
37 changes: 32 additions & 5 deletions apps/food/app/pages/command-center/sign-in/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,29 @@
Мы вас заждались!
</h1>

<form action="" class="max-w-sm">
<div class="max-w-sm">
<div v-if="error" class="mb-4 text-red-500 text-center">
Неверный логин или пароль
</div>

<div class="w-full mb-6">
<div class="mb-4">
<input
v-model="state.login"
name="login"
placeholder="Логин"
required
value=""
class="peer block w-full rounded-2xl border border-gray-200 py-3 px-4 text-base outline-2 outline-offset-1 outline-gray-500 placeholder:text-gray-400"
>
</div>

<div class="mb-4">
<input
v-model="state.password"
name="password"
type="password"
placeholder="Пароль"
required
value=""
class="peer block w-full rounded-2xl border border-gray-200 py-3 px-4 text-base outline-2 outline-offset-1 outline-gray-500 placeholder:text-gray-400"
>
</div>
Expand All @@ -40,13 +44,14 @@
<div class="flex flex-row gap-4 justify-center">
<button
type="submit"
:disabled="false"
:disabled="status === 'pending'"
class="px-5 py-3 flex flex-row gap-2 justify-center items-center text-base font-medium cursor-pointer bg-gray-100 hover:bg-gray-200 hover:scale-95 duration-200 rounded-2xl disabled:animate-pulse"
@click="sighIn"
>
Войти <Icon :name="icons.arrowRight" size="22" />
</button>
</div>
</form>
</div>
</div>
</div>
</template>
Expand All @@ -57,4 +62,26 @@ definePageMeta({
})

const { icons } = useAppConfig()
const { user, fetch: refreshSession } = useUserSession()
if (user.value?.isStaff) {
await navigateTo('/command-center')
}

const state = reactive({
login: '',
password: '',
})

const { error, status, execute: sighIn } = await useFetch('/api/auth/sign-in', {
method: 'POST',
body: state,
immediate: false,
watch: false,
onResponse: async ({ response }) => {
if (response.ok) {
await refreshSession()
await navigateTo('/command-center')
}
},
})
</script>
2 changes: 1 addition & 1 deletion apps/food/server/api/auth/sign-in.post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default defineEventHandler(async (event) => {
where: { id: credentials.userId },
})
if (!user) {
throw createError({ statusCode: 401, statusMessage: 'Wrong login or password' })
throw createError({ statusCode: 401, statusMessage: 'No user found' })
}

await setUserSession(event, {
Expand Down
Loading