refactor: modals
This commit is contained in:
+1
-1
File diff suppressed because one or more lines are too long
@@ -1,8 +1,6 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import Button from '@/components/button/PrimaryButton';
|
|
||||||
import SearchBox from '@/components/input/SearchBox';
|
import SearchBox from '@/components/input/SearchBox';
|
||||||
import BlurredOverlayContainer from '@/components/overlays/BlurredOverlayContainer';
|
|
||||||
import { ScrollArea } from '@/components/ui/scrollarea';
|
import { ScrollArea } from '@/components/ui/scrollarea';
|
||||||
import { Radar2, Trash } from 'iconsax-react';
|
import { Radar2, Trash } from 'iconsax-react';
|
||||||
import { Check, CheckCheck } from 'lucide-react';
|
import { Check, CheckCheck } from 'lucide-react';
|
||||||
@@ -10,10 +8,10 @@ import Image from 'next/image';
|
|||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import React, { useCallback, useState } from 'react'
|
import React, { useCallback, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { motion } from 'framer-motion';
|
|
||||||
import { LongPressCallbackMeta, LongPressReactEvents, useLongPress } from 'use-long-press'
|
import { LongPressCallbackMeta, LongPressReactEvents, useLongPress } from 'use-long-press'
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import { ef } from '@/lib/helpers/utfNumbers';
|
import useToggle from '@/hooks/helpers/useToggle';
|
||||||
|
import Prompt from '@/components/utils/Prompt';
|
||||||
|
|
||||||
type Props = object
|
type Props = object
|
||||||
|
|
||||||
@@ -36,8 +34,8 @@ function ChatIndex({ }: Props) {
|
|||||||
});
|
});
|
||||||
const [search, setSearch] = useState('');
|
const [search, setSearch] = useState('');
|
||||||
const [selectedChats, setSelectedChats] = useState<Array<string>>([]);
|
const [selectedChats, setSelectedChats] = useState<Array<string>>([]);
|
||||||
const [deleteModalVisible, setDeleteModalVisible] = useState(false);
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const { active: deleteModal, onToggle: onToggleDeleteModal } = useToggle();
|
||||||
|
|
||||||
const [chatsList, setChatList] = useState<Array<ChatEntryModel>>([
|
const [chatsList, setChatList] = useState<Array<ChatEntryModel>>([
|
||||||
{
|
{
|
||||||
@@ -105,12 +103,10 @@ function ChatIndex({ }: Props) {
|
|||||||
const toggleDeleteModalVisiblity = (e?: React.MouseEvent) => {
|
const toggleDeleteModalVisiblity = (e?: React.MouseEvent) => {
|
||||||
e?.preventDefault();
|
e?.preventDefault();
|
||||||
e?.stopPropagation();
|
e?.stopPropagation();
|
||||||
setDeleteModalVisible((state) => {
|
if (deleteModal) {
|
||||||
if (state) {
|
setSelectedChats([]);
|
||||||
setSelectedChats([]);
|
}
|
||||||
}
|
onToggleDeleteModal()
|
||||||
return !state;
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteSelectedChats = () => {
|
const deleteSelectedChats = () => {
|
||||||
@@ -157,7 +153,7 @@ function ChatIndex({ }: Props) {
|
|||||||
<SearchBox placeholder={t('InputSearch.Placeholder')} value={search} onChange={(e) => setSearch(e.target.value)} />
|
<SearchBox placeholder={t('InputSearch.Placeholder')} value={search} onChange={(e) => setSearch(e.target.value)} />
|
||||||
|
|
||||||
{selectedChats.length > 0 ?
|
{selectedChats.length > 0 ?
|
||||||
<span onClick={toggleDeleteModalVisiblity} className='bg-container p-2 rounded-xl active:bg-gray-50'>
|
<span onClick={onToggleDeleteModal} className='bg-container p-2 rounded-xl active:bg-gray-50'>
|
||||||
<Trash size={24} className='stroke-primary' />
|
<Trash size={24} className='stroke-primary' />
|
||||||
</span>
|
</span>
|
||||||
:
|
:
|
||||||
@@ -222,30 +218,16 @@ function ChatIndex({ }: Props) {
|
|||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<BlurredOverlayContainer visible={deleteModalVisible} onClick={toggleDeleteModalVisiblity} inDuration={100} outDuration={100} outDelay={75}>
|
<Prompt
|
||||||
<div className="absolute top-1/2 left-0 w-full px-6">
|
title={tDeleteModal('Heading')}
|
||||||
<motion.div
|
description={tDeleteModal('Description').replace('{count}', String(selectedChats.length))}
|
||||||
animate={{ y: deleteModalVisible ? [10, 0] : [0, 10] }}
|
textConfirm={tDeleteModal('ButtonOk')}
|
||||||
transition={{ duration: 0.1, ease: 'easeInOut' }}
|
textCancel={tDeleteModal('ButtonCancel')}
|
||||||
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"
|
onConfirm={deleteSelectedChats}
|
||||||
>
|
onCancel={toggleDeleteModalVisiblity}
|
||||||
<h2 className="text-base font-medium">
|
onClick={toggleDeleteModalVisiblity}
|
||||||
{tDeleteModal('Heading')}
|
visible={deleteModal}
|
||||||
</h2>
|
/>
|
||||||
<p className="text-xs font-medium mt-6">
|
|
||||||
{tDeleteModal('Description').replace('{count}', ef(selectedChats.length))}
|
|
||||||
</p>
|
|
||||||
<div className="grid grid-cols-2 gap-5.5 mt-8">
|
|
||||||
<Button onClick={deleteSelectedChats} className="text-sm font-normal">
|
|
||||||
{tDeleteModal('ButtonOk')}
|
|
||||||
</Button>
|
|
||||||
<Button onClick={toggleDeleteModalVisiblity} className="bg-disabled! text-disabled2! text-sm font-normal">
|
|
||||||
{tDeleteModal('ButtonCancel')}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</motion.div>
|
|
||||||
</div>
|
|
||||||
</BlurredOverlayContainer>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,20 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import React, { useMemo, useRef, useState } from 'react';
|
import React, { useMemo, useRef } from 'react';
|
||||||
import { motion, PanInfo, Variants } from 'framer-motion';
|
import { motion, PanInfo, Variants } from 'framer-motion';
|
||||||
import SideMenuItem from './SideMenuItem';
|
import SideMenuItem from './SideMenuItem';
|
||||||
import NoteBoardIcon from '../icons/NoteBoardIcon';
|
import NoteBoardIcon from '../icons/NoteBoardIcon';
|
||||||
import BlurredOverlayContainer from '../overlays/BlurredOverlayContainer';
|
import BlurredOverlayContainer from '../overlays/BlurredOverlayContainer';
|
||||||
import NightModeSwitch from '../button/NightModeSwitch';
|
import NightModeSwitch from '../button/NightModeSwitch';
|
||||||
import Button from '../button/PrimaryButton';
|
import Button from '../button/PrimaryButton';
|
||||||
import { useAuthStore } from '@/zustand/authStore';
|
import { useParams, usePathname } 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 { CalendarSearch, Cup, DirectboxReceive, DocumentCopy, Game, Icon, Instagram, Like1, LogoutCurve, Notification, Receipt1, Setting2, Share, TicketDiscount, Whatsapp } from 'iconsax-react';
|
import { CalendarSearch, Cup, DirectboxReceive, DocumentCopy, Game, Icon, Instagram, Like1, LogoutCurve, Notification, Receipt1, Setting2, Share, TicketDiscount, Whatsapp } from 'iconsax-react';
|
||||||
import TelegramIcon from '../icons/TelegramIcon';
|
import TelegramIcon from '../icons/TelegramIcon';
|
||||||
|
import Modal from '../utils/Modal';
|
||||||
|
import LogoutPrompt from '@/features/general/LogoutPrompt';
|
||||||
|
import useToggle from '@/hooks/helpers/useToggle';
|
||||||
|
|
||||||
type MenuItemType = {
|
type MenuItemType = {
|
||||||
href: string | undefined;
|
href: string | undefined;
|
||||||
@@ -49,21 +51,17 @@ 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 [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 { active: logoutModal, onToggle: onToggleLogoutModal } = useToggle();
|
||||||
const router = useRouter();
|
const { active: shareModal, onToggle: onToggleShareModal } = useToggle();
|
||||||
|
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const { name } = params;
|
const { name } = params;
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
const { t: tMenu } = useTranslation('common', {
|
const { t: tMenu } = useTranslation('common', {
|
||||||
keyPrefix: 'SideMenu'
|
keyPrefix: 'SideMenu'
|
||||||
});
|
});
|
||||||
const { t: tLogoutModal } = useTranslation('common', {
|
|
||||||
keyPrefix: 'LogoutModal'
|
|
||||||
});
|
|
||||||
const { t: tShareModal } = useTranslation('common', {
|
const { t: tShareModal } = useTranslation('common', {
|
||||||
keyPrefix: 'ShareModal'
|
keyPrefix: 'ShareModal'
|
||||||
});
|
});
|
||||||
@@ -79,29 +77,9 @@ function SideMenu({ menuState, toggleMenuState, nightModeState, togglenightModeS
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleLogoutModalVisiblity = (e?: React.MouseEvent) => {
|
|
||||||
e?.preventDefault();
|
|
||||||
e?.stopPropagation();
|
|
||||||
setLogoutModalVisible((state) => !state);
|
|
||||||
};
|
|
||||||
|
|
||||||
const toggleShareModalVisiblity = (e?: React.MouseEvent) => {
|
|
||||||
e?.preventDefault();
|
|
||||||
e?.stopPropagation();
|
|
||||||
setShareModalVisible((state) => !state);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onLogout = (e: React.MouseEvent<HTMLButtonElement> | null) => {
|
|
||||||
if (!e) return;
|
|
||||||
if (userIsAuthenticated) {
|
|
||||||
authLogout();
|
|
||||||
router.replace('/');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const hrefOnClicks = [
|
const hrefOnClicks = [
|
||||||
{ href: '?logout', handler: toggleLogoutModalVisiblity },
|
{ href: '?logout', handler: onToggleLogoutModal },
|
||||||
{ href: '?share', handler: toggleShareModalVisiblity }
|
{ href: '?share', handler: onToggleShareModal }
|
||||||
];
|
];
|
||||||
|
|
||||||
const renderMenu = () => {
|
const renderMenu = () => {
|
||||||
@@ -210,80 +188,56 @@ function SideMenu({ menuState, toggleMenuState, nightModeState, togglenightModeS
|
|||||||
className="fixed top-0 bottom-0 right-0 bg-white w-[200px] h-dvh flex flex-col z-40 overflow-clip not-xl:!rounded-s-none"
|
className="fixed top-0 bottom-0 right-0 bg-white w-[200px] h-dvh flex flex-col z-40 overflow-clip not-xl:!rounded-s-none"
|
||||||
>
|
>
|
||||||
{renderMenu()}
|
{renderMenu()}
|
||||||
|
{String(logoutModal)}
|
||||||
</motion.nav>
|
</motion.nav>
|
||||||
</BlurredOverlayContainer>
|
</BlurredOverlayContainer>
|
||||||
<nav
|
<nav
|
||||||
className="hidden fixed top-4 bottom-4 right-4 bg-white xl:w-[250px] xl:flex flex-col z-40 overflow-clip xl:rounded-4xl"
|
className="hidden fixed top-4 bottom-4 right-4 bg-white xl:w-[250px] xl:flex flex-col z-40 overflow-clip xl:rounded-4xl"
|
||||||
>
|
>
|
||||||
{renderMenu()}
|
{renderMenu()}
|
||||||
</nav>
|
</nav>
|
||||||
</aside>
|
</aside>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Logout Modal */}
|
{/* Logout Modal */}
|
||||||
<BlurredOverlayContainer visible={logoutModalVisible} onClick={toggleLogoutModalVisiblity} inDuration={100} outDuration={100} outDelay={75}>
|
<LogoutPrompt
|
||||||
<div className="absolute top-1/2 left-6 right-6 px-6">
|
visible={logoutModal}
|
||||||
<motion.div
|
onClick={onToggleLogoutModal}
|
||||||
animate={{ y: logoutModalVisible ? [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">
|
|
||||||
{tLogoutModal('Heading')}
|
|
||||||
</h2>
|
|
||||||
<p className="text-xs font-medium mt-6">
|
|
||||||
{tLogoutModal('Description')}
|
|
||||||
</p>
|
|
||||||
<div className="grid grid-cols-2 gap-5.5 mt-8">
|
|
||||||
<Button onClick={onLogout} className="text-sm font-normal">
|
|
||||||
{tLogoutModal('ButtonOk')}
|
|
||||||
</Button>
|
|
||||||
<Button onClick={toggleLogoutModalVisiblity} className="bg-disabled! text-disabled2! text-sm font-normal">
|
|
||||||
{tLogoutModal('ButtonCancel')}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</motion.div>
|
|
||||||
</div>
|
|
||||||
</BlurredOverlayContainer>
|
|
||||||
|
|
||||||
{/* Share modal */}
|
{/* Share modal */}
|
||||||
<BlurredOverlayContainer visible={shareModalVisible} onClick={toggleShareModalVisiblity} inDuration={100} outDuration={100} outDelay={75}>
|
<Modal
|
||||||
<div className="absolute top-1/2 left-6 right-6 px-6">
|
visible={shareModal}
|
||||||
<motion.div
|
onClick={onToggleShareModal}
|
||||||
animate={{ y: shareModalVisible ? [10, 0] : [0, 10] }}
|
>
|
||||||
transition={{ duration: 0.1, ease: 'easeInOut' }}
|
<h2 className="text-base font-medium">
|
||||||
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"
|
<Share className="inline-block ml-2 mb-1.5 stroke-primary" size={24} />
|
||||||
>
|
{tShareModal('Heading')}
|
||||||
<h2 className="text-base font-medium">
|
</h2>
|
||||||
<Share className="inline-block ml-2 mb-1.5 stroke-primary" size={24} />
|
<p className="text-xs font-medium mt-6">
|
||||||
{tShareModal('Heading')}
|
{tShareModal('Description')}
|
||||||
</h2>
|
</p>
|
||||||
<p className="text-xs font-medium mt-6">
|
|
||||||
{tShareModal('Description')}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<Button onClick={onLogout} className="text-sm mt-8">
|
<Button onClick={() => { }} className="text-sm mt-8">
|
||||||
<DocumentCopy className="inline-block ml-2 mb-0.5 stroke-white" size={20} />
|
<DocumentCopy className="inline-block ml-2 mb-0.5 stroke-white" size={20} />
|
||||||
<span className="font-light">{tShareModal('ButtonCopy')}</span>
|
<span className="font-light">{tShareModal('ButtonCopy')}</span>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<div className="grid grid-cols-3 gap-5.5 mt-6 px-12">
|
<div className="grid grid-cols-3 gap-5.5 mt-6 px-12">
|
||||||
<div className="place-items-center">
|
<div className="place-items-center">
|
||||||
<TelegramIcon width={24} height={24} className="mb-1.5 stroke-primary" />
|
<TelegramIcon width={24} height={24} className="mb-1.5 stroke-primary" />
|
||||||
<span className='text-xs2 font-medium'>Telegram</span>
|
<span className='text-xs2 font-medium'>Telegram</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="place-items-center">
|
<div className="place-items-center">
|
||||||
<Whatsapp size={24} className="mb-1.5 stroke-primary" />
|
<Whatsapp size={24} className="mb-1.5 stroke-primary" />
|
||||||
<span className='text-xs2 font-medium'>WhatsApp</span>
|
<span className='text-xs2 font-medium'>WhatsApp</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="place-items-center">
|
<div className="place-items-center">
|
||||||
<Instagram size={24} className="mb-1.5 stroke-primary" />
|
<Instagram size={24} className="mb-1.5 stroke-primary" />
|
||||||
<span className='text-xs2 font-medium'>Instagram</span>
|
<span className='text-xs2 font-medium'>Instagram</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</motion.div>
|
|
||||||
</div>
|
</div>
|
||||||
</BlurredOverlayContainer>
|
</Modal>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ export type BlurredOverlayContainerProps = {
|
|||||||
outDuration?: number
|
outDuration?: number
|
||||||
children: ReactNode
|
children: ReactNode
|
||||||
noBlur?: boolean
|
noBlur?: boolean
|
||||||
|
onClick?: React.MouseEventHandler | undefined
|
||||||
} & React.ComponentProps<typeof motion.div>
|
} & React.ComponentProps<typeof motion.div>
|
||||||
|
|
||||||
const BlurredOverlayContainer = ({
|
const BlurredOverlayContainer = ({
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import { motion } from 'framer-motion'
|
||||||
|
import React from 'react'
|
||||||
|
import BlurredOverlayContainer, { BlurredOverlayContainerProps } from '../overlays/BlurredOverlayContainer'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
|
||||||
|
} & BlurredOverlayContainerProps
|
||||||
|
|
||||||
|
function Modal({ visible, onClick, children, ...rest }: Props) {
|
||||||
|
return (
|
||||||
|
<BlurredOverlayContainer
|
||||||
|
visible={visible}
|
||||||
|
onClick={onClick}
|
||||||
|
inDuration={100}
|
||||||
|
outDuration={100}
|
||||||
|
outDelay={75}
|
||||||
|
{...rest}
|
||||||
|
>
|
||||||
|
<div className="absolute top-1/2 left-6 right-6 px-6">
|
||||||
|
<motion.div
|
||||||
|
animate={{ y: visible ? [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"
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</BlurredOverlayContainer>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Modal
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import { BlurredOverlayContainerProps } from '@/components/overlays/BlurredOverlayContainer'
|
||||||
|
import Modal from '@/components/utils/Modal'
|
||||||
|
import React from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { Button } from '../ui/button'
|
||||||
|
|
||||||
|
export type PromptProps = {
|
||||||
|
title?: string,
|
||||||
|
description?: string,
|
||||||
|
textConfirm?: string,
|
||||||
|
textCancel?: string,
|
||||||
|
onConfirm: React.MouseEventHandler | undefined,
|
||||||
|
onCancel: React.MouseEventHandler | undefined,
|
||||||
|
children?: React.ReactNode | null
|
||||||
|
} & Omit<BlurredOverlayContainerProps, 'children'>
|
||||||
|
|
||||||
|
function Prompt({ title, description, textConfirm, textCancel, onConfirm, onCancel, visible, onClick, children = null, ...rest }: PromptProps) {
|
||||||
|
const { t } = useTranslation('common', {
|
||||||
|
keyPrefix: 'DefaultPrompt'
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
visible={visible}
|
||||||
|
onClick={onClick}
|
||||||
|
{...rest}
|
||||||
|
>
|
||||||
|
<h2 className="text-base font-medium">
|
||||||
|
{title ?? t('Heading')}
|
||||||
|
</h2>
|
||||||
|
<p className="text-xs font-medium mt-6">
|
||||||
|
{description ?? t('Description')}
|
||||||
|
</p>
|
||||||
|
{children}
|
||||||
|
<div className="grid grid-cols-2 gap-5.5 mt-8">
|
||||||
|
<Button onClick={onConfirm} className="text-sm h-11 font-normal cursor-pointer">
|
||||||
|
{textConfirm ?? t('ButtonOk')}
|
||||||
|
</Button>
|
||||||
|
<Button onClick={onCancel} className="bg-disabled! h-11 cursor-pointer text-disabled2! active:brightness-95 hover:brightness-105 text-sm font-normal">
|
||||||
|
{textCancel ?? t('ButtonCancel')}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Prompt
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
import Prompt, { PromptProps } from '@/components/utils/Prompt'
|
||||||
|
import { useAuthStore } from '@/zustand/authStore';
|
||||||
|
import { useRouter } from 'next/navigation';
|
||||||
|
import React from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
|
|
||||||
|
function LogoutPrompt({ ...rest }: Omit<PromptProps, 'onConfirm' | 'onCancel' | 'children'>) {
|
||||||
|
const { t } = useTranslation('common', {
|
||||||
|
keyPrefix: 'LogoutModal'
|
||||||
|
});
|
||||||
|
const authLogout = useAuthStore((state) => state.logout);
|
||||||
|
const router = useRouter();
|
||||||
|
const userIsAuthenticated = useAuthStore((state) => state.isAuthenticated);
|
||||||
|
|
||||||
|
const onConfirmLogout = (e: React.MouseEvent) => {
|
||||||
|
if (!e) return;
|
||||||
|
if (userIsAuthenticated) {
|
||||||
|
authLogout();
|
||||||
|
}
|
||||||
|
router.replace('/');
|
||||||
|
};
|
||||||
|
|
||||||
|
const toggleShareModalVisiblity = (e: React.MouseEvent) => {
|
||||||
|
e?.preventDefault();
|
||||||
|
e?.stopPropagation();
|
||||||
|
console.log(e);
|
||||||
|
rest.onClick?.(e);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Prompt
|
||||||
|
title={t("Heading")}
|
||||||
|
description={t("Description")}
|
||||||
|
textConfirm={t("ButtonOk")}
|
||||||
|
textCancel={t("ButtonCancel")}
|
||||||
|
onConfirm={onConfirmLogout}
|
||||||
|
onCancel={toggleShareModalVisiblity}
|
||||||
|
{...rest}>
|
||||||
|
<></>
|
||||||
|
</Prompt>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LogoutPrompt
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { useState } from 'react'
|
||||||
|
|
||||||
|
const useToggle = () => {
|
||||||
|
const [active, setActive] = useState<boolean>(false);
|
||||||
|
|
||||||
|
const onToggle = (e?: React.MouseEvent | null) => {
|
||||||
|
if (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
}
|
||||||
|
setActive((prev) => !prev);
|
||||||
|
}
|
||||||
|
|
||||||
|
return { active, onToggle }
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useToggle
|
||||||
@@ -23,6 +23,12 @@
|
|||||||
"NavAriaLabel": "لینکهای اصلی",
|
"NavAriaLabel": "لینکهای اصلی",
|
||||||
"ControlsAriaLabel": "پایین منو"
|
"ControlsAriaLabel": "پایین منو"
|
||||||
},
|
},
|
||||||
|
"Prompt": {
|
||||||
|
"Heading": "نیازمند تایید",
|
||||||
|
"Description": "آیا ادامه میدهید؟",
|
||||||
|
"ButtonOk": "بله",
|
||||||
|
"ButtonCancel": "خیر"
|
||||||
|
},
|
||||||
"LogoutModal": {
|
"LogoutModal": {
|
||||||
"Heading": "خروج از سیستم",
|
"Heading": "خروج از سیستم",
|
||||||
"Description": "آیا میخواهید از سیستم خارج شوید؟",
|
"Description": "آیا میخواهید از سیستم خارج شوید؟",
|
||||||
|
|||||||
Reference in New Issue
Block a user