Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 51 additions & 14 deletions src/components/blur-mode/blur-mode.button.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,64 @@
import { useState } from 'react'
import { useGeneralSetting } from '@/context/general-setting.context'
import Tooltip from '../toolTip'
import { Icon } from '@/src/icons'
import { ConfirmationModal } from '../modal/confirmation-modal'
import Analytics from '@/analytics'

export function BlurModeButton() {
const { blurMode, updateSetting } = useGeneralSetting()
const [showConfirm, setShowConfirm] = useState(false)

const applyBlurMode = (value: boolean) => {
updateSetting('blurMode', value)
}

const handleBlurModeToggle = () => {
const newBlurMode = !blurMode
updateSetting('blurMode', newBlurMode)
if (!blurMode) {
setShowConfirm(true)
Analytics.event('blurModeConfirm')
} else {
applyBlurMode(false)
}
}

const handleConfirm = () => {
applyBlurMode(true)
setShowConfirm(false)
}

return (
<Tooltip content={blurMode ? 'غیرفعالسازی' : 'فعالسازی حالت مخفی'}>
<div
onClick={handleBlurModeToggle}
className="relative p-2 transition-all cursor-pointer nav-btn text-base-content/40 hover:text-base-content active:scale-90"
>
{blurMode ? (
<Icon name="outlineEye" size={15} />
) : (
<Icon name="outlineEyeSlash" size={15} />
)}
</div>
</Tooltip>
<>
<Tooltip content={blurMode ? 'غیرفعالسازی' : 'فعالسازی حالت مخفی'}>
<div
onClick={handleBlurModeToggle}
className="relative p-2 transition-all cursor-pointer nav-btn text-base-content/40 hover:text-base-content active:scale-90"
>
{blurMode ? (
<Icon name="outlineEye" size={15} />
) : (
<Icon name="outlineEyeSlash" size={15} />
)}
</div>
</Tooltip>

<ConfirmationModal
isOpen={showConfirm}
onClose={() => setShowConfirm(false)}
onConfirm={handleConfirm}
variant="primary"
title="حالت مخفی فعال میشه!"
icon={<Icon name="userSecret" />}
message={
<div>
با فعال کردن «حالت مخفی»، اطلاعات حساس، وظایف و محتوای ویجت‌ها
به‌صورت خودکار تار میشن تا اگر کسی از کنار صفحه یا پشت سرت نگاه
کرد، نتونه چیزی بخونه 🔒
</div>
}
confirmText="بریم تو حالت مخفی"
cancelText="نه فعلا"
/>
</>
)
}
66 changes: 40 additions & 26 deletions src/components/modal/confirmation-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,43 +12,54 @@ interface ConfirmationModalProps {
message?: string | ReactNode
confirmText?: ReactNode
cancelText?: string
variant?: 'danger' | 'warning' | 'info'
variant?: 'danger' | 'warning' | 'info' | 'primary'
isLoading?: boolean
icon?: ReactNode
direction?: 'rtl' | 'ltr'
}

const variantConfig = {
danger: {
icon: <Icon name="trash" size={24} />,
icon: <Icon name="trash" size={18} />,
accentBar: 'bg-error',
iconBg: 'bg-error/10',
iconColor: 'text-error',
confirmBg: 'bg-error hover:bg-error/90',
confirmText: 'text-white',
},
warning: {
icon: <Icon name="alert" size={24} />,
icon: <Icon name="alert" size={18} />,
accentBar: 'bg-warning',
iconBg: 'bg-warning/10',
iconColor: 'text-warning',
confirmBg: 'bg-warning hover:bg-warning/90',
confirmText: 'text-white',
},
info: {
icon: <Icon name="info" size={24} />,
icon: <Icon name="info" size={18} />,
accentBar: 'bg-info',
iconBg: 'bg-info/10',
iconColor: 'text-info',
confirmBg: 'bg-info/80 hover:bg-info/90',
confirmText: 'text-white',
},
primary: {
icon: <Icon name="info" size={18} />,
accentBar: 'bg-primary',
iconBg: 'bg-primary/10',
iconColor: 'text-primary',
confirmBg: 'bg-primary/80 hover:bg-primary/90',
confirmText: 'text-white',
},
}

export function ConfirmationModal({
isOpen,
onClose,
onConfirm,
title = 'تأیید عملیات',
title = 'تایید عملیات',
message = 'آیا از انجام این عملیات اطمینان دارید؟',
confirmText = 'تأیید',
confirmText = 'تایید',
cancelText = 'انصراف',
variant = 'danger',
isLoading = false,
Expand Down Expand Up @@ -78,47 +89,50 @@ export function ConfirmationModal({
direction={direction}
closeOnBackdropClick={!isLoading}
showCloseButton={!isLoading}
title={' '}
>
<div className="space-y-2 text-center">
<div className="flex justify-center">
title={
<div className="flex items-center gap-3">
<div
className={`w-16 h-16 rounded-full flex items-center justify-center ${config.iconBg}`}
className={`flex h-10 w-10 shrink-0 items-center justify-center rounded-xl ${config.iconBg}`}
>
<div className={config.iconColor}>{displayIcon}</div>
</div>
{title && (
<h3 className="text-base font-semibold text-content">{title}</h3>
)}
</div>

{title && <h3 className="text-lg font-semibold text-content">{title}</h3>}

<div className="text-sm leading-relaxed text-muted">
}
>
<div className="relative overflow-hidden">
<div className="pt-1 text-sm leading-relaxed text-muted">
{typeof message === 'string' ? <p>{message}</p> : message}
</div>

<div className="flex gap-3 pt-2">
<div className="mt-4 border-t border-base-content/10" />

<div className="flex items-center justify-end gap-2 pt-3">
<Button
onClick={handleCancel}
size="md"
disabled={isLoading}
className="bg-transparent border-none text-muted hover:text-content hover:bg-base-300/40 rounded-2xl"
>
{cancelText}
</Button>
<Button
onClick={handleConfirm}
size="md"
disabled={isLoading}
loading={isLoading}
loadingText={
<div className="flex items-center gap-1">
<IconLoading className="!mx-0 !text-white" />
<IconLoading className="mx-0! text-white!" />
<span className="text-xs">در حال انجام...</span>
</div>
}
className={`flex-1 ${config.confirmBg} ${config.confirmText} border-none rounded-2xl`}
className={`${config.confirmBg} ${config.confirmText} w-fit px-8 border-none rounded-2xl`}
>
{confirmText}
</Button>
<Button
onClick={handleCancel}
size="md"
disabled={isLoading}
className="flex-1 border border-content/20 text-content hover:bg-base-300/50 rounded-2xl"
>
{cancelText}
</Button>
</div>
</div>
</Modal>
Expand Down
5 changes: 2 additions & 3 deletions src/icons/packs/default.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import {
FaSpinner,
FaTelegramPlane,
FaUpload,
FaUserSecret,
} from 'react-icons/fa'
import {
TbCloudOff,
Expand Down Expand Up @@ -253,7 +254,5 @@ export const defaultIcons = {
simple_ui: LuLayoutTemplate,
arrowRightLeft: TbArrowsRightLeft,
bookmark: HiBookmark,
userSecret: FaUserSecret,
} satisfies IconMap



1 change: 1 addition & 0 deletions src/icons/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,5 @@ export type IconName =
| 'simple_ui'
| 'arrowRightLeft'
| 'bookmark'
| 'userSecret'
export type IconMap = Record<IconName, IconType>
12 changes: 6 additions & 6 deletions src/layouts/bookmark/bookmark-grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { validate } from 'uuid'
import { useAuth } from '@/context/auth.context'
import { AuthRequiredModal } from '@/components/auth/AuthRequiredModal'
import { showToast } from '@/common/toast'
import { Icon } from '@/src/icons'

interface BookmarkGridProps {
displayedBookmarks: Bookmark[]
Expand Down Expand Up @@ -228,15 +229,14 @@ export function BookmarkGrid({
isOpen={showDeleteConfirmationModal}
onClose={handleCancelDelete}
onConfirm={handleConfirmDelete}
title="حذف بوکمارک"
title="حذف بوکمارک؟"
message={
bookmarkToDelete?.type === 'FOLDER' ? (
<div>
<p>
آیا از حذف پوشه "{bookmarkToDelete.title}" اطمینان دارید؟
</p>
<p className="mt-2 text-xs text-error">
تمام بوکمارک‌های داخل این پوشه نیز حذف خواهند شد.
<p>آیا از حذف پوشه "{bookmarkToDelete.title}" مطمئن هستی؟</p>
<p className="flex gap-1 px-2 py-1 mt-2 text-xs rounded-xl bg-error/20 text-error">
با حذف این پوشه، تمام بوکمارک‌های داخلش هم برای همیشه حذف
میشن و این عمل قابل بازگشت نیست!
</p>
</div>
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export const UserProfile = () => {
isOpen={showConfirm}
onClose={() => setShowConfirm(false)}
onConfirm={() => onClickLogout()}
icon={<Icon name="logOut" />}
message="مطمعنی میخای از حسابت خارج بشی؟"
title="خروج از حساب کاربری"
confirmText="بله، خروج"
Expand Down
2 changes: 1 addition & 1 deletion src/layouts/widgets/habit/habits.layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ export function HabitsContent() {
onClose={() => setArchiveConfirm(null)}
onConfirm={handleConfirmArchive}
variant="danger"
title=""
title="بایگانی عادت؟"
message={`از بایگانی کردن این عادت اطمینان داری؟`}
confirmText="بله، بایگانی کن"
cancelText="انصراف"
Expand Down
3 changes: 2 additions & 1 deletion src/layouts/widgets/todos/todo.item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,9 @@ export function TodoItem({ todo, blurMode = false, onEdit, onUpdated }: Prop) {
onClose={() => setShowConfirmation(false)}
onConfirm={onConfirmDelete}
confirmText={isPending ? <IconLoading /> : 'حذف'}
message="آیا از حذف مطمئن هستید؟"
message="این عمل قابل بازگشت نیست و وظیفه برای همیشه حذف خواهد شد"
variant="danger"
title="حذف این تسک؟"
/>
)}
</div>
Expand Down
Loading