From 87c5908177e50d372606e576d5cf68a471bbfda6 Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Mon, 18 Aug 2025 16:10:49 +0330 Subject: [PATCH] short description + edit first name last name + ... --- src/index.css | 9 +++ src/langs/fa.json | 4 +- src/pages/profile/Profile.tsx | 10 +++ src/pages/profile/components/FirstName.tsx | 71 ++++++++++++++++++++++ src/pages/profile/components/LastName.tsx | 71 ++++++++++++++++++++++ src/pages/service/BuyService.tsx | 8 ++- src/pages/service/DetailService.tsx | 20 +++++- src/pages/service/types/ServiecTypes.ts | 4 +- 8 files changed, 190 insertions(+), 7 deletions(-) create mode 100644 src/pages/profile/components/FirstName.tsx create mode 100644 src/pages/profile/components/LastName.tsx diff --git a/src/index.css b/src/index.css index d72a445..bffd054 100644 --- a/src/index.css +++ b/src/index.css @@ -256,3 +256,12 @@ body { .plan:nth-child(even) { background-color: #f5f5f5; } + +@layer utilities { + .line-clamp-4 { + display: -webkit-box; + -webkit-line-clamp: 4; + -webkit-box-orient: vertical; + overflow: hidden; + } +} diff --git a/src/langs/fa.json b/src/langs/fa.json index 42d2921..5fdd05e 100644 --- a/src/langs/fa.json +++ b/src/langs/fa.json @@ -54,7 +54,7 @@ "menu": "منو", "mainpage": "صفحه اصلی", "myservice": "سرویس های من", - "other_service": "سایر سرویس ها", + "other_service": "سرویس های داناک", "receipt_list": "لیست صورتحساب", "transactions": "تراکنش ها", "other": "سایر", @@ -397,6 +397,8 @@ "enter_carefully_your_information": "اطلاعت شخصی خود را با دقت وارد کنید.", "date_of_birth": "تاریخ تولد", "national_code": "کد ملی", + "first_name": "نام", + "last_name": "نام خانوادگی", "address": "آدرس", "address_live": "آدرس محل سکونت خود را با دقت وارد کنید", "province": "استان", diff --git a/src/pages/profile/Profile.tsx b/src/pages/profile/Profile.tsx index 03c5e9c..8c87548 100644 --- a/src/pages/profile/Profile.tsx +++ b/src/pages/profile/Profile.tsx @@ -18,6 +18,8 @@ import { useFormik } from 'formik' import * as Yup from 'yup' import Email from './components/Email' import Phone from './components/Phone' +import FirstName from './components/FirstName.tsx' +import LastName from './components/LastName.tsx' const Profile: FC = () => { @@ -34,6 +36,8 @@ const Profile: FC = () => { cityId: '', userAddress: '', postalCode: '', + firstName: '', + lastName: '', }, validationSchema: Yup.object({ cityId: Yup.string().required(t('errors.required')), @@ -59,6 +63,8 @@ const Profile: FC = () => { cityId: getProfile.data.data.user.city?.id || '', userAddress: getProfile.data.data.user.userAddress || '', postalCode: getProfile.data.data.user.postalCode || '', + firstName: getProfile.data.data.user.firstName || '', + lastName: getProfile.data.data.user.lastName || '', }) if (getProfile.data.data.user.city) { } @@ -190,6 +196,10 @@ const Profile: FC = () => { value={getProfile.data?.data?.user?.nationalCode} /> + + + + diff --git a/src/pages/profile/components/FirstName.tsx b/src/pages/profile/components/FirstName.tsx new file mode 100644 index 0000000..234b1d9 --- /dev/null +++ b/src/pages/profile/components/FirstName.tsx @@ -0,0 +1,71 @@ +import { FC, useEffect, useState } from 'react' +import Input from '../../../components/Input' +import Button from '../../../components/Button' +import { Edit } from 'iconsax-react' +import { useTranslation } from 'react-i18next' +import { useUpdateProfile } from '../hooks/useProfileData' +import { UpdateProfileType } from '../types/ProfileTypes' +import { toast } from '../../../components/Toast' +import { ErrorType } from '../../../helpers/types' + +type Props = { + firstName: string | null | undefined +} + +const FirstName: FC = (props: Props) => { + + const { t } = useTranslation('global') + const [value, setValue] = useState(props.firstName || '') + const [isReadOnly, setIsReadOnly] = useState(true) + const updateProfile = useUpdateProfile() + + useEffect(() => { + setValue(props.firstName || '') + }, [props.firstName]) + + const handleSave = () => { + const params: UpdateProfileType = { firstName: value } + updateProfile.mutate(params, { + onSuccess: () => { + toast(t('success'), 'success') + setIsReadOnly(true) + }, + onError: (error: ErrorType) => { + toast(error.response?.data?.error?.message[0], 'error') + } + }) + } + + const isDisabled = value.trim().length === 0 || value === (props.firstName || '') + + return ( +
+ setValue(e.target.value)} + /> + { + isReadOnly ? ( +
setIsReadOnly(false)} className='flex cursor-pointer relative -top-3 gap-1 text-[#0047FF] text-xs items-center'> + +
{t('edit')}
+
+ ) : ( +
+ ) +} + +export default FirstName + + diff --git a/src/pages/profile/components/LastName.tsx b/src/pages/profile/components/LastName.tsx new file mode 100644 index 0000000..4605f09 --- /dev/null +++ b/src/pages/profile/components/LastName.tsx @@ -0,0 +1,71 @@ +import { FC, useEffect, useState } from 'react' +import Input from '../../../components/Input' +import Button from '../../../components/Button' +import { Edit } from 'iconsax-react' +import { useTranslation } from 'react-i18next' +import { useUpdateProfile } from '../hooks/useProfileData' +import { UpdateProfileType } from '../types/ProfileTypes' +import { toast } from '../../../components/Toast' +import { ErrorType } from '../../../helpers/types' + +type Props = { + lastName: string | null | undefined +} + +const LastName: FC = (props: Props) => { + + const { t } = useTranslation('global') + const [value, setValue] = useState(props.lastName || '') + const [isReadOnly, setIsReadOnly] = useState(true) + const updateProfile = useUpdateProfile() + + useEffect(() => { + setValue(props.lastName || '') + }, [props.lastName]) + + const handleSave = () => { + const params: UpdateProfileType = { lastName: value } + updateProfile.mutate(params, { + onSuccess: () => { + toast(t('success'), 'success') + setIsReadOnly(true) + }, + onError: (error: ErrorType) => { + toast(error.response?.data?.error?.message[0], 'error') + } + }) + } + + const isDisabled = value.trim().length === 0 || value === (props.lastName || '') + + return ( +
+ setValue(e.target.value)} + /> + { + isReadOnly ? ( +
setIsReadOnly(false)} className='flex cursor-pointer relative -top-3 gap-1 text-[#0047FF] text-xs items-center'> + +
{t('edit')}
+
+ ) : ( +
+ ) +} + +export default LastName + + diff --git a/src/pages/service/BuyService.tsx b/src/pages/service/BuyService.tsx index a326dba..20475d6 100644 --- a/src/pages/service/BuyService.tsx +++ b/src/pages/service/BuyService.tsx @@ -33,11 +33,15 @@ const BuyService: FC = () => { }, validationSchema: Yup.object({ businessName: Yup.string().required(t('errors.required')), - businessPhone: Yup.string().required(t('errors.required')), - description: Yup.string().required(t('errors.required')), planId: Yup.string().required(t('errors.required')) }), onSubmit: (values) => { + if (!values.businessPhone) { + values.businessPhone = undefined + } + if (!values.description) { + values.description = undefined + } buyService.mutate(values, { onSuccess: (data) => { toast(t('success'), 'success') diff --git a/src/pages/service/DetailService.tsx b/src/pages/service/DetailService.tsx index 7766fb5..bb71bbc 100644 --- a/src/pages/service/DetailService.tsx +++ b/src/pages/service/DetailService.tsx @@ -1,4 +1,4 @@ -import { FC, Fragment } from 'react' +import { FC, Fragment, useState } from 'react' import { useTranslation } from 'react-i18next' import Rate from 'rc-rate' import ServiceImages from './components/ServiceImages' @@ -20,6 +20,7 @@ const DetailService: FC = () => { const getAdsLeft = useGetAds(AdsDisplayLocation.SINGLE_SERVICE_PAGE) const getDetailService = useGetServiceBySlug(id ? id : '') + const [isExpanded, setIsExpanded] = useState(false) return (
@@ -87,8 +88,23 @@ const DetailService: FC = () => {
{t('service.compelete_description')}
-

+

+ { + (getDetailService.data?.data?.danakService?.metaDescription?.length || 0) > 0 && ( +
+ +
+ ) + }
diff --git a/src/pages/service/types/ServiecTypes.ts b/src/pages/service/types/ServiecTypes.ts index 62889d9..5b2ae6f 100644 --- a/src/pages/service/types/ServiecTypes.ts +++ b/src/pages/service/types/ServiecTypes.ts @@ -120,8 +120,8 @@ export type MyServicesItem = { export type BuyServiceType = { planId: string; businessName: string; - businessPhone: string; - description: string; + businessPhone?: string; + description?: string; serviceId: string; };