add: share modal
This commit is contained in:
@@ -1,12 +1,13 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import AnimatedBottomSheet from '@/components/bottomsheet/AnimatedBottomSheet';
|
import AnimatedBottomSheet from '@/components/bottomsheet/AnimatedBottomSheet';
|
||||||
import EqualizerIcon from '@/components/icons/EqualizerIcon';
|
import EqualizerIcon from '@/components/icons/EqualizerIcon';
|
||||||
|
import TelegramIcon from '@/components/icons/TelegramIcon';
|
||||||
import TabContainer from '@/components/tab/TabContainer';
|
import TabContainer from '@/components/tab/TabContainer';
|
||||||
import { TabHeader } from '@/components/tab/TabHeader';
|
import { TabHeader } from '@/components/tab/TabHeader';
|
||||||
import Comment from '@/components/utils/Comment';
|
import Comment from '@/components/utils/Comment';
|
||||||
import RateBar from '@/components/utils/RateBar';
|
import RateBar from '@/components/utils/RateBar';
|
||||||
import { AboutDataModel } from '@/lib/api/info/getAboutData';
|
import { AboutDataModel } from '@/lib/api/info/getAboutData';
|
||||||
import { ArrowDown2, CallCalling, Clock, Gallery, InfoCircle, Instagram, Location, MouseCircle, Star1, Whatsapp } from 'iconsax-react';
|
import { ArrowDown2, CallCalling, Clock, Gallery, InfoCircle, Instagram, Location, Star1, Whatsapp } from 'iconsax-react';
|
||||||
import { useQueryState } from 'next-usequerystate';
|
import { useQueryState } from 'next-usequerystate';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import React, { useCallback, useState } from 'react'
|
import React, { useCallback, useState } from 'react'
|
||||||
@@ -74,7 +75,7 @@ function AboutPage({ data }: Readonly<{ data: AboutDataModel; }>) {
|
|||||||
}
|
}
|
||||||
{data.contacts.telegram &&
|
{data.contacts.telegram &&
|
||||||
<a href={`https://t.me/${data.contacts.telegram}`} className='bg-[#EAEDF5] p-2 rounded-normal'>
|
<a href={`https://t.me/${data.contacts.telegram}`} className='bg-[#EAEDF5] p-2 rounded-normal'>
|
||||||
<MouseCircle variant='Linear' className='stroke-foreground' size={24} />
|
<TelegramIcon className='stroke-foreground' width={24} height={24} />
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
{data.contacts.whatsapp &&
|
{data.contacts.whatsapp &&
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const TelegramIcon: React.FC<React.SVGProps<SVGSVGElement>> = (props) => (
|
||||||
|
<svg
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
{...props} // This allows passing additional props like className, style, etc.
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M16.1502 12.8299L14.4202 13.4099C13.9402 13.5699 13.5702 13.9399 13.4102 14.4199L12.8302 16.1499C12.3402 17.6399 10.2402 17.6099 9.78018 16.1199L7.83019 9.83988C7.45019 8.58988 8.60019 7.43989 9.83019 7.81989L16.1202 9.76987C17.6102 10.2399 17.6302 12.3399 16.1502 12.8299Z"
|
||||||
|
stroke="#333333"
|
||||||
|
strokeWidth="1.5"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z"
|
||||||
|
stroke="#333333"
|
||||||
|
strokeWidth="1.5"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default TelegramIcon;
|
||||||
@@ -21,6 +21,8 @@ import { useAuthStore } from '@/zustand/authStore';
|
|||||||
import { useParams, usePathname, useRouter } from 'next/navigation';
|
import { useParams, usePathname, useRouter } from 'next/navigation';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { DocumentCopy, Instagram, Share, Whatsapp } from 'iconsax-react';
|
||||||
|
import TelegramIcon from '../icons/TelegramIcon';
|
||||||
|
|
||||||
type MenuItemType = {
|
type MenuItemType = {
|
||||||
href: string | undefined;
|
href: string | undefined;
|
||||||
@@ -37,7 +39,7 @@ const menuItems: Array<Array<MenuItemType>> = [
|
|||||||
{ href: 'orders', title: 'Orders', icon: <CalendarSearchIcon width={20} height={20} /> },
|
{ href: 'orders', title: 'Orders', icon: <CalendarSearchIcon width={20} height={20} /> },
|
||||||
{ href: 'transactions', title: 'Transactions', icon: <ReceiptIcon width={20} height={20} /> },
|
{ href: 'transactions', title: 'Transactions', icon: <ReceiptIcon width={20} height={20} /> },
|
||||||
{ href: '/', title: 'Games', icon: <GameControllerIcon width={20} height={20} /> },
|
{ href: '/', title: 'Games', icon: <GameControllerIcon width={20} height={20} /> },
|
||||||
{ href: 'my-services', title: 'ShareWithFriends', icon: <ThumbsUpIcon width={20} height={20} /> },
|
{ href: '?share', title: 'ShareWithFriends', icon: <ThumbsUpIcon width={20} height={20} /> },
|
||||||
{ href: 'services', title: 'ReportProblem', icon: <NoteBoardIcon width={20} height={20} /> },
|
{ href: 'services', title: 'ReportProblem', icon: <NoteBoardIcon width={20} height={20} /> },
|
||||||
{ href: 'invoices', title: 'InstallApp', icon: <DirectboxReceiveIcon width={20} height={20} /> }
|
{ href: 'invoices', title: 'InstallApp', icon: <DirectboxReceiveIcon width={20} height={20} /> }
|
||||||
],
|
],
|
||||||
@@ -58,6 +60,7 @@ type Props = {
|
|||||||
function SideMenu({ menuState, toggleMenuState, nightModeState, togglenightModeState }: Props) {
|
function SideMenu({ menuState, toggleMenuState, nightModeState, togglenightModeState }: Props) {
|
||||||
const menuStateMemo = useMemo(() => menuState, [menuState]);
|
const menuStateMemo = useMemo(() => menuState, [menuState]);
|
||||||
const [logoutModalVisible, setLogoutModalVisible] = useState(false);
|
const [logoutModalVisible, setLogoutModalVisible] = useState(false);
|
||||||
|
const [shareModalVisible, setShareModalVisible] = useState(false);
|
||||||
const closeRef = useRef<HTMLDivElement>(null);
|
const closeRef = useRef<HTMLDivElement>(null);
|
||||||
const userIsAuthenticated = true; // useAuthStore((state) => state.isAuthenticated);
|
const userIsAuthenticated = true; // useAuthStore((state) => state.isAuthenticated);
|
||||||
const authLogout = useAuthStore((state) => state.logout);
|
const authLogout = useAuthStore((state) => state.logout);
|
||||||
@@ -71,6 +74,9 @@ function SideMenu({ menuState, toggleMenuState, nightModeState, togglenightModeS
|
|||||||
const { t: tLogoutModal } = useTranslation('common', {
|
const { t: tLogoutModal } = useTranslation('common', {
|
||||||
keyPrefix: 'LogoutModal'
|
keyPrefix: 'LogoutModal'
|
||||||
});
|
});
|
||||||
|
const { t: tShareModal } = useTranslation('common', {
|
||||||
|
keyPrefix: 'ShareModal'
|
||||||
|
});
|
||||||
|
|
||||||
const variants: Variants = {
|
const variants: Variants = {
|
||||||
hidden: { x: '100%', transition: { duration: 0.1, ease: 'easeInOut' } },
|
hidden: { x: '100%', transition: { duration: 0.1, ease: 'easeInOut' } },
|
||||||
@@ -89,6 +95,12 @@ function SideMenu({ menuState, toggleMenuState, nightModeState, togglenightModeS
|
|||||||
setLogoutModalVisible((state) => !state);
|
setLogoutModalVisible((state) => !state);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const toggleShareModalVisiblity = (e?: React.MouseEvent) => {
|
||||||
|
e?.preventDefault();
|
||||||
|
e?.stopPropagation();
|
||||||
|
setShareModalVisible((state) => !state);
|
||||||
|
};
|
||||||
|
|
||||||
const onLogout = (e: React.MouseEvent<HTMLButtonElement> | null) => {
|
const onLogout = (e: React.MouseEvent<HTMLButtonElement> | null) => {
|
||||||
if (!e) return;
|
if (!e) return;
|
||||||
if (userIsAuthenticated) {
|
if (userIsAuthenticated) {
|
||||||
@@ -97,7 +109,10 @@ function SideMenu({ menuState, toggleMenuState, nightModeState, togglenightModeS
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const hrefOnClicks = [{ href: '?logout', handler: toggleLogoutModalVisiblity }];
|
const hrefOnClicks = [
|
||||||
|
{ href: '?logout', handler: toggleLogoutModalVisiblity },
|
||||||
|
{ href: '?share', handler: toggleShareModalVisiblity }
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -137,6 +152,11 @@ function SideMenu({ menuState, toggleMenuState, nightModeState, togglenightModeS
|
|||||||
className={clsx(isActive && 'text-foreground!')}
|
className={clsx(isActive && 'text-foreground!')}
|
||||||
href={item.href ?? ''}
|
href={item.href ?? ''}
|
||||||
title={tMenu(item.title)}
|
title={tMenu(item.title)}
|
||||||
|
onClick={
|
||||||
|
typeof item.href === 'string'
|
||||||
|
? hrefOnClicks.find((i) => i.href === item.href)?.handler
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
icon={
|
icon={
|
||||||
<span className={clsx(isActive ? 'text-foreground!' : 'text-icon-deactive')}>
|
<span className={clsx(isActive ? 'text-foreground!' : 'text-icon-deactive')}>
|
||||||
{item.icon}
|
{item.icon}
|
||||||
@@ -203,6 +223,45 @@ function SideMenu({ menuState, toggleMenuState, nightModeState, togglenightModeS
|
|||||||
</motion.div>
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
</BlurredOverlayContainer>
|
</BlurredOverlayContainer>
|
||||||
|
|
||||||
|
{/* Share modal */}
|
||||||
|
<BlurredOverlayContainer visible={shareModalVisible} onClick={toggleShareModalVisiblity} inDuration={100} outDuration={100} outDelay={75}>
|
||||||
|
<div className="absolute top-1/2 left-0 w-full px-6">
|
||||||
|
<motion.div
|
||||||
|
animate={{ y: shareModalVisible ? [10, 0] : [0, 10] }}
|
||||||
|
transition={{ duration: 0.1, ease: 'easeInOut' }}
|
||||||
|
className="top-1/2 absolute left-1/2 min-w-xs w-full max-w-sm text-center -translate-1/2 px-6 pt-8 pb-9 drop-shadow-container bg-white/63 rounded-4xl"
|
||||||
|
>
|
||||||
|
<h2 className="text-base font-medium">
|
||||||
|
<Share className="inline-block ml-2 mb-1.5 stroke-primary" size={24} />
|
||||||
|
{tShareModal('Heading')}
|
||||||
|
</h2>
|
||||||
|
<p className="text-xs font-medium mt-6">
|
||||||
|
{tShareModal('Description')}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<Button onClick={onLogout} className="text-sm mt-8">
|
||||||
|
<DocumentCopy className="inline-block ml-2 mb-0.5 stroke-white" size={20} />
|
||||||
|
<span className="font-light">{tShareModal('ButtonCopy')}</span>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-3 gap-5.5 mt-6 px-12">
|
||||||
|
<div className="place-items-center">
|
||||||
|
<TelegramIcon width={24} height={24} className="mb-1.5 stroke-primary" />
|
||||||
|
<span className='text-xs2 font-medium'>Telegram</span>
|
||||||
|
</div>
|
||||||
|
<div className="place-items-center">
|
||||||
|
<Whatsapp size={24} className="mb-1.5 stroke-primary" />
|
||||||
|
<span className='text-xs2 font-medium'>WhatsApp</span>
|
||||||
|
</div>
|
||||||
|
<div className="place-items-center">
|
||||||
|
<Instagram size={24} className="mb-1.5 stroke-primary" />
|
||||||
|
<span className='text-xs2 font-medium'>Instagram</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</BlurredOverlayContainer>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,11 @@
|
|||||||
"ButtonOk": "بله خارج میشوم",
|
"ButtonOk": "بله خارج میشوم",
|
||||||
"ButtonCancel": "منصرف شدم"
|
"ButtonCancel": "منصرف شدم"
|
||||||
},
|
},
|
||||||
|
"ShareModal": {
|
||||||
|
"Heading": "اشتراک گذاری",
|
||||||
|
"Description": "اپلیکیشن ما را با دوستان خود به اشتراک بگذارید!",
|
||||||
|
"ButtonCopy": "کپی کردن لینک"
|
||||||
|
},
|
||||||
"DeleteChatModal": {
|
"DeleteChatModal": {
|
||||||
"Heading": "پاک کردن چت",
|
"Heading": "پاک کردن چت",
|
||||||
"Description": "آیا از پاک کردن {count} چت اطمینان دارید؟",
|
"Description": "آیا از پاک کردن {count} چت اطمینان دارید؟",
|
||||||
|
|||||||
Reference in New Issue
Block a user