changed route folder

This commit is contained in:
Mamalizz
2025-01-25 02:13:49 +03:30
parent a0a7f650ea
commit 5aea2057d2
2 changed files with 0 additions and 322 deletions
-88
View File
@@ -1,88 +0,0 @@
<script lang="ts" setup>
import useGetCategories from "~/composables/api/product/useGetCategories";
// state
const { data: categories, suspense } = useGetCategories();
const search = ref("");
const debouncedSearch = refDebounced(search, 300);
// computed
const filteredCategories = computed(() => {
if (debouncedSearch.value.length > 0) {
return categories.value!.filter(cat => cat.name.includes(debouncedSearch.value));
}
return categories.value!;
});
// lifecycle
onServerPrefetch(async () => {
const response = await suspense();
if (response.isError) {
throw createError({
statusCode: 500,
statusMessage: `Error in categories page prefetch`
});
}
});
</script>
<template>
<div class="container">
<div class="mt-20 flex gap-6 justify-between items-center">
<span class="typo-h-3 text-black">دسته بندی ها</span>
<Input
class="max-w-[400px] w-full"
variant="outlined"
placeholder="جستجو..."
v-model="search"
>
<template #endItem>
<div class="flex items-center gap-1">
<Icon class="translate-y-[-1px]" name="ci:search" size="24" />
</div>
</template>
</Input>
</div>
<Transition name="fade" mode="out-in">
<div
v-if="filteredCategories.length !== 0"
v-auto-animate
class="grid grid-cols-3 gap-4 w-full mt-12"
>
<CategoryCard
v-for="category in filteredCategories"
:key="category.id"
:id="category.id"
:category="category.name"
picture="/img/product-1.jpg"
:count="20"
description="یک دسته بندی تستasdasd"
dark-layer
/>
</div>
<div
v-else
class="flex w-full mt-12"
>
<div
class="flex-col flex-grow py-[12rem] gap-6 border-2 border-slate-200 border-dashed size-full rounded-100 flex-center"
>
<Icon name="bi:search" size="50" class="**:fill-gray-500" />
<span class="text-lg text-gray-500">
دسته بندی یافت نشد :(
</span>
</div>
</div>
</Transition>
</div>
</template>
-234
View File
@@ -1,234 +0,0 @@
<script lang="ts" setup>
// import
import { helpers, required } from "@vuelidate/validators";
import { useVuelidate } from "@vuelidate/core";
import useOtp from "~/composables/api/auth/useOtp";
import useSignIn from "~/composables/api/auth/useSignIn";
import { definePageMeta } from "#imports";
import useGetAccount from "~/composables/api/account/useGetAccount";
import { useAuth } from "~/composables/api/auth/useAuth";
import { useToast } from "~/composables/global/useToast";
import { useTimer } from "~/composables/global/useTimer";
// types
type LoginInfo = {
phone: string;
};
// meta
definePageMeta({
middleware: ["check-is-not-logged-in"]
});
// state
const { addToast } = useToast();
const { updateToken, updateRefreshToken } = useAuth();
const { refetch: refetchAccount } = useGetAccount();
const showOtp = ref(false);
const otpCode = ref([]);
const formRules = computed(() => {
return {
phone: {
required: helpers.withMessage("Phone is required", required),
phoneValidator: helpers.regex(/^[1-9][0-9]{9}$/)
}
};
});
const loginInfo = ref<LoginInfo>({
phone: ""
});
const formValidator$ = useVuelidate(formRules, loginInfo);
const {
timer: otpBlockerTimePassed,
start: startOtpBlocker,
reset: resetOtpBlocker,
isPending: isResendOtpBlocked
} = useTimer({
duration: 5000
});
const { mutateAsync: sendOtp, isPending: sendOtpIsPending } = useOtp();
const { mutateAsync: signIn, isPending: signInIsPending, status: signInStatus } = useSignIn();
// computed
const sendOtpHandler = async () => {
if (!sendOtpIsPending.value) {
try {
await sendOtp({
phone: `0${loginInfo.value.phone}`
});
addToast({
message: "کد برای شما ارسال شد",
options: {
status: "success"
}
});
showOtp.value = true;
} catch (e) {
addToast({
message: "مشکلی پیش آمده",
options: {
status: "error"
}
});
}
}
};
const handleLogin = async () => {
if (!showOtp.value) {
await formValidator$.value.$validate();
if (!formValidator$.value.$errors.length) {
await sendOtpHandler();
}
} else {
try {
const response = await signIn({
otp: otpCode.value.join(""),
phone: `0${loginInfo.value.phone}`
});
updateToken(response.access);
updateRefreshToken(response.refresh);
await new Promise(resolve => setTimeout(resolve, 1000));
await refetchAccount();
addToast({
message: "با موفقیت وارد شدید",
options: {
status: "success"
}
});
navigateTo("/");
} catch (e) {
otpCode.value = [];
addToast({ message: "مشکلی پیش آمده" });
}
}
};
const resendOtp = async () => {
try {
await sendOtpHandler();
resetOtpBlocker();
startOtpBlocker();
} catch (e) {
resetOtpBlocker();
}
};
const resetForm = () => {
loginInfo.value.phone = "";
formValidator$.value.$reset();
otpCode.value = [];
showOtp.value = false;
};
</script>
<template>
<div class="container min-h-[700px] flex flex-col items-center justify-center">
<h1 class="typo-hero-2">
فرم ورود
</h1>
<form
@submit.prevent
class="max-w-[500px] w-full mt-12"
>
<div
v-if="!showOtp"
class="flex items-center gap-2 w-full"
>
<Input
class="w-full"
v-model="loginInfo.phone"
placeholder="9380123456"
dir="ltr"
:error="formValidator$.phone.$error"
>
<template #startItem>
<span class="text-slate-500">
+98
</span>
</template>
</Input>
<div class="flex items-center gap-1">
<Icon class="translate-y-[-1px]" name="twemoji:flag-iran" size="24" />
</div>
</div>
<OtpInput
v-else
v-model="otpCode"
:status="signInStatus === 'success' ? 'success' : signInStatus === 'error' ? 'error' : 'idle'"
:disabled="signInIsPending || sendOtpIsPending"
:autofocus="true"
@complete="handleLogin"
/>
<Button
v-if="!showOtp"
class="rounded-full w-full mt-4"
type="submit"
@click="handleLogin"
:loading="sendOtpIsPending"
:disabled="sendOtpIsPending"
>
ارسال کد
</Button>
<div
v-else
class="flex items-center w-full gap-4 mt-4"
>
<Button
class="rounded-full w-full mt-4"
type="button"
variant="secondary"
@click="resetForm"
:disabled="signInIsPending || sendOtpIsPending"
>
تغییر شماره
</Button>
<Button
class="rounded-full w-full mt-4"
type="submit"
@click="resendOtp"
:loading="signInIsPending || sendOtpIsPending"
:disabled="signInIsPending || isResendOtpBlocked || sendOtpIsPending"
>
ارسال مجدد کد
{{ isResendOtpBlocked ? otpBlockerTimePassed : "" }}
</Button>
</div>
<div class="flex items-center gap-2 justify-center mt-6">
<span>
بازگشت به فروشگاه
</span>
<Icon
name="ci:left-rotation"
size="24"
/>
</div>
</form>
</div>
</template>