add: profile edit page

This commit is contained in:
Mahyar Khanbolooki
2025-07-17 17:15:17 +03:30
parent ac5eb68444
commit 77505d5098
11 changed files with 594 additions and 234 deletions
+1 -1
View File
@@ -18,7 +18,7 @@ function FoodPage({ }: Props) {
return (
<div className='w-full'>
<div className='w-full -translate-y-2'>
<div className="relative w-full rounded-2xl overflow-hidden">
<Image
className='w-full '
+3 -4
View File
@@ -13,12 +13,11 @@ import React from "react";
import MenuItem from "@/components/listview/MenuItem";
import Button from "@/components/button/PrimaryButton";
import AnimatedBottomSheet from "@/components/bottomsheet/AnimatedBottomSheet";
import SearchComboBox from "@/components/combobox/SearchComboBox";
import { DropdownOption } from "@/components/combobox/Combobox";
import { Switch } from "@/components/ui/switch";
import { TicketPercentIcon } from "lucide-react";
import { MedalStar } from 'iconsax-react'
import { useQueryState } from 'next-usequerystate'
import ComboBox, { DropdownOption } from "@/components/combobox/ComboBox";
const categories = new Array(13).fill({ title: "خوراک", icon: "" });
@@ -239,12 +238,12 @@ const MenuIndex = () => {
<AnimatedBottomSheet title="فیلتر ها" visible={filterModal} outDelay={150} onClick={toggleFilterModal}>
<div className="ps-8.5 pe-[31px] mt-[89px]">
<SearchComboBox
<ComboBox
title="محتویات"
options={contents}
selectedId={selectedContentId}
onSelectionChange={changeSelectedContent} />
<SearchComboBox
<ComboBox
className="relative mt-9.5"
title="روش ارسال"
options={shippings}
+165
View File
@@ -0,0 +1,165 @@
"use client";
import Button from '@/components/button/PrimaryButton';
import { Button as ShadButton } from '@/components/ui/button';
import ComboBox from '@/components/combobox/ComboBox';
import InputField from '@/components/input/InputField';
import { PORFILE_EDIT_PAGE_ELEMENT } from '@/enums';
import { Popover, PopoverTrigger, PopoverContent } from '@radix-ui/react-popover';
// import { useProfile } from '@/hooks/auth/useProfile';
// import { useAuthStore } from '@/zustand/authStore';
import { Calendar2, Camera } from 'iconsax-react';
import Image from 'next/image';
import React, { ChangeEvent, useState } from 'react'
import Calendar from '@/components/ui/calendar';
import { getDateLib } from "react-day-picker/persian";
type Props = object
function ProfileIndex({ }: Props) {
const [fullname, setFullName] = useState("");
const [email, setEmail] = useState("");
const [phoneNumber, setPhoneNumber] = useState("");
const [dateOfBirth, setDateOfBirth] = React.useState<Date | undefined>(new Date());
const [selectedGender, setSelectedGender] = useState("");
const [showCalendar, setShowCalendar] = useState(false);
const dateLib = getDateLib()
const changeGender = (e: React.MouseEvent<HTMLDivElement, MouseEvent>, index: number) => {
setSelectedGender(() => String(index));
}
// const isAuthenticated = useAuthStore((state) => state.isAuthenticated);
// const { mutate, data, isPending } = useProfile();
// useEffect(() => {
// if (isAuthenticated) {
// mutate();
// }
// // eslint-disable-next-line react-hooks/exhaustive-deps
// }, [isAuthenticated])
const onChange = (e: ChangeEvent<HTMLInputElement>) => {
if (e.target.name == PORFILE_EDIT_PAGE_ELEMENT.INPUT_FULLNAME) {
setFullName(() => e.target.value)
}
else if (e.target.name == PORFILE_EDIT_PAGE_ELEMENT.INPUT_EMAIL) {
setEmail(() => e.target.value)
}
else if (e.target.name == PORFILE_EDIT_PAGE_ELEMENT.INPUT_PHONE) {
setPhoneNumber(() => e.target.value)
}
// else if (e.target.name == PORFILE_EDIT_PAGE_ELEMENT.INPUT_DOB) {
// setDateOfBirth(() => e.target.value)
// }
}
return (
<>
<div className='relative text-center'>
<div className='font-medium text-sm2 leading-6'>ویرایش اطلاعات</div>
</div>
<div className="mt-8 bg-container rounded-container w-full box-shadow-normal py-6 px-4 flex flex-col justify-between">
<div className="">
<div className="justify-self-center w-fit relative text-center pb-10"
>
<button>
<Image
src={'/assets/images/user-avatar.png'}
className='rounded-full'
alt='user avatar'
width={96}
height={96}
/>
<div
className='w-24 h-24 absolute top-0 left-0 rounded-full'
style={{
background: 'linear-gradient(180deg, rgba(0, 0, 0, 0) 51.56%, rgba(0, 0, 0, 0.5) 100%)'
}}>
<Camera size={20} className='stroke-white absolute bottom-3 left-1/2 -translate-x-1/2' />
</div>
</button>
</div>
<div className="grid gap-6 mt-6">
<InputField
onChange={onChange}
className=''
labelText='نام و نام خانوادگی'
htmlFor={PORFILE_EDIT_PAGE_ELEMENT.INPUT_FULLNAME}
value={fullname}
/>
<InputField
onChange={onChange}
dir='ltr'
type='email'
className=''
labelText='ایمیل'
htmlFor={PORFILE_EDIT_PAGE_ELEMENT.INPUT_EMAIL}
value={email}
/>
<InputField
onChange={onChange}
dir='ltr'
type='number'
className=''
labelText='شماره همراه'
htmlFor={PORFILE_EDIT_PAGE_ELEMENT.INPUT_PHONE}
value={phoneNumber}
/>
<Popover open={showCalendar} onOpenChange={setShowCalendar}>
<PopoverTrigger asChild>
<ShadButton
variant="outline"
id="date"
className="w-full bg-white justify-between font-normal relative h-11 rounded-normal hover:bg-white"
>
{dateOfBirth ? dateLib.format(dateOfBirth, "yyyy/MM/dd") : "انتخاب کنید"}
<Calendar2 className='stroke-disabled2' size={24} />
<span className='absolute text-xs top-0 -translate-y-2 right-2 bg-white px-2'>تاریخ تولد</span>
</ShadButton>
</PopoverTrigger>
<PopoverContent className="w-auto overflow-hidden p-0 z-20 box-shadow-normal rounded-lg" align="center">
<Calendar
className='bg-white z-20 min-w-64 rounded-lg'
mode="single"
defaultMonth={dateOfBirth}
selected={dateOfBirth}
captionLayout="dropdown"
onSelect={(date) => {
setDateOfBirth(date)
setShowCalendar(false)
}}
/>
</PopoverContent>
</Popover>
<div className='relative'>
<ComboBox
searchable={false}
title=""
options={[{ id: '0', title: 'آقا', label: 'آقا' }, { id: '1', title: 'خانوم', label: 'خانوم' }]}
id={PORFILE_EDIT_PAGE_ELEMENT.INPUT_GENDER}
selectedId={selectedGender}
onSelectionChange={changeGender} />
<span className='absolute text-xs top-0 -translate-y-2 right-2 bg-white px-2'>جنسیت</span>
</div>
</div>
</div>
<div className='w-full text-center mt-16 grid grid-cols-2 gap-4'>
<Button>ذخیره</Button>
<Button className='bg-neutral-200! text-disabled-text!'>انصراف</Button>
</div>
</div>
</>
)
}
export default ProfileIndex
+6 -2
View File
@@ -5,11 +5,13 @@ import Button from '@/components/button/PrimaryButton';
// import { useAuthStore } from '@/zustand/authStore';
import { ArrowLeft, Calendar2, CallCalling, Profile, Sms, Verify } from 'iconsax-react';
import Image from 'next/image';
import Link from 'next/link';
import React from 'react'
type Props = object
function ProfileIndex({ }: Props) {
// const isAuthenticated = useAuthStore((state) => state.isAuthenticated);
// const { mutate, data, isPending } = useProfile();
@@ -30,7 +32,7 @@ function ProfileIndex({ }: Props) {
</button>
</div>
<div className="mt-9 rounded-container w-full box-shadow-normal py-6 px-4 flex flex-col justify-between">
<div className="mt-8 bg-white rounded-container w-full box-shadow-normal py-6 px-4 flex flex-col justify-between">
<div className="">
<div className="flex items-center justify-start gap-4 pb-6 border-b-[1.5px] border-border">
@@ -78,7 +80,9 @@ function ProfileIndex({ }: Props) {
</div>
<div className='w-full text-center mt-6'>
<Button>ویرایش اطلاعات</Button>
<Link href={'/profile/edit'}>
<Button>ویرایش اطلاعات</Button>
</Link>
</div>
</div>
</>