Skip to content

Commit

Permalink
feat: add confirm and workspace auth pages, fix: fsd features structure
Browse files Browse the repository at this point in the history
  • Loading branch information
mnenie committed Dec 21, 2024
1 parent 0f035bb commit 388156d
Show file tree
Hide file tree
Showing 42 changed files with 434 additions and 104 deletions.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<script setup lang="ts">
import { useDark, useWindowSize } from '@vueuse/core'
import { computed } from 'vue'
import { reviews } from '../model'
import useTextChanging from '../model/composables/useTextChanging'
import { reviews } from '../model/fixtures'
const { currentIndex } = useTextChanging(reviews)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,47 @@
<script setup lang="ts">
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRoute } from 'vue-router'
const { tm, locale } = useI18n()
const route = useRoute()
// @ts-expect-error tm types
const privacyItems = tm('authentication.privacy')
const maxWidth = computed(() => {
return locale.value === 'ru-RU' ? '400px' : '320px'
})
const privacyChangingItem = computed(() =>
route.path === '/auth/sign-in' ? privacyItems[1] : privacyItems[0],
)
</script>

<template>
<p
class="pt-2.5 text-sm text-center text-neutral-500 my-0 mx-auto select-none dark:text-neutral-400"
:style="{ maxWidth }"
>
{{ privacyItems[0] }}
{{ privacyChangingItem }}
<a
href="https://github.com/mnenie/jenda"
target="_blank"
rel="noopener noreferrer"
class="cursor-pointer underline underline-offset-4 duration-100 ease-in
hover:text-neutral-900 dark:hover:text-neutral-500"
>
{{ privacyItems[1] }}
{{ privacyItems[2] }}
</a>
{{ privacyItems[2] }}
{{ privacyItems[3] }}
<a
href="https://github.com/mnenie/jenda"
target="_blank"
rel="noopener noreferrer"
class="cursor-pointer underline underline-offset-4 duration-100 ease-in
hover:text-neutral-900 dark:hover:text-neutral-500"
>
{{ privacyItems[3] }}
{{ privacyItems[4] }}
</a>
</p>
</template>
5 changes: 5 additions & 0 deletions core/client/src/features/auth/common/ui/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import BgPanel from './BgPanel.vue'
import LogoFile from './LogoFile.vue'
import PrivacyPolicy from './PrivacyPolicy.vue'

export { BgPanel, LogoFile, PrivacyPolicy }
2 changes: 0 additions & 2 deletions core/client/src/features/auth/model/index.ts

This file was deleted.

12 changes: 0 additions & 12 deletions core/client/src/features/auth/model/validation.ts

This file was deleted.

1 change: 1 addition & 0 deletions core/client/src/features/auth/oauth/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './ui'
1 change: 1 addition & 0 deletions core/client/src/features/auth/oauth/ui/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as GoogleOauth } from './GoogleOauth.vue'
1 change: 1 addition & 0 deletions core/client/src/features/auth/sign-in/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './ui'
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,20 @@ import { UiButton, UiInput } from '@/shared/ui'
import { toTypedSchema } from '@vee-validate/zod'
import { useField, useForm } from 'vee-validate'
import { toast } from 'vue-sonner'
import { validationRules } from '../model'
import { z } from 'zod'
const validationSchema = toTypedSchema(validationRules)
const validationSchema = toTypedSchema(
z.object({
email: z
.string({ required_error: 'Email is a required field' })
.nonempty('Email is a required field')
.email('Email must be a valid'),
password: z
.string({ required_error: 'Password is a required field' })
.nonempty('Password is a required field')
.min(8, 'Password must be at least 8 characters'),
}),
)
const { handleSubmit, errors } = useForm({
validationSchema,
Expand Down Expand Up @@ -55,7 +66,7 @@ const onLogin = handleSubmit((values) => {
</div>
</div>
<div class="grid gap-2">
<UiButton>
<UiButton type="submit">
{{ $t('authentication.login.btn') }}
</UiButton>
<p class="text-sm text-center select-none text-neutral-500 dark:text-neutral-300">
Expand Down
3 changes: 3 additions & 0 deletions core/client/src/features/auth/sign-in/ui/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import SignInForm from './SignInForm.vue'

export { SignInForm }
1 change: 1 addition & 0 deletions core/client/src/features/auth/sign-up/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './ui'
80 changes: 80 additions & 0 deletions core/client/src/features/auth/sign-up/ui/ConfirmForm.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<script setup lang="ts">
import { UiButton, UiPinInput, UiPinInputGroup, UiPinInputInput } from '@/shared/ui'
import { toTypedSchema } from '@vee-validate/zod'
import { useField, useForm } from 'vee-validate'
import { useRouter } from 'vue-router'
import { toast } from 'vue-sonner'
import { z } from 'zod'
const formSchema = toTypedSchema(z.object({
pin: z.array(z.coerce.string()).length(5, { message: 'Invalid pin' }),
}))
const { handleSubmit, setFieldValue, errors } = useForm({
validationSchema: formSchema,
initialValues: {
pin: [],
},
})
const { value: pin } = useField<string[]>('pin')
const router = useRouter()
const onConfirm = handleSubmit((values) => {
router.push('/auth/sign-up/workspace')
})
function onResend() {
toast.success('OTP has been sent to your email')
}
</script>

<template>
<form @submit.prevent="onConfirm">
<div v-auto-animate class="form-field">
<UiPinInput
id="pin-input"
v-model:model-value="pin"
placeholder=""
class="flex gap-2 items-center mt-1 w-full"
otp
type="number"
@update:model-value="(arrStr) => {
setFieldValue('pin', arrStr.filter(Boolean))
}"
>
<UiPinInputGroup>
<UiPinInputInput
v-for="(id, index) in 5"
:key="id"
:index="index"
/>
</UiPinInputGroup>
</UiPinInput>
<span
v-if="errors.pin"
class="text-xs text-red-500 !fw500"
>
{{ errors.pin }}
</span>
</div>
<p class="text-sm text-neutral-400 mt-2">
{{ $t('authentication.form.otp') }}
</p>
<UiButton type="submit" class="w-full mt-4 mb-2">
{{ $t('authentication.confirm.btn') }}
</UiButton>
<p
class="text-sm text-center select-none text-neutral-500 dark:text-neutral-300"
@click="onResend"
>
{{ $t('authentication.confirm.proposal') }}
<span
class="cursor-pointer underline underline-offset-4 duration-100 ease-in hover:text-neutral-900 dark:hover:text-neutral-400"
>
{{ $t('authentication.confirm.route') }}
</span>
</p>
</form>
</template>
18 changes: 18 additions & 0 deletions core/client/src/features/auth/sign-up/ui/HandleLogo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<script setup lang="ts">
import { authWorkspaceKey } from '@/shared/constants'
import { UiButton } from '@/shared/ui'
import { inject } from 'vue'
const { openFileChooser, reset } = inject(authWorkspaceKey)!
</script>

<template>
<div class="flex items-center gap-2">
<UiButton size="sm" variant="outline" @click="openFileChooser($event)">
{{ $t('authentication.workspace.logo.btn', 1) }}
</UiButton>
<UiButton size="sm" variant="outline" class="!text-red-500" @click="reset">
{{ $t('authentication.workspace.logo.btn', 2) }}
</UiButton>
</div>
</template>
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,20 @@ import { UiButton, UiInput } from '@/shared/ui'
import { toTypedSchema } from '@vee-validate/zod'
import { useField, useForm } from 'vee-validate'
import { useRouter } from 'vue-router'
import { validationRules } from '../model'
import { z } from 'zod'
const validationSchema = toTypedSchema(validationRules)
const validationSchema = toTypedSchema(
z.object({
email: z
.string({ required_error: 'Email is a required field' })
.nonempty('Email is a required field')
.email('Email must be a valid'),
password: z
.string({ required_error: 'Password is a required field' })
.nonempty('Password is a required field')
.min(8, 'Password must be at least 8 characters'),
}),
)
const { handleSubmit, errors } = useForm({
validationSchema,
Expand Down Expand Up @@ -57,7 +68,7 @@ const onRegistration = handleSubmit((values) => {
</div>
</div>
<div class="grid gap-2">
<UiButton>
<UiButton type="submit">
{{ $t('authentication.registration.btn') }}
</UiButton>
<p class="text-sm text-center select-none text-neutral-500 dark:text-neutral-300">
Expand Down
81 changes: 81 additions & 0 deletions core/client/src/features/auth/sign-up/ui/WorkspaceForm.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<script setup lang="ts">
import { UiButton, UiInput } from '@/shared/ui'
import { toTypedSchema } from '@vee-validate/zod'
import { useField, useForm } from 'vee-validate'
import { useRouter } from 'vue-router'
import { z } from 'zod'
const validationSchema = toTypedSchema(
z.object({
name: z
.string({ required_error: 'Name is a required field' })
.nonempty('Name is a required field'),
link: z
.string({ required_error: 'Link is a required field' })
.nonempty('Link is a required field')
.min(3, 'Link must be at least 3 characters'),
}),
)
const { handleSubmit, errors } = useForm({
validationSchema,
})
const { value: name } = useField<string>('name')
const { value: link } = useField<string>('link')
const router = useRouter()
const onWorkspaceCreation = handleSubmit((values) => {
// on registration event
router.push('/boards')
})
</script>

<template>
<form @submit.prevent="onWorkspaceCreation">
<div class="grid gap-6">
<div class="grid gap-4">
<div v-auto-animate class="form-field">
<label
class="form-label"
for="name"
>
{{ $t('authentication.workspace.form.name.label') }}
</label>
<UiInput
id="name"
v-model="name"
:placeholder="$t('authentication.workspace.form.name.placeholder')"
/>
<span
v-if="errors.name"
class="text-xs text-red-500 !fw500"
>
{{ errors.name }}
</span>
</div>
<div v-auto-animate class="form-field">
<label
class="form-label"
for="link"
>
{{ $t('authentication.workspace.form.link.label') }}
</label>
<div class="relative w-full h-9 flex items-center">
<span class="text-sm pb-0.5px text-neutral-500 absolute left-3">workpaces/</span>
<UiInput id="link" v-model="link" class="pl-89px" type="text" />
</div>
<span
v-if="errors.link"
class="text-xs text-red-500 !fw500"
>
{{ errors.link }}
</span>
</div>
</div>
<UiButton type="submit">
{{ $t('authentication.workspace.route') }}
</UiButton>
</div>
</form>
</template>
6 changes: 6 additions & 0 deletions core/client/src/features/auth/sign-up/ui/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import ConfirmForm from './ConfirmForm.vue'
import HandleLogo from './HandleLogo.vue'
import SignUpForm from './SignUpForm.vue'
import WorkspaceForm from './WorkspaceForm.vue'

export { ConfirmForm, HandleLogo, SignUpForm, WorkspaceForm }
37 changes: 0 additions & 37 deletions core/client/src/features/auth/ui/ConfirmForm.vue

This file was deleted.

9 changes: 0 additions & 9 deletions core/client/src/features/auth/ui/index.ts

This file was deleted.

Loading

0 comments on commit 388156d

Please sign in to comment.