fix problem
This commit is contained in:
@@ -6,8 +6,8 @@ import PlusIcon from "@/components/icons/PlusIcon";
|
|||||||
import { toast, toastLoginRequired } from "@/components/Toast";
|
import { toast, toastLoginRequired } from "@/components/Toast";
|
||||||
import { getToken } from "@/lib/api/func";
|
import { getToken } from "@/lib/api/func";
|
||||||
import { ef } from "@/lib/helpers/utfNumbers";
|
import { ef } from "@/lib/helpers/utfNumbers";
|
||||||
import clsx from "clsx";
|
|
||||||
import { glassSurface, glassSurfaceCard, glassSurfaceFlat } from "@/lib/styles/glassSurface";
|
import { glassSurface, glassSurfaceCard, glassSurfaceFlat } from "@/lib/styles/glassSurface";
|
||||||
|
import clsx from "clsx";
|
||||||
import { motion } from "framer-motion";
|
import { motion } from "framer-motion";
|
||||||
import { ArrowLeft, Clock, Cup, Heart, TruckTick } from "iconsax-react";
|
import { ArrowLeft, Clock, Cup, Heart, TruckTick } from "iconsax-react";
|
||||||
import { useParams, useRouter } from "next/navigation";
|
import { useParams, useRouter } from "next/navigation";
|
||||||
@@ -106,18 +106,14 @@ function FoodPage({}: Props) {
|
|||||||
: Array.isArray(foodData.images) && foodData.images.length > 0
|
: Array.isArray(foodData.images) && foodData.images.length > 0
|
||||||
? typeof foodData.images[0] === "string"
|
? typeof foodData.images[0] === "string"
|
||||||
? foodData.images[0]
|
? foodData.images[0]
|
||||||
: typeof foodData.images[0] === "object" &&
|
: typeof foodData.images[0] === "object" && foodData.images[0] !== null && "url" in foodData.images[0]
|
||||||
foodData.images[0] !== null &&
|
|
||||||
"url" in foodData.images[0]
|
|
||||||
? (foodData.images[0] as { url: string }).url
|
? (foodData.images[0] as { url: string }).url
|
||||||
: "/assets/images/no-image.png"
|
: "/assets/images/no-image.png"
|
||||||
: "/assets/images/no-image.png";
|
: "/assets/images/no-image.png";
|
||||||
const categoryName = foodData.category?.title;
|
const categoryName = foodData.category?.title;
|
||||||
const prepareTime = foodData.prepareTime || 0;
|
const prepareTime = foodData.prepareTime || 0;
|
||||||
const price = foodData.price || 0;
|
const price = foodData.price || 0;
|
||||||
const content = Array.isArray(foodData.content)
|
const content = Array.isArray(foodData.content) ? foodData.content.join("، ") : foodData.content || foodData.desc || "";
|
||||||
? foodData.content.join("، ")
|
|
||||||
: foodData.content || foodData.desc || "";
|
|
||||||
|
|
||||||
const handleBackToMenu = () => {
|
const handleBackToMenu = () => {
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
@@ -136,7 +132,9 @@ function FoodPage({}: Props) {
|
|||||||
!isAvailable && "opacity-50",
|
!isAvailable && "opacity-50",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className={glassSurface('relative w-full lg:h-full min-h-0 rounded-2xl overflow-hidden lg:rounded-r-none lg:order-1 lg:!bg-transparent lg:!border-0 lg:!shadow-none lg:[backdrop-filter:none]')}>
|
<div
|
||||||
|
className={glassSurface("relative w-full lg:h-full min-h-0 rounded-2xl overflow-hidden lg:rounded-r-none lg:order-1 lg:bg-transparent! lg:border-0! lg:shadow-none! lg:[backdrop-filter:none]")}
|
||||||
|
>
|
||||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||||
<img
|
<img
|
||||||
className="lg:object-cover lg:h-full object-cover bg-[#F2F2F9] w-full"
|
className="lg:object-cover lg:h-full object-cover bg-[#F2F2F9] w-full"
|
||||||
@@ -147,34 +145,20 @@ function FoodPage({}: Props) {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<div className="absolute top-4 left-0 pe-5.5 ps-7 w-full inline-flex justify-between items-center">
|
<div className="absolute top-4 left-0 pe-5.5 ps-7 w-full inline-flex justify-between items-center">
|
||||||
<div className={glassSurfaceFlat('whitespace-nowrap rounded-[34px] py-1.5 px-4 w-min text-xs text-disabled2 dark:text-disabled-text font-bold')}>
|
<div className={glassSurfaceFlat("whitespace-nowrap rounded-[34px] py-1.5 px-4 w-min text-xs text-disabled2 dark:text-disabled-text font-bold")}>{categoryName || "-"}</div>
|
||||||
{categoryName || "-"}
|
<button onClick={handleBackToMenu} className={glassSurfaceFlat("p-2 rounded-full")}>
|
||||||
</div>
|
<ArrowLeft size={18} className="stroke-primary dark:stroke-foreground" />
|
||||||
<button
|
|
||||||
onClick={handleBackToMenu}
|
|
||||||
className={glassSurfaceFlat('p-2 rounded-full')}
|
|
||||||
>
|
|
||||||
<ArrowLeft
|
|
||||||
size={18}
|
|
||||||
className="stroke-primary dark:stroke-foreground"
|
|
||||||
/>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={glassSurfaceCard('relative px-6 pt-6 pb-7.5 lg:flex lg:flex-col lg:h-full lg:min-h-0 w-full overflow-hidden not-lg:-translate-y-6 lg:rounded-l-none lg:overflow-y-auto rounded-3xl')}>
|
<div
|
||||||
|
className={glassSurfaceCard("relative px-6 pt-6 pb-7.5 lg:flex lg:flex-col lg:h-full lg:min-h-0 w-full overflow-hidden not-lg:-translate-y-6 lg:rounded-l-none lg:overflow-y-auto rounded-3xl")}
|
||||||
|
>
|
||||||
<div className="w-full inline-flex justify-between items-center shrink-0">
|
<div className="w-full inline-flex justify-between items-center shrink-0">
|
||||||
<h5 className="text-base font-bold">{foodName}</h5>
|
<h5 className="text-base font-bold">{foodName}</h5>
|
||||||
<button
|
<button onClick={handleToggleFavorite} className="p-2 bg-[#EAECF0] dark:bg-neutral-600 rounded-lg">
|
||||||
onClick={handleToggleFavorite}
|
<Heart variant={isFavorite ? "Bold" : "Outline"} size={24} color="currentColor" className={isFavorite ? "fill-primary dark:fill-foreground" : ""} />
|
||||||
className="p-2 bg-[#EAECF0] dark:bg-neutral-600 rounded-lg"
|
|
||||||
>
|
|
||||||
<Heart
|
|
||||||
variant={isFavorite ? "Bold" : "Outline"}
|
|
||||||
size={24}
|
|
||||||
color="currentColor"
|
|
||||||
className={isFavorite ? "fill-primary dark:fill-foreground" : ""}
|
|
||||||
/>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -182,10 +166,7 @@ function FoodPage({}: Props) {
|
|||||||
<div className="text-xs">
|
<div className="text-xs">
|
||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-1">
|
||||||
<Clock size={14} className="stroke-disabled-text" />
|
<Clock size={14} className="stroke-disabled-text" />
|
||||||
<span className="text-disabled-text">
|
<span className="text-disabled-text">زمان پخت و آماده سازی: {prepareTime > 0 ? `${ef(String(prepareTime))} دقیقه` : "-"}</span>
|
||||||
زمان پخت و آماده سازی:{" "}
|
|
||||||
{prepareTime > 0 ? `${ef(String(prepareTime))} دقیقه` : "-"}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2 mt-2">
|
<div className="flex items-center gap-2 mt-2">
|
||||||
<Cup size={14} className="stroke-disabled-text" />
|
<Cup size={14} className="stroke-disabled-text" />
|
||||||
@@ -195,18 +176,9 @@ function FoodPage({}: Props) {
|
|||||||
<div>۰</div>
|
<div>۰</div>
|
||||||
<span>امتیاز برای هر بار خرید</span>
|
<span>امتیاز برای هر بار خرید</span>
|
||||||
</>
|
</>
|
||||||
) : about?.data?.score?.purchaseScore &&
|
) : about?.data?.score?.purchaseScore && about?.data?.score?.purchaseAmount ? (
|
||||||
about?.data?.score?.purchaseAmount ? (
|
|
||||||
<>
|
<>
|
||||||
<div>
|
<div>{ef(Math.round(foodData?.price * (Number(about.data.score.purchaseScore) / Number(about.data.score.purchaseAmount))).toLocaleString("en-US"))}</div>
|
||||||
{ef(
|
|
||||||
Math.round(
|
|
||||||
foodData?.price *
|
|
||||||
(Number(about.data.score.purchaseScore) /
|
|
||||||
Number(about.data.score.purchaseAmount)),
|
|
||||||
).toLocaleString("en-US"),
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<span>امتیاز برای هر بار خرید</span>
|
<span>امتیاز برای هر بار خرید</span>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
@@ -216,9 +188,7 @@ function FoodPage({}: Props) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2 mt-2">
|
<div className="flex items-center gap-2 mt-2">
|
||||||
<TruckTick size={14} className="stroke-disabled-text" />
|
<TruckTick size={14} className="stroke-disabled-text" />
|
||||||
<span className="text-disabled-text">
|
<span className="text-disabled-text">{foodData.pickupServe ? "ارسال با پیک" : "-"}</span>
|
||||||
{foodData.pickupServe ? "ارسال با پیک" : "-"}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -235,38 +205,23 @@ function FoodPage({}: Props) {
|
|||||||
className="bg-background pattern-secondary-bg active:drop-shadow-xs max-w-[115px] rounded-md w-full h-8 inline-flex p-1 justify-between items-center gap-2 relative overflow-hidden"
|
className="bg-background pattern-secondary-bg active:drop-shadow-xs max-w-[115px] rounded-md w-full h-8 inline-flex p-1 justify-between items-center gap-2 relative overflow-hidden"
|
||||||
>
|
>
|
||||||
{quantity <= 0 ? (
|
{quantity <= 0 ? (
|
||||||
<button
|
<button onClick={handleAddToCart} disabled={!isAvailable} className="inline-flex w-full justify-center items-center gap-2 disabled:pointer-events-none disabled:opacity-40">
|
||||||
onClick={handleAddToCart}
|
|
||||||
disabled={!isAvailable}
|
|
||||||
className="inline-flex w-full justify-center items-center gap-2 disabled:pointer-events-none disabled:opacity-40"
|
|
||||||
>
|
|
||||||
<PlusIcon />
|
<PlusIcon />
|
||||||
<div className="text-sm2 pt-0.5 font-normal text-foreground">
|
<div className="text-sm2 pt-0.5 font-normal text-foreground">افزودن</div>
|
||||||
افزودن
|
|
||||||
</div>
|
|
||||||
</button>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<button
|
<button
|
||||||
onClick={handleAddToCart}
|
onClick={handleAddToCart}
|
||||||
disabled={!isAvailable}
|
disabled={!isAvailable}
|
||||||
className={glassSurfaceFlat('hover:brightness-95 active:brightness-90 rounded-sm p-2 transition-all disabled:opacity-40 disabled:pointer-events-none')}
|
className={glassSurfaceFlat("hover:brightness-95 active:brightness-90 rounded-sm p-2 transition-all disabled:opacity-40 disabled:pointer-events-none")}
|
||||||
>
|
>
|
||||||
<PlusIcon className="text-foreground" />
|
<PlusIcon className="text-foreground" />
|
||||||
</button>
|
</button>
|
||||||
<motion.div
|
<motion.div key={quantity} initial={{ scale: 1 }} animate={{ scale: [1.2, 0.95, 1] }} transition={{ duration: 0.3 }} className="text-sm2 pt-0.5 font-semibold">
|
||||||
key={quantity}
|
|
||||||
initial={{ scale: 1 }}
|
|
||||||
animate={{ scale: [1.2, 0.95, 1] }}
|
|
||||||
transition={{ duration: 0.3 }}
|
|
||||||
className="text-sm2 pt-0.5 font-semibold"
|
|
||||||
>
|
|
||||||
{quantity}
|
{quantity}
|
||||||
</motion.div>
|
</motion.div>
|
||||||
<button
|
<button onClick={handleRemoveFromCart} className={glassSurfaceFlat("hover:brightness-95 active:brightness-90 rounded-sm p-2 transition-all")}>
|
||||||
onClick={handleRemoveFromCart}
|
|
||||||
className={glassSurfaceFlat('hover:brightness-95 active:brightness-90 rounded-sm p-2 transition-all')}
|
|
||||||
>
|
|
||||||
<MinusIcon className="text-foreground" />
|
<MinusIcon className="text-foreground" />
|
||||||
</button>
|
</button>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,260 +1,198 @@
|
|||||||
'use client';
|
"use client";
|
||||||
|
|
||||||
import Button from '@/components/button/PrimaryButton';
|
import Button from "@/components/button/PrimaryButton";
|
||||||
import PasswordField from '@/components/input/PasswordField';
|
import PasswordField from "@/components/input/PasswordField";
|
||||||
import TabContainer from '@/components/tab/TabContainer'
|
import { Switch } from "@/components/ui/switch";
|
||||||
import { TabHeader } from '@/components/tab/TabHeader'
|
import Accordion from "@/components/utils/Accordion";
|
||||||
import { Switch } from '@/components/ui/switch';
|
import Seperator from "@/components/utils/Seperator";
|
||||||
import Accordion from '@/components/utils/Accordion';
|
import { SmartIcon } from "@/components/utils/SmartIcon";
|
||||||
import Seperator from '@/components/utils/Seperator';
|
import { getI18nObject } from "@/lib/i18n";
|
||||||
import { SmartIcon } from '@/components/utils/SmartIcon';
|
import { glassSurfaceCard } from "@/lib/styles/glassSurface";
|
||||||
import { getI18nObject } from '@/lib/i18n';
|
import { SettingsData } from "@/types/i18n/settings";
|
||||||
import { SettingsData } from '@/types/i18n/settings';
|
import { ArrowLeft, Key, TickCircle } from "iconsax-react";
|
||||||
import { Key, KeySquare, Notification1, ArrowLeft, TickCircle } from 'iconsax-react'
|
import { useRouter } from "next/navigation";
|
||||||
import { useRouter } from 'next/navigation';
|
import React, { Fragment, useState } from "react";
|
||||||
import React, { Fragment, useState } from 'react'
|
import { useTranslation } from "react-i18next";
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { glassSurfaceCard } from '@/lib/styles/glassSurface';
|
|
||||||
|
|
||||||
function UserSettingsIndex() {
|
function UserSettingsIndex() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { t } = useTranslation('settings');
|
const { t } = useTranslation("settings");
|
||||||
const data: SettingsData = getI18nObject(t, "data");
|
const data: SettingsData = getI18nObject(t, "data");
|
||||||
const [statisticalParticipation, setStatisticalParticipation] = useState(true);
|
const [statisticalParticipation, setStatisticalParticipation] = useState(true);
|
||||||
|
|
||||||
const onSwitched = (e: React.MouseEvent) => {
|
const onSwitched = (e: React.MouseEvent) => {
|
||||||
const target = e.target as HTMLElement;
|
const target = e.target as HTMLElement;
|
||||||
console.log('Save changed setting?', target.id);
|
console.log("Save changed setting?", target.id);
|
||||||
}
|
};
|
||||||
|
|
||||||
const handleStatisticalToggle = (checked: boolean) => {
|
const handleStatisticalToggle = (checked: boolean) => {
|
||||||
setStatisticalParticipation(checked);
|
setStatisticalParticipation(checked);
|
||||||
console.log('Statistical participation:', checked);
|
console.log("Statistical participation:", checked);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const notifsTab = () => {
|
|
||||||
|
|
||||||
return (
|
|
||||||
<section aria-labelledby="about-title" className='py-4 flex-1 h-full'>
|
|
||||||
<section
|
|
||||||
className={glassSurfaceCard('p-4')}>
|
|
||||||
|
|
||||||
<div className="flex justify-between items-center pb-[25px]">
|
|
||||||
<h2 className='text-sm leading-5'>{data.TabNotifications.Heading}</h2>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='p-2 pt-0'>
|
|
||||||
{data.TabNotifications.Accordions.map((accordion, i) => {
|
|
||||||
return (
|
|
||||||
<Fragment key={i}>
|
|
||||||
<Accordion
|
|
||||||
title={accordion.Heading}
|
|
||||||
group={'accordions'}
|
|
||||||
icon={accordion.Icon}
|
|
||||||
>
|
|
||||||
<div className='grid gap-4 mb-3'>
|
|
||||||
{accordion.Items.map((item, j) => {
|
|
||||||
return (
|
|
||||||
<label
|
|
||||||
key={j}
|
|
||||||
htmlFor={item.HtmlName}
|
|
||||||
className="flex w-full h-11 items-center justify-between gap-2 px-3 py-4 relative bg-container/29 rounded-xl border border-solid border-neutral-200 dark:border-neutral-600 focus:outline-none focus:ring-2 focus:ring-black"
|
|
||||||
>
|
|
||||||
|
|
||||||
<span className="inline-flex items-center gap-2.5 text-sm2">
|
|
||||||
<SmartIcon icon={item.Icon} />
|
|
||||||
{item.Label}
|
|
||||||
</span>
|
|
||||||
<Switch
|
|
||||||
onClick={onSwitched}
|
|
||||||
id={item.HtmlName}
|
|
||||||
name={item.HtmlName}
|
|
||||||
className="w-12 h-6 scale-[0.9]"
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</Accordion>
|
|
||||||
<Seperator className='last:hidden' />
|
|
||||||
</Fragment>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</section>
|
|
||||||
|
|
||||||
</section>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const passwordTab = () => {
|
|
||||||
|
|
||||||
return (
|
|
||||||
<section aria-labelledby="reviews-title" className='py-4'>
|
|
||||||
<section
|
|
||||||
className={glassSurfaceCard('p-4')}>
|
|
||||||
|
|
||||||
<div className="flex justify-between items-center pb-[25px]">
|
|
||||||
<h2 className='text-sm leading-5'>{data.TabPassword.Heading}</h2>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form
|
|
||||||
onSubmit={(e) => e.preventDefault()}
|
|
||||||
className='grid gap-6 p-2'
|
|
||||||
>
|
|
||||||
{data.TabPassword.Inputs.map((input, i) => {
|
|
||||||
return (
|
|
||||||
<PasswordField
|
|
||||||
labelText={input.Label}
|
|
||||||
className='bg-container'
|
|
||||||
key={i}
|
|
||||||
htmlFor={input.HtmlName ?? ''}
|
|
||||||
placeholder={input.Placeholder}
|
|
||||||
autoComplete={input.AutoComplete}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
{data.TabPassword.Rules.map((rule, i) => {
|
|
||||||
return (
|
|
||||||
<section
|
|
||||||
key={i}
|
|
||||||
className='bg-background rounded-normal p-4 text-xs flex flex-col gap-2 font-light'
|
|
||||||
>
|
|
||||||
<h6 className='text-sm mb-2'>{rule.Heading}</h6>
|
|
||||||
{rule.Items.map((item, i) => {
|
|
||||||
return (
|
|
||||||
<li key={i}>{item}</li>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</section>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
|
|
||||||
<Button className='mt-4'>
|
|
||||||
<div className='flex items-center justify-center gap-1'>
|
|
||||||
<TickCircle className='stroke-white' size={20} />
|
|
||||||
<span className='mt-0.5'>
|
|
||||||
{data.TabPassword.ButtonSubmit}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</Button>
|
|
||||||
</form>
|
|
||||||
</section>
|
|
||||||
</section>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const authenticatorTab = () => {
|
|
||||||
|
|
||||||
return (
|
|
||||||
<section aria-labelledby="reviews-title" className='py-4'>
|
|
||||||
<div
|
|
||||||
className={glassSurfaceCard('p-4')}>
|
|
||||||
|
|
||||||
<div className="pb-4">
|
|
||||||
<h2 className='text-sm leading-5'>{data.TabAuthenticator.Heading}</h2>
|
|
||||||
<p className='text-xs mt-3 text-disabled-text font-light'>{data.TabAuthenticator.Description}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Seperator />
|
|
||||||
|
|
||||||
<div className='p-2'>
|
|
||||||
<div className='mt-14 bg-blue-100 p-4 place-self-center rounded-full'>
|
|
||||||
<Key size={32} className='stroke-blue-500' />
|
|
||||||
</div>
|
|
||||||
<p className='text-sm2 mt-4 font-light place-self-center'>
|
|
||||||
{data.TabAuthenticator.Tip}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div className='place-self-center mt-2'>
|
|
||||||
<Button className='mt-4 px-14 py-2'>
|
|
||||||
<div className='flex items-center justify-center gap-1'>
|
|
||||||
<TickCircle className='stroke-white' size={20} />
|
|
||||||
<span className='mt-0.5'>
|
|
||||||
{data.TabAuthenticator.ButtonSubmit}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{data.TabAuthenticator.Guides.map((guide, i) => {
|
|
||||||
return (
|
|
||||||
<section
|
|
||||||
key={i}
|
|
||||||
className='bg-background rounded-normal mt-14 p-4 text-xs flex flex-col gap-2 font-light'
|
|
||||||
>
|
|
||||||
<h6 className='text-sm'>{guide.Heading}</h6>
|
|
||||||
<p className='text-disabled-text'>{guide.Description}</p>
|
|
||||||
{guide.Items.map((item, i) => {
|
|
||||||
return (
|
|
||||||
<div key={i}>
|
|
||||||
<div className='ml-2 mt-2 bg-blue-100 inline-block size-6 text-center pt-[5px] pr-[1px] text-blue-500 rounded-full'>
|
|
||||||
{item.Mark}
|
|
||||||
</div>
|
|
||||||
<span>
|
|
||||||
{item.Label}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
|
|
||||||
{guide.Notes.map((note, i) => {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
key={i}
|
|
||||||
className='mt-4 p-3 text-yellow-800 rounded-lg bg-yellow-50 border border-solid border-yellow-200'
|
|
||||||
>
|
|
||||||
{note}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</section>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const notifsTab = () => {
|
||||||
return (
|
return (
|
||||||
<div className='overflow-y-auto h-full noscrollbar flex flex-col gap-6'>
|
<section aria-labelledby="about-title" className="py-4 flex-1 h-full">
|
||||||
<div className='grid grid-cols-3 items-center'>
|
<section className={glassSurfaceCard("p-4")}>
|
||||||
<span></span>
|
<div className="flex justify-between items-center pb-[25px]">
|
||||||
<h1 className='text-sm2 place-self-center font-medium'>{data.Heading}</h1>
|
<h2 className="text-sm leading-5">{data.TabNotifications.Heading}</h2>
|
||||||
<ArrowLeft
|
</div>
|
||||||
className='cursor-pointer place-self-end'
|
|
||||||
size='24'
|
<div className="p-2 pt-0">
|
||||||
color='currentColor'
|
{data.TabNotifications.Accordions.map((accordion, i) => {
|
||||||
onClick={() => { router.back() }}
|
return (
|
||||||
/>
|
<Fragment key={i}>
|
||||||
|
<Accordion title={accordion.Heading} group={"accordions"} icon={accordion.Icon}>
|
||||||
|
<div className="grid gap-4 mb-3">
|
||||||
|
{accordion.Items.map((item, j) => {
|
||||||
|
return (
|
||||||
|
<label
|
||||||
|
key={j}
|
||||||
|
htmlFor={item.HtmlName}
|
||||||
|
className="flex w-full h-11 items-center justify-between gap-2 px-3 py-4 relative bg-container/29 rounded-xl border border-solid border-neutral-200 dark:border-neutral-600 focus:outline-none focus:ring-2 focus:ring-black"
|
||||||
|
>
|
||||||
|
<span className="inline-flex items-center gap-2.5 text-sm2">
|
||||||
|
<SmartIcon icon={item.Icon} />
|
||||||
|
{item.Label}
|
||||||
|
</span>
|
||||||
|
<Switch onClick={onSwitched} id={item.HtmlName} name={item.HtmlName} className="w-12 h-6 scale-[0.9]" />
|
||||||
|
</label>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</Accordion>
|
||||||
|
<Seperator className="last:hidden" />
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const passwordTab = () => {
|
||||||
|
return (
|
||||||
|
<section aria-labelledby="reviews-title" className="py-4">
|
||||||
|
<section className={glassSurfaceCard("p-4")}>
|
||||||
|
<div className="flex justify-between items-center pb-[25px]">
|
||||||
|
<h2 className="text-sm leading-5">{data.TabPassword.Heading}</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form onSubmit={(e) => e.preventDefault()} className="grid gap-6 p-2">
|
||||||
|
{data.TabPassword.Inputs.map((input, i) => {
|
||||||
|
return <PasswordField labelText={input.Label} className="bg-container" key={i} htmlFor={input.HtmlName ?? ""} placeholder={input.Placeholder} autoComplete={input.AutoComplete} />;
|
||||||
|
})}
|
||||||
|
|
||||||
|
{data.TabPassword.Rules.map((rule, i) => {
|
||||||
|
return (
|
||||||
|
<section key={i} className="bg-background rounded-normal p-4 text-xs flex flex-col gap-2 font-light">
|
||||||
|
<h6 className="text-sm mb-2">{rule.Heading}</h6>
|
||||||
|
{rule.Items.map((item, i) => {
|
||||||
|
return <li key={i}>{item}</li>;
|
||||||
|
})}
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
|
||||||
|
<Button className="mt-4">
|
||||||
|
<div className="flex items-center justify-center gap-1">
|
||||||
|
<TickCircle className="stroke-white" size={20} />
|
||||||
|
<span className="mt-0.5">{data.TabPassword.ButtonSubmit}</span>
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const authenticatorTab = () => {
|
||||||
|
return (
|
||||||
|
<section aria-labelledby="reviews-title" className="py-4">
|
||||||
|
<div className={glassSurfaceCard("p-4")}>
|
||||||
|
<div className="pb-4">
|
||||||
|
<h2 className="text-sm leading-5">{data.TabAuthenticator.Heading}</h2>
|
||||||
|
<p className="text-xs mt-3 text-disabled-text font-light">{data.TabAuthenticator.Description}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Seperator />
|
||||||
|
|
||||||
|
<div className="p-2">
|
||||||
|
<div className="mt-14 bg-blue-100 p-4 place-self-center rounded-full">
|
||||||
|
<Key size={32} className="stroke-blue-500" />
|
||||||
|
</div>
|
||||||
|
<p className="text-sm2 mt-4 font-light place-self-center">{data.TabAuthenticator.Tip}</p>
|
||||||
|
|
||||||
|
<div className="place-self-center mt-2">
|
||||||
|
<Button className="mt-4 px-14 py-2">
|
||||||
|
<div className="flex items-center justify-center gap-1">
|
||||||
|
<TickCircle className="stroke-white" size={20} />
|
||||||
|
<span className="mt-0.5">{data.TabAuthenticator.ButtonSubmit}</span>
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<section className={glassSurfaceCard('p-4')}>
|
{data.TabAuthenticator.Guides.map((guide, i) => {
|
||||||
<div className='flex justify-between items-center pb-4'>
|
return (
|
||||||
<h2 className='text-sm leading-5'>{data.StatisticalParticipation.Heading}</h2>
|
<section key={i} className="bg-background rounded-normal mt-14 p-4 text-xs flex flex-col gap-2 font-light">
|
||||||
<Switch
|
<h6 className="text-sm">{guide.Heading}</h6>
|
||||||
checked={statisticalParticipation}
|
<p className="text-disabled-text">{guide.Description}</p>
|
||||||
onCheckedChange={handleStatisticalToggle}
|
{guide.Items.map((item, i) => {
|
||||||
id={data.StatisticalParticipation.HtmlName}
|
return (
|
||||||
name={data.StatisticalParticipation.HtmlName}
|
<div key={i}>
|
||||||
className="w-12 h-6 scale-[0.9]"
|
<div className="ml-2 mt-2 bg-blue-100 inline-block size-6 text-center pt-[5px] pr-px text-blue-500 rounded-full">{item.Mark}</div>
|
||||||
/>
|
<span>{item.Label}</span>
|
||||||
</div>
|
</div>
|
||||||
<p className='text-xs text-disabled-text font-light'>
|
);
|
||||||
{data.StatisticalParticipation.Description}
|
})}
|
||||||
</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
|
{guide.Notes.map((note, i) => {
|
||||||
|
return (
|
||||||
|
<div key={i} className="mt-4 p-3 text-yellow-800 rounded-lg bg-yellow-50 border border-solid border-yellow-200">
|
||||||
|
{note}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
</section>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="overflow-y-auto h-full noscrollbar flex flex-col gap-6">
|
||||||
|
<div className="grid grid-cols-3 items-center">
|
||||||
|
<span></span>
|
||||||
|
<h1 className="text-sm2 place-self-center font-medium">{data.Heading}</h1>
|
||||||
|
<ArrowLeft
|
||||||
|
className="cursor-pointer place-self-end"
|
||||||
|
size="24"
|
||||||
|
color="currentColor"
|
||||||
|
onClick={() => {
|
||||||
|
router.back();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<section className={glassSurfaceCard("p-4")}>
|
||||||
|
<div className="flex justify-between items-center pb-4">
|
||||||
|
<h2 className="text-sm leading-5">{data.StatisticalParticipation.Heading}</h2>
|
||||||
|
<Switch
|
||||||
|
checked={statisticalParticipation}
|
||||||
|
onCheckedChange={handleStatisticalToggle}
|
||||||
|
id={data.StatisticalParticipation.HtmlName}
|
||||||
|
name={data.StatisticalParticipation.HtmlName}
|
||||||
|
className="w-12 h-6 scale-[0.9]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<p className="text-xs text-disabled-text font-light">{data.StatisticalParticipation.Description}</p>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default UserSettingsIndex
|
export default UserSettingsIndex;
|
||||||
|
|||||||
@@ -1,112 +1,85 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import Button from '@/components/button/PrimaryButton';
|
import Button from "@/components/button/PrimaryButton";
|
||||||
import InputField from '@/components/input/InputField';
|
import InputField from "@/components/input/InputField";
|
||||||
import { ef, ue } from '@/lib/helpers/utfNumbers';
|
import { ef, ue } from "@/lib/helpers/utfNumbers";
|
||||||
import { ArrowLeft, ArrowRight, WalletMinus } from 'iconsax-react';
|
import { glassSurfaceCard } from "@/lib/styles/glassSurface";
|
||||||
import { useRouter } from 'next/navigation';
|
import { ArrowLeft, ArrowRight, WalletMinus } from "iconsax-react";
|
||||||
import React, { useState } from 'react'
|
import { useRouter } from "next/navigation";
|
||||||
import { glassSurfaceCard } from '@/lib/styles/glassSurface';
|
import React, { useState } from "react";
|
||||||
|
|
||||||
type Props = object
|
type Props = object;
|
||||||
|
|
||||||
function UserWalletIndex({ }: Props) {
|
function UserWalletIndex({}: Props) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [chargeValue, setChargeValue] = useState<string>('0');
|
const [chargeValue, setChargeValue] = useState<string>("0");
|
||||||
const chargeAction = (e: React.FormEvent<HTMLFormElement>) => {
|
const chargeAction = (e: React.FormEvent<HTMLFormElement>) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const data = new FormData(e.currentTarget)
|
const data = new FormData(e.currentTarget);
|
||||||
const value = Number(ue(String(data.get('chargeValue') ?? 0))) + 0;
|
const value = Number(ue(String(data.get("chargeValue") ?? 0))) + 0;
|
||||||
console.log("Charge for: ", value);
|
console.log("Charge for: ", value);
|
||||||
}
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='overflow-y-auto h-full noscrollbar flex flex-col'>
|
<div className="overflow-y-auto h-full noscrollbar flex flex-col">
|
||||||
<div className='grid grid-cols-3 items-center'>
|
<div className="grid grid-cols-3 items-center">
|
||||||
<span></span>
|
<span></span>
|
||||||
<h1 className='text-sm2 place-self-center font-medium'>پروفایل کاربری</h1>
|
<h1 className="text-sm2 place-self-center font-medium">پروفایل کاربری</h1>
|
||||||
<ArrowLeft
|
<ArrowLeft
|
||||||
className='cursor-pointer place-self-end'
|
className="cursor-pointer place-self-end"
|
||||||
size='24'
|
size="24"
|
||||||
color='currentColor'
|
color="currentColor"
|
||||||
onClick={() => { router.back() }}
|
onClick={() => {
|
||||||
/>
|
router.back();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form onSubmit={chargeAction} className={glassSurfaceCard("mt-8 flex-1 h-full w-full py-6 px-4 flex flex-col justify-between")}>
|
||||||
|
<div className="">
|
||||||
|
<div className="flex items-center justify-center text-center gap-4 pb-6 border-b-[1.5px] border-border">
|
||||||
|
<div className="block">
|
||||||
|
<div className="font-medium text-sm flex items-center gap-2">
|
||||||
|
<WalletMinus className="size-5 stroke-foreground mb-0.5" />
|
||||||
|
موجودی کیف پول
|
||||||
|
</div>
|
||||||
|
<div className="text-sm text-primary mt-3 inline-flex dark:text-neutral-200 items-center gap-2">{ef("250.000 تومان")}</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<form
|
<div className="grid gap-3 mt-6">
|
||||||
onSubmit={chargeAction}
|
<div className="inline-flex items-center mb-3 gap-2.5 text-sm2">برای شارژ کیف پول خود میتوانید بر روی یکی از مبالغ زیر کلیک کنید و یا مبلغ دلخواه خود را وارد کنید</div>
|
||||||
className={glassSurfaceCard('mt-8 flex-1 h-full w-full py-6 px-4 flex flex-col justify-between')}>
|
<Button type="button" onClick={() => setChargeValue("50000")} className="bg-disabled! text-sm2 text-foreground! flex justify-between items-center">
|
||||||
|
<ArrowRight className="stroke-foreground size-5" />
|
||||||
<div className="">
|
<span className="mt-0.5">{ef("50,000 تومان")}</span>
|
||||||
<div className="flex items-center justify-center text-center gap-4 pb-6 border-b-[1.5px] border-border">
|
</Button>
|
||||||
<div className='block'>
|
<Button type="button" onClick={() => setChargeValue("150000")} className="bg-disabled! text-sm2 text-foreground! flex justify-between items-center">
|
||||||
<div className='font-medium text-sm flex items-center gap-2'>
|
<ArrowRight className="stroke-foreground size-5" />
|
||||||
<WalletMinus className='size-5 stroke-foreground mb-0.5' />
|
<span className="mt-0.5">{ef("150,000 تومان")}</span>
|
||||||
موجودی کیف پول
|
</Button>
|
||||||
</div>
|
<Button type="button" onClick={() => setChargeValue("300000")} className="bg-disabled! text-sm2 text-foreground! flex justify-between items-center">
|
||||||
<div className='text-sm text-primary mt-3 inline-flex dark:text-neutral-200 items-center gap-2'>
|
<ArrowRight className="stroke-foreground size-5" />
|
||||||
{ef('250.000 تومان')}
|
<span className="mt-0.5">{ef("300,000 تومان")}</span>
|
||||||
</div>
|
</Button>
|
||||||
</div>
|
<InputField
|
||||||
</div>
|
className="bg-container mt-7"
|
||||||
|
labelText="مبلغ دلخواه (تومان)"
|
||||||
<div className="grid gap-3 mt-6">
|
dir="ltr"
|
||||||
<div className='inline-flex items-center mb-3 gap-2.5 text-sm2'>
|
inputMode="decimal"
|
||||||
برای شارژ کیف پول خود میتوانید بر روی یکی از مبالغ زیر کلیک کنید و یا مبلغ دلخواه خود را وارد کنید
|
htmlFor="chargeValue"
|
||||||
</div>
|
placeholder=""
|
||||||
<Button
|
value={ef(chargeValue)}
|
||||||
type='button'
|
onChange={(e) => setChargeValue(e.target.value)}
|
||||||
onClick={() => setChargeValue('50000')}
|
/>
|
||||||
className='!bg-disabled text-sm2 !text-foreground flex justify-between items-center'
|
</div>
|
||||||
>
|
|
||||||
<ArrowRight className='stroke-foreground size-5' />
|
|
||||||
<span className='mt-0.5'>
|
|
||||||
{ef('50,000 تومان')}
|
|
||||||
</span>
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
type='button'
|
|
||||||
onClick={() => setChargeValue('150000')}
|
|
||||||
className='!bg-disabled text-sm2 !text-foreground flex justify-between items-center'
|
|
||||||
>
|
|
||||||
<ArrowRight className='stroke-foreground size-5' />
|
|
||||||
<span className='mt-0.5'>
|
|
||||||
{ef('150,000 تومان')}
|
|
||||||
</span>
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
type='button'
|
|
||||||
onClick={() => setChargeValue('300000')}
|
|
||||||
className='!bg-disabled text-sm2 !text-foreground flex justify-between items-center'
|
|
||||||
>
|
|
||||||
<ArrowRight className='stroke-foreground size-5' />
|
|
||||||
<span className='mt-0.5'>
|
|
||||||
{ef('300,000 تومان')}
|
|
||||||
</span>
|
|
||||||
</Button>
|
|
||||||
<InputField
|
|
||||||
className='bg-container mt-7'
|
|
||||||
labelText='مبلغ دلخواه (تومان)'
|
|
||||||
dir='ltr'
|
|
||||||
inputMode='decimal'
|
|
||||||
htmlFor='chargeValue'
|
|
||||||
placeholder=''
|
|
||||||
value={ef(chargeValue)}
|
|
||||||
onChange={(e) => setChargeValue(e.target.value)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='w-full text-center mt-6'>
|
|
||||||
<Button
|
|
||||||
type='submit'
|
|
||||||
>
|
|
||||||
شارژ کیف پول
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
|
||||||
|
<div className="w-full text-center mt-6">
|
||||||
|
<Button type="submit">شارژ کیف پول</Button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default UserWalletIndex
|
export default UserWalletIndex;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
'use client';
|
"use client";
|
||||||
|
|
||||||
import React from 'react';
|
import { glassSurface } from "@/lib/styles/glassSurface";
|
||||||
import { glassSurface } from '@/lib/styles/glassSurface';
|
import React from "react";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
@@ -9,13 +9,7 @@ type Props = {
|
|||||||
|
|
||||||
function MenuItemRendererComponent({ children, ...rest }: Props) {
|
function MenuItemRendererComponent({ children, ...rest }: Props) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div {...rest} className={glassSurface(rest.className, "pb-4! py-4 transition-all duration-200 ease-out w-full rounded-3xl px-4 flex items-center justify-between gap-4")}>
|
||||||
{...rest}
|
|
||||||
className={glassSurface(
|
|
||||||
rest.className,
|
|
||||||
'!pb-4 py-4 transition-all duration-200 ease-out w-full rounded-3xl px-4 flex items-center justify-between gap-4',
|
|
||||||
)}>
|
|
||||||
|
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
'use client';
|
"use client";
|
||||||
|
|
||||||
import { useEffect, useRef, useState } from 'react';
|
import { motion } from "framer-motion";
|
||||||
import { motion } from 'framer-motion';
|
import Image from "next/image";
|
||||||
import Image from 'next/image';
|
import { useEffect, useRef, useState } from "react";
|
||||||
|
|
||||||
const MAX_DISPLAY_MS = 1200;
|
const MAX_DISPLAY_MS = 1200;
|
||||||
const EXIT_MS = 350;
|
const EXIT_MS = 350;
|
||||||
@@ -14,27 +14,21 @@ interface SplashScreenProps {
|
|||||||
onDismiss: () => void;
|
onDismiss: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function SplashScreen({
|
export default function SplashScreen({ logo, restaurantName, onDismiss }: SplashScreenProps) {
|
||||||
logo,
|
|
||||||
restaurantName,
|
|
||||||
onDismiss,
|
|
||||||
}: SplashScreenProps) {
|
|
||||||
const [opacity, setOpacity] = useState(1);
|
const [opacity, setOpacity] = useState(1);
|
||||||
const [logoState, setLogoState] = useState<'idle' | 'loading' | 'ready' | 'error'>(
|
const [logoState, setLogoState] = useState<"idle" | "loading" | "ready" | "error">(logo ? "loading" : "idle");
|
||||||
logo ? 'loading' : 'idle',
|
|
||||||
);
|
|
||||||
const onDismissRef = useRef(onDismiss);
|
const onDismissRef = useRef(onDismiss);
|
||||||
onDismissRef.current = onDismiss;
|
onDismissRef.current = onDismiss;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setLogoState(logo ? 'loading' : 'idle');
|
setLogoState(logo ? "loading" : "idle");
|
||||||
}, [logo]);
|
}, [logo]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!logo || logoState !== 'loading') return;
|
if (!logo || logoState !== "loading") return;
|
||||||
|
|
||||||
const logoTimeout = setTimeout(() => {
|
const logoTimeout = setTimeout(() => {
|
||||||
setLogoState('error');
|
setLogoState("error");
|
||||||
}, LOGO_TIMEOUT_MS);
|
}, LOGO_TIMEOUT_MS);
|
||||||
|
|
||||||
return () => clearTimeout(logoTimeout);
|
return () => clearTimeout(logoTimeout);
|
||||||
@@ -55,13 +49,12 @@ export default function SplashScreen({
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{ opacity: 1 }}
|
initial={{ opacity: 1 }}
|
||||||
animate={{ opacity }}
|
animate={{ opacity }}
|
||||||
transition={{ duration: EXIT_MS / 1000, ease: 'easeOut' }}
|
transition={{ duration: EXIT_MS / 1000, ease: "easeOut" }}
|
||||||
className="fixed inset-0 z-[9999] flex flex-col items-center justify-center bg-background"
|
className="fixed inset-0 z-9999 flex flex-col items-center justify-center bg-background"
|
||||||
data-slot="splash-screen"
|
data-slot="splash-screen"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
>
|
>
|
||||||
@@ -74,7 +67,7 @@ export default function SplashScreen({
|
|||||||
transition={{
|
transition={{
|
||||||
duration: 3,
|
duration: 3,
|
||||||
repeat: Infinity,
|
repeat: Infinity,
|
||||||
ease: 'easeInOut',
|
ease: "easeInOut",
|
||||||
}}
|
}}
|
||||||
className="absolute -top-20 -right-20 w-80 h-80 rounded-full bg-primary/20 blur-3xl"
|
className="absolute -top-20 -right-20 w-80 h-80 rounded-full bg-primary/20 blur-3xl"
|
||||||
/>
|
/>
|
||||||
@@ -87,31 +80,30 @@ export default function SplashScreen({
|
|||||||
duration: 3,
|
duration: 3,
|
||||||
delay: 0.5,
|
delay: 0.5,
|
||||||
repeat: Infinity,
|
repeat: Infinity,
|
||||||
ease: 'easeInOut',
|
ease: "easeInOut",
|
||||||
}}
|
}}
|
||||||
className="absolute -bottom-20 -left-20 w-80 h-80 rounded-full bg-primary/20 blur-3xl"
|
className="absolute -bottom-20 -left-20 w-80 h-80 rounded-full bg-primary/20 blur-3xl"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-col items-center gap-8 px-8 w-full max-w-md relative z-10">
|
<div className="flex flex-col items-center gap-8 px-8 w-full max-w-md relative z-10">
|
||||||
{logo && logoState !== 'error' && (
|
{logo && logoState !== "error" && (
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<Image
|
<Image
|
||||||
src={logo}
|
src={logo}
|
||||||
alt={restaurantName || 'Restaurant Logo'}
|
alt={restaurantName || "Restaurant Logo"}
|
||||||
width={200}
|
width={200}
|
||||||
height={100}
|
height={100}
|
||||||
unoptimized
|
unoptimized
|
||||||
priority
|
priority
|
||||||
className="object-contain"
|
className="object-contain"
|
||||||
onLoad={() => setLogoState('ready')}
|
onLoad={() => setLogoState("ready")}
|
||||||
onError={() => setLogoState('error')}
|
onError={() => setLogoState("error")}
|
||||||
style={{
|
style={{
|
||||||
opacity: logoState === 'ready' ? 1 : 0,
|
opacity: logoState === "ready" ? 1 : 0,
|
||||||
transition: 'opacity 0.3s',
|
transition: "opacity 0.3s",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -127,7 +119,7 @@ export default function SplashScreen({
|
|||||||
duration: 1.5,
|
duration: 1.5,
|
||||||
delay,
|
delay,
|
||||||
repeat: Infinity,
|
repeat: Infinity,
|
||||||
ease: 'easeInOut',
|
ease: "easeInOut",
|
||||||
}}
|
}}
|
||||||
className="w-3 h-3 rounded-full bg-primary shadow-lg shadow-primary/50"
|
className="w-3 h-3 rounded-full bg-primary shadow-lg shadow-primary/50"
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user