diff --git a/.github/workflows/pull.yml b/.github/workflows/pull.yml index 66b84c43..73d3d888 100644 --- a/.github/workflows/pull.yml +++ b/.github/workflows/pull.yml @@ -24,6 +24,9 @@ jobs: - name: Install dependencies run: bun install + - name: Generate WXT types + run: bunx wxt prepare + - name: Build files run: bun compile diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 5f7bfcb5..ea5557b1 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -21,6 +21,9 @@ jobs: - name: Install dependencies run: bun install + - name: Generate WXT types + run: bunx wxt prepare + - name: Build files run: bun compile diff --git a/.gitignore b/.gitignore index f9b65d12..201c15df 100644 --- a/.gitignore +++ b/.gitignore @@ -31,4 +31,5 @@ dev local_output diff.txt -docs/* \ No newline at end of file +docs/* +.claude \ No newline at end of file diff --git a/bun.lock b/bun.lock index 6a08ae6c..0c931d18 100644 --- a/bun.lock +++ b/bun.lock @@ -13,6 +13,8 @@ "axios": "1.18.0", "canvas-confetti": "1.9.4", "chart.js": "4.5.1", + "class-variance-authority": "0.7.1", + "clsx": "2.1.1", "framer-motion": "12.40.0", "jalali-moment": "3.3.11", "moment": "2.30.1", @@ -24,7 +26,7 @@ "react-chartjs-2": "5.3.1", "react-colorful": "5.7.0", "react-dom": "19.2.7", - "react-easy-crop": "^6.2.2", + "react-easy-crop": "6.2.2", "react-hot-toast": "2.6.0", "react-icons": "5.6.0", "react-joyride": "3.1.0", @@ -523,6 +525,8 @@ "citty": ["citty@0.1.6", "", { "dependencies": { "consola": "^3.2.3" } }, "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ=="], + "class-variance-authority": ["class-variance-authority@0.7.1", "", { "dependencies": { "clsx": "^2.1.1" } }, "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg=="], + "cli-boxes": ["cli-boxes@3.0.0", "", {}, "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g=="], "cli-cursor": ["cli-cursor@3.1.0", "", { "dependencies": { "restore-cursor": "^3.1.0" } }, "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw=="], @@ -539,6 +543,8 @@ "clone": ["clone@1.0.4", "", {}, "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg=="], + "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], + "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], diff --git a/package.json b/package.json index 525a8b01..26289578 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,8 @@ "axios": "1.18.0", "canvas-confetti": "1.9.4", "chart.js": "4.5.1", + "class-variance-authority": "0.7.1", + "clsx": "2.1.1", "framer-motion": "12.40.0", "jalali-moment": "3.3.11", "moment": "2.30.1", diff --git a/src/common/utils/cn.ts b/src/common/utils/cn.ts new file mode 100644 index 00000000..224a5a82 --- /dev/null +++ b/src/common/utils/cn.ts @@ -0,0 +1,36 @@ +import { type ClassValue, clsx } from 'clsx' +import { extendTailwindMerge } from 'tailwind-merge' + +const twMerge = extendTailwindMerge<'wg-backdrop'>({ + extend: { + classGroups: { + 'wg-backdrop': ['bg-glass'], + + 'bg-color': ['bg-widget', 'bg-content', 'bg-raised'], + 'text-color': ['text-strong', 'text-content', 'text-muted', 'text-subtle'], + 'border-color': ['border-content', 'border-strong'], + + rounded: ['rounded-widget', 'rounded-card'], + shadow: ['elevation-sm', 'elevation', 'elevation-lg'], + transition: ['transition-ui'], + 'outline-style': ['focus-ring'], + z: [ + 'z-base', + 'z-raised', + 'z-sticky', + 'z-drag', + 'z-nav', + 'z-backdrop', + 'z-sheet', + 'z-modal', + 'z-popover', + 'z-toast', + 'z-pet', + ], + }, + }, +}) + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)) +} diff --git a/src/common/utils/translate-error.ts b/src/common/utils/translate-error.ts index bf3e176c..f1ed6776 100644 --- a/src/common/utils/translate-error.ts +++ b/src/common/utils/translate-error.ts @@ -114,6 +114,7 @@ const errorTranslations: Record = { FOLDER_STRUCTURE_TOO_DEEP: 'FOLDER_STRUCTURE_TOO_DEEP', BULK_IMPORT_LIMIT_EXCEEDED: `تعداد آیتم درون‌ریزی بیش‌از حد هست`, NO_VALID_ITEMS_TO_IMPORT: 'هیچ آیتم معتبری برای درون‌ریزی وجود نداره', + BIRTHDATE_CANNOT_BE_CHANGED: 'به تازگی تاریخ تولدت رو عوض کردی!', } const validationTranslations: Record = { diff --git a/src/components/auth/auth-required-modal.tsx b/src/components/auth/auth-required-modal.tsx index fbeced95..93c28766 100644 --- a/src/components/auth/auth-required-modal.tsx +++ b/src/components/auth/auth-required-modal.tsx @@ -1,6 +1,6 @@ import { callEvent } from '@/common/utils/call-event' -import Modal from '@/components/modal' -import { Button } from '../button/button' +import { Modal } from '@/components/ui' +import { Button } from '@/components/ui' import { Icon } from '@/src/icons' interface AuthRequiredModalProps { @@ -35,7 +35,7 @@ export function AuthRequiredModal({ closeOnBackdropClick={true} >
-
+
{loginButtonText} @@ -60,7 +60,8 @@ export function AuthRequiredModal({ diff --git a/src/components/auth/require-auth.tsx b/src/components/auth/require-auth.tsx index 20b0b95f..e43ce02d 100644 --- a/src/components/auth/require-auth.tsx +++ b/src/components/auth/require-auth.tsx @@ -2,7 +2,7 @@ import { Motion as motion } from '@/common/motion' import type { ReactNode } from 'react' import { callEvent } from '@/common/utils/call-event' import { useAuth } from '@/context/auth.context' -import { Button } from '../button/button' +import { Button } from '@/components/ui' interface RequireAuthProps { children: ReactNode @@ -49,8 +49,8 @@ export const RequireAuth = ({ children, fallback, mode = 'block' }: RequireAuthP @@ -76,8 +76,8 @@ export const RequireAuth = ({ children, fallback, mode = 'block' }: RequireAuthP diff --git a/src/components/auth/require-verification.tsx b/src/components/auth/require-verification.tsx index 2aae3ca1..8908fc0d 100644 --- a/src/components/auth/require-verification.tsx +++ b/src/components/auth/require-verification.tsx @@ -2,7 +2,7 @@ import { Motion as motion } from '@/common/motion' import type { ReactNode } from 'react' import { callEvent } from '@/common/utils/call-event' import { useAuth } from '@/context/auth.context' -import { Button } from '../button/button' +import { Button } from '@/components/ui' import { Icon } from '@/src/icons' interface RequireVerificationProps { diff --git a/src/components/badges/new.badge.tsx b/src/components/badges/new.badge.tsx deleted file mode 100644 index 7ff24ffa..00000000 --- a/src/components/badges/new.badge.tsx +++ /dev/null @@ -1,10 +0,0 @@ -interface Prop { - className: string -} -export function NewBadge({ className }: Prop) { - return ( - - ) -} diff --git a/src/components/blur-mode/blur-mode.button.tsx b/src/components/blur-mode/blur-mode.button.tsx index d31a4522..e8bd33da 100644 --- a/src/components/blur-mode/blur-mode.button.tsx +++ b/src/components/blur-mode/blur-mode.button.tsx @@ -1,8 +1,8 @@ import { useState } from 'react' import { useGeneralSetting } from '@/context/general-setting.context' -import Tooltip from '../tool-tip' +import { Tooltip } from '@/components/ui' import { Icon } from '@/src/icons' -import { ConfirmationModal } from '../modal/confirmation-modal' +import { ConfirmationModal } from '@/components/ui' import Analytics from '@/analytics' export function BlurModeButton() { diff --git a/src/components/button/button.tsx b/src/components/button/button.tsx deleted file mode 100644 index 5ac12d5d..00000000 --- a/src/components/button/button.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { Icon } from '@/src/icons' -import type React from 'react' - -interface ButtonProps { - onClick?: () => void - disabled?: boolean - className?: string - style?: React.CSSProperties - icon?: React.ReactNode - loading?: boolean - loadingText?: React.ReactNode - type?: 'button' | 'submit' | 'reset' - fullWidth?: boolean - rounded?: 'sm' | 'md' | 'lg' | 'xl' | 'full' - children?: React.ReactNode - isPrimary?: boolean - size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' - ref?: any -} -export function Button(prop: ButtonProps) { - const sizes: Record = { - xs: 'btn-xs', - sm: 'btn-sm', - md: 'btn-md', - lg: 'btn-lg', - xl: 'btn-xl', - } - - return ( - - ) -} diff --git a/src/components/chip.component.tsx b/src/components/chip.component.tsx deleted file mode 100644 index 461076ce..00000000 --- a/src/components/chip.component.tsx +++ /dev/null @@ -1,25 +0,0 @@ -interface ChipProps { - selected: boolean - onClick: () => void - children: React.ReactNode - className?: string - dir?: string -} - -export const Chip: React.FC = ({ - selected, - onClick, - children, - className = '', - dir, -}) => { - return ( - - ) -} diff --git a/src/components/date-picker/index.ts b/src/components/date-picker/index.ts deleted file mode 100644 index 6bc7ab0d..00000000 --- a/src/components/date-picker/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { DatePicker } from './date-picker' diff --git a/src/components/dropdown/index.ts b/src/components/dropdown/index.ts deleted file mode 100644 index 90f5fb6a..00000000 --- a/src/components/dropdown/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export type { DropdownOption, DropdownProps } from './dropdown' -export { Dropdown } from './dropdown' diff --git a/src/components/extension-installed-modal.tsx b/src/components/extension-installed-modal.tsx index cd89e9e6..106521f0 100644 --- a/src/components/extension-installed-modal.tsx +++ b/src/components/extension-installed-modal.tsx @@ -1,8 +1,8 @@ import { useState } from 'react' import keepItImage from '@/assets/images/keep-it.png' -import { Button } from './button/button' -import Checkbox from './checkbox' -import Modal from './modal' +import { Button } from './ui' +import { Checkbox } from '@/components/ui' +import { Modal } from '@/components/ui' import { Icon } from '../icons' interface ExtensionInstalledModalProps { @@ -72,7 +72,7 @@ const StepOne = ({ onGetStarted }: StepOneProps) => { size="md" onClick={onGetStarted} className="w-full text-base font-light shadow-sm rounded-2xl shadow-primary outline-none!" - isPrimary={true} + variant="primary" > شروع کنید @@ -158,14 +158,16 @@ const StepFirefoxConsent = ({ onGetStarted }: StepFirefoxConsentProps) => { diff --git a/src/components/filter-tooltip/index.ts b/src/components/filter-tooltip/index.ts deleted file mode 100644 index 27d286d1..00000000 --- a/src/components/filter-tooltip/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export { - FilterTooltip, - type FilterOption, - type FilterTooltipProps, -} from './filter-tooltip' diff --git a/src/components/loading/icon-loading.tsx b/src/components/loading/icon-loading.tsx deleted file mode 100644 index 3f885630..00000000 --- a/src/components/loading/icon-loading.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { Icon } from '@/src/icons' -import Tooltip from '../tool-tip' - -interface IconLoadingProps { - title?: string - className?: string -} -export function IconLoading({ title, className }: IconLoadingProps) { - if (!title) { - return ( - - ) - } - return ( - - - - ) -} diff --git a/src/components/pagination/index.ts b/src/components/pagination/index.ts deleted file mode 100644 index 93a761b4..00000000 --- a/src/components/pagination/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export type { PaginationProps } from './pagination' -export { Pagination } from './pagination' diff --git a/src/components/section-panel.tsx b/src/components/section-panel.tsx deleted file mode 100644 index eb6e6e57..00000000 --- a/src/components/section-panel.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import type { ReactNode } from 'react' -import React from 'react' - -interface SectionPanelProps { - title: ReactNode - children: ReactNode - delay?: number - size?: 'xs' | 'sm' | 'md' | 'lg' - icon?: React.ReactElement -} - -export function SectionPanel({ title, children, size = 'md', icon }: SectionPanelProps) { - const getSizeStyles = () => { - switch (size) { - case 'xs': - return { - container: 'rounded-sm', - header: 'p-1', - title: 'text-sm', - content: 'p-1', - } - case 'sm': - return { - container: 'rounded-lg', - header: 'p-3', - title: 'text-base', - content: 'p-3', - } - case 'lg': - return { - container: 'rounded-xl', - header: 'p-5', - title: 'text-xl', - content: 'p-5', - } - default: // md - return { - container: 'rounded-xl', - header: 'p-4', - title: 'text-lg', - content: 'p-4', - } - } - } - const sizeStyles = getSizeStyles() - - return ( -
-
-
- {icon && React.cloneElement(icon, {})} -

- {title} -

-
-
-
{children}
-
- ) -} diff --git a/src/components/text-input.tsx b/src/components/text-input.tsx index 93f230ee..b71e3848 100644 --- a/src/components/text-input.tsx +++ b/src/components/text-input.tsx @@ -39,6 +39,13 @@ const sizes: Record = { [TextInputSize.XL]: 'input-xl', } +/** + * @deprecated Use `import { TextInput } from '@/components/ui'`. + * + * The replacement is source-compatible (no call site passes `size`, and the + * unexported `TextInputSize` enum is now a string union), so migration is a + * pure import swap — done in batches so each screen gets looked at. + */ export const TextInput = memo(function TextInput({ onChange, value, diff --git a/src/components/toggle-switch.component.tsx b/src/components/toggle-switch.component.tsx deleted file mode 100644 index 93a9ec7c..00000000 --- a/src/components/toggle-switch.component.tsx +++ /dev/null @@ -1,38 +0,0 @@ -interface ToggleSwitchProps { - enabled: boolean - disabled?: boolean - loading?: boolean - onToggle: () => void -} - -export const ToggleSwitch = ({ - enabled, - disabled = false, - loading = false, - onToggle, -}: ToggleSwitchProps) => { - const getTrackStyle = () => { - if (enabled) { - return 'bg-primary' - } - - return 'bg-base-300' - } - - return ( -
- -
- ) -} diff --git a/src/components/avatar.component.tsx b/src/components/ui/avatar/avatar.tsx similarity index 70% rename from src/components/avatar.component.tsx rename to src/components/ui/avatar/avatar.tsx index e5c33098..056366f3 100644 --- a/src/components/avatar.component.tsx +++ b/src/components/ui/avatar/avatar.tsx @@ -1,26 +1,22 @@ +import type { VariantProps } from 'class-variance-authority' import { useEffect, useState } from 'react' +import { cn } from '@/common/utils/cn' +import { avatarVariants } from './avatar.variants' -interface AvatarProps { +export interface AvatarProps extends VariantProps { url?: string | null file?: File | null placeholder?: string - size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' className?: string onClick?: () => void } -const sizeClasses = { - xs: 'w-6 h-6 text-xs', - sm: 'w-8 h-8 text-sm', - md: 'w-10 h-10 text-base', - lg: 'w-12 h-12 text-lg', - xl: 'w-16 h-16 text-xl', -} + export function AvatarComponent({ url, file, placeholder = '', - size = 'md', - className = '', + size, + className, onClick, }: AvatarProps) { const [imageError, setImageError] = useState(false) @@ -52,10 +48,7 @@ export function AvatarComponent({ const shouldShowImage = displayUrl && !imageError return ( -
+
{shouldShowImage ? ( ) : ( -
+
{placeholder.charAt(0)?.toUpperCase() || '?'}
)} diff --git a/src/components/ui/avatar/avatar.variants.ts b/src/components/ui/avatar/avatar.variants.ts new file mode 100644 index 00000000..62a31ffa --- /dev/null +++ b/src/components/ui/avatar/avatar.variants.ts @@ -0,0 +1,21 @@ +import { cva } from 'class-variance-authority' + +export const avatarVariants = cva( + ['rounded-full', 'overflow-hidden', 'flex', 'items-center', 'justify-center'], + { + variants: { + size: { + xs: ['w-6', 'h-6', 'text-xs'], + sm: ['w-8', 'h-8', 'text-sm'], + md: ['w-10', 'h-10', 'text-base'], + lg: ['w-12', 'h-12', 'text-lg'], + xl: ['w-16', 'h-16', 'text-xl'], + }, + }, + defaultVariants: { + size: 'md', + }, + } +) + +export type AvatarVariant = typeof avatarVariants diff --git a/src/components/ui/badge/badge.tsx b/src/components/ui/badge/badge.tsx new file mode 100644 index 00000000..bc1bfa41 --- /dev/null +++ b/src/components/ui/badge/badge.tsx @@ -0,0 +1,14 @@ +import { twMerge } from 'tailwind-merge' +interface Prop { + className: string +} +export function NewBadge({ className }: Prop) { + return ( + + ) +} diff --git a/src/components/bottom-sheet/bottom-sheet.tsx b/src/components/ui/bottom-sheet/bottom-sheet.tsx similarity index 100% rename from src/components/bottom-sheet/bottom-sheet.tsx rename to src/components/ui/bottom-sheet/bottom-sheet.tsx diff --git a/src/components/ui/button/button.tsx b/src/components/ui/button/button.tsx new file mode 100644 index 00000000..8143cd73 --- /dev/null +++ b/src/components/ui/button/button.tsx @@ -0,0 +1,56 @@ +import type React from 'react' +import { cn } from '@/common/utils/cn' +import { Icon } from '@/src/icons' +import { type ButtonVariantProps, buttonVariants } from './button.variants' + +export interface ButtonProps + extends Omit, 'color'>, + ButtonVariantProps { + loading?: boolean + loadingText?: React.ReactNode + icon?: React.ReactNode + /** @deprecated Use `variant="primary"` instead. */ + isPrimary?: boolean +} + +export function Button({ + className, + variant, + size, + rounded, + fullWidth, + isPrimary, + loading, + loadingText, + icon, + type = 'button', + children, + ...rest +}: ButtonProps) { + const resolvedVariant = variant ?? (isPrimary ? 'primary' : 'default') + + return ( + + ) +} diff --git a/src/components/ui/button/button.variants.ts b/src/components/ui/button/button.variants.ts new file mode 100644 index 00000000..95f0e4c0 --- /dev/null +++ b/src/components/ui/button/button.variants.ts @@ -0,0 +1,56 @@ +import { cva, type VariantProps } from 'class-variance-authority' + +export const buttonVariants = cva( + [ + 'inline-flex shrink-0 items-center justify-center gap-1.5', + 'whitespace-nowrap align-middle select-none cursor-pointer', + 'border font-semibold', + 'transition-ui', + 'focus-visible:focus-ring', + 'disabled:pointer-events-none disabled:opacity-50', + ], + { + variants: { + variant: { + default: + 'bg-content text-content border-content hover:bg-base-content/5!', + primary: 'bg-primary text-white border-transparent hover:bg-primary/90', + secondary: + 'bg-secondary text-secondary-content border-transparent hover:bg-secondary/90', + outline: 'bg-transparent text-content border-content hover:bg-raised', + ghost: 'bg-transparent text-muted border-transparent hover:bg-raised hover:text-content', + danger: 'bg-error text-error-content border-transparent hover:bg-error/90', + success: + 'bg-success text-success-content border-transparent hover:bg-success/90', + }, + size: { + xs: 'h-6 px-2 text-[0.6875rem]', + sm: 'h-8 px-3 text-xs', + md: 'h-10 px-4 text-sm', + lg: 'h-12 px-5 text-lg', + xl: 'h-14 px-6 text-[1.375rem]', + }, + rounded: { + sm: 'rounded-sm', + md: 'rounded-md', + lg: 'rounded-lg', + xl: 'rounded-xl', + '2xl': 'rounded-2xl', + full: 'rounded-full', + card: 'rounded-card', + }, + fullWidth: { + true: 'w-full', + false: '', + }, + }, + defaultVariants: { + variant: 'default', + size: 'md', + rounded: 'card', + fullWidth: false, + }, + } +) + +export type ButtonVariantProps = VariantProps diff --git a/src/components/checkbox-description.component.tsx b/src/components/ui/checkbox/checkbox-description.tsx similarity index 90% rename from src/components/checkbox-description.component.tsx rename to src/components/ui/checkbox/checkbox-description.tsx index d293b1b9..b4202268 100644 --- a/src/components/checkbox-description.component.tsx +++ b/src/components/ui/checkbox/checkbox-description.tsx @@ -1,4 +1,4 @@ -import CustomCheckbox from '@/components/checkbox' +import { Checkbox } from '@/components/ui' interface Props { isEnabled: boolean @@ -20,7 +20,7 @@ export function CheckBoxWithDescription({ } onClick={onToggle} > - { if (checked) { if (checkedCheckBoxClassName) return checkedCheckBoxClassName - return 'bg-blue-500 border-blue-500' + return 'bg-primary border-primary' } if (unCheckedCheckBoxClassName) return unCheckedCheckBoxClassName @@ -90,4 +90,6 @@ const CustomCheckbox = ({ ) } -export default memo(CustomCheckbox) +export const Checkbox = memo(CheckboxBase) + +Checkbox.displayName = 'Checkbox' diff --git a/src/components/ui/chip/chip.tsx b/src/components/ui/chip/chip.tsx new file mode 100644 index 00000000..0dca9ba2 --- /dev/null +++ b/src/components/ui/chip/chip.tsx @@ -0,0 +1,28 @@ +import type { VariantProps } from 'class-variance-authority' +import { cn } from '@/common/utils/cn' +import { chipVariants } from './chip.variants' + +export interface ChipProps extends VariantProps { + onClick: () => void + children: React.ReactNode + className?: string + dir?: string +} + +export const Chip: React.FC = ({ + selected, + onClick, + children, + className, + dir, +}) => { + return ( + + ) +} diff --git a/src/components/ui/chip/chip.variants.ts b/src/components/ui/chip/chip.variants.ts new file mode 100644 index 00000000..ba02b2d3 --- /dev/null +++ b/src/components/ui/chip/chip.variants.ts @@ -0,0 +1,33 @@ +import { cva } from 'class-variance-authority' + +export const chipVariants = cva( + [ + 'px-4', + 'py-2', + 'cursor-pointer', + 'rounded-full', + 'text-xs', + 'font-bold', + 'border-2', + 'transition-all', + 'active:scale-95', + ], + { + variants: { + selected: { + true: ['bg-primary', 'border-primary', 'text-white'], + false: [ + 'bg-base-100', + 'border-base-300/30', + 'text-base-content/80', + 'hover:border-primary/30', + ], + }, + }, + defaultVariants: { + selected: false, + }, + } +) + +export type ChipVariant = typeof chipVariants diff --git a/src/components/popover-color-picker.tsx b/src/components/ui/color-picker/color-picker.tsx similarity index 92% rename from src/components/popover-color-picker.tsx rename to src/components/ui/color-picker/color-picker.tsx index 164d6a80..efa62463 100644 --- a/src/components/popover-color-picker.tsx +++ b/src/components/ui/color-picker/color-picker.tsx @@ -7,7 +7,7 @@ interface PopoverColorPickerProps { onChange: (color: string) => void } -const PopoverColorPicker: React.FC = ({ color, onChange }) => { +export const ColorPicker: React.FC = ({ color, onChange }) => { const triggerRef = useRef(null) const popoverRef = useRef(null) const [isOpen, setIsOpen] = useState(false) @@ -71,7 +71,7 @@ const PopoverColorPicker: React.FC = ({ color, onChange createPortal(
= ({ color, onChange ) } - -export default PopoverColorPicker diff --git a/src/components/context-menu.component.tsx b/src/components/ui/context-menu/context-menu.tsx similarity index 79% rename from src/components/context-menu.component.tsx rename to src/components/ui/context-menu/context-menu.tsx index 45f4fc42..d8f90694 100644 --- a/src/components/context-menu.component.tsx +++ b/src/components/ui/context-menu/context-menu.tsx @@ -1,4 +1,5 @@ import { useEffect, useRef } from 'react' +import { cn } from '@/common/utils/cn' interface ContextMenuProps { className?: string @@ -32,11 +33,13 @@ export function ContextMenu({ return (
{children} diff --git a/src/components/date-picker/date-picker.tsx b/src/components/ui/date-picker/date-picker.tsx similarity index 97% rename from src/components/date-picker/date-picker.tsx rename to src/components/ui/date-picker/date-picker.tsx index ce556a90..f3cb33e5 100644 --- a/src/components/date-picker/date-picker.tsx +++ b/src/components/ui/date-picker/date-picker.tsx @@ -1,3 +1,4 @@ +import { twMerge } from 'tailwind-merge' import { Icon } from '@/src/icons' import jalaliMoment from 'jalali-moment' import { useState } from 'react' @@ -134,7 +135,7 @@ export function DatePicker({ if (isDaySelected) return '' if (isFriday) { - return 'hover:bg-red-400/10' + return 'hover:bg-error/10' } return 'hover:bg-primary/10' @@ -189,7 +190,10 @@ export function DatePicker({ return (

diff --git a/src/components/dropdown/dropdown.tsx b/src/components/ui/dropdown/dropdown.tsx similarity index 93% rename from src/components/dropdown/dropdown.tsx rename to src/components/ui/dropdown/dropdown.tsx index 735c1e5e..99f7f733 100644 --- a/src/components/dropdown/dropdown.tsx +++ b/src/components/ui/dropdown/dropdown.tsx @@ -1,3 +1,4 @@ +import { twMerge } from 'tailwind-merge' import type { ReactNode } from 'react' import { Portal } from '../portal/portal' import { useDropdown } from './use-dropdown' @@ -198,7 +199,7 @@ export function Dropdown({ ) return ( -
+
-
+
void + placeholder?: string + onFocus?: () => void + onKeyDown?: (e: React.KeyboardEvent) => void + disabled?: boolean + name?: string + type?: string + direction?: 'rtl' | 'ltr' | 'auto' + className?: string + ref?: React.RefObject + debounce?: boolean + debounceTime?: number + maxLength?: number + size?: TextInputSize + invalid?: boolean + min?: number + max?: number + autoComplete?: 'on' | 'off' +} + +export const TextInput = memo(function TextInput({ + onChange, + value, + defaultValue, + placeholder, + onFocus, + onKeyDown, + disabled = false, + name, + id, + type = 'text', + direction, + className, + ref, + debounce = false, + debounceTime = 150, + maxLength = 1000, + size = 'md', + invalid = false, + min, + max, + autoComplete = 'off', +}: TextInputProps) { + const debounceTimerRef = useRef(null) + const isControlled = value !== undefined + + const handleChange = useCallback( + (e: React.ChangeEvent) => { + const newValue = e.target.value + + if (!debounce) { + onChange(newValue) + return + } + + if (debounceTimerRef.current) { + clearTimeout(debounceTimerRef.current) + } + + debounceTimerRef.current = setTimeout( + () => { + onChange(newValue) + }, + type === 'color' ? 50 : debounceTime + ) + }, + [onChange, debounce, type, debounceTime] + ) + + useEffect(() => { + return () => { + if (debounceTimerRef.current) { + clearTimeout(debounceTimerRef.current) + } + } + }, []) + + const inputProps = { + ref, + id, + type, + name, + disabled, + onFocus, + onKeyDown, + dir: direction, + placeholder: placeholder || '', + className: cn(textInputVariants({ size, invalid }), className), + onChange: handleChange, + maxLength, + autoComplete, + min, + max, + } + + if (isControlled) { + return + } + + return +}) + +TextInput.displayName = 'TextInput' diff --git a/src/components/ui/input/input.variants.ts b/src/components/ui/input/input.variants.ts new file mode 100644 index 00000000..4989d91a --- /dev/null +++ b/src/components/ui/input/input.variants.ts @@ -0,0 +1,44 @@ +import { cva, type VariantProps } from 'class-variance-authority' + +export const textInputVariants = cva( + [ + 'w-full inline-flex items-center', + 'bg-content text-content', + 'border border-content rounded-xl', + 'font-light', + 'transition-ui', + 'placeholder:text-subtle', + 'outline-none focus:outline-none', + 'focus:border-primary focus:ring-1 focus:ring-primary/20', + 'disabled:cursor-not-allowed disabled:opacity-50', + ], + { + variants: { + size: { + xs: 'h-6 px-2 text-[0.6875rem]', + sm: 'h-8 px-3 text-xs', + md: 'h-10 px-3 text-sm', + lg: 'h-12 px-4 text-lg', + xl: 'h-14 px-4 text-[1.375rem]', + }, + invalid: { + true: 'border-error focus:border-error focus:ring-error/20', + false: '', + }, + }, + defaultVariants: { + size: 'md', + invalid: false, + }, + } +) + +export type TextInputVariantProps = VariantProps + +/** + * Replaces the old `TextInputSize` enum, which was never exported (so it could + * not be part of the public API) and which no call site passed. A string union + * is a pure widening — `size="sm"` becomes newly legal, nothing breaks — and it + * avoids shipping an enum's runtime object. + */ +export type TextInputSize = NonNullable diff --git a/src/components/item-selector.tsx b/src/components/ui/item-selector/item-selector.tsx similarity index 89% rename from src/components/item-selector.tsx rename to src/components/ui/item-selector/item-selector.tsx index 0639a91f..6621e046 100644 --- a/src/components/item-selector.tsx +++ b/src/components/ui/item-selector/item-selector.tsx @@ -1,4 +1,5 @@ import type React from 'react' +import { cn } from '@/common/utils/cn' interface Props { isActive: boolean @@ -27,11 +28,13 @@ export function ItemSelector({ return (
diff --git a/src/components/ui/loading/loading.tsx b/src/components/ui/loading/loading.tsx new file mode 100644 index 00000000..8d018d66 --- /dev/null +++ b/src/components/ui/loading/loading.tsx @@ -0,0 +1,25 @@ +import { cn } from '@/common/utils/cn' +import { Icon } from '@/src/icons' +import { Tooltip } from '../tooltip/tooltip' + +interface IconLoadingProps { + title?: string + className?: string +} + +export function IconLoading({ title, className }: IconLoadingProps) { + const icon = ( + + ) + + if (!title) return icon + + return ( + + {icon} + + ) +} diff --git a/src/components/modal/confirmation-modal.tsx b/src/components/ui/modal/confirmation-modal.tsx similarity index 63% rename from src/components/modal/confirmation-modal.tsx rename to src/components/ui/modal/confirmation-modal.tsx index 2dcb2b7f..e604343c 100644 --- a/src/components/modal/confirmation-modal.tsx +++ b/src/components/ui/modal/confirmation-modal.tsx @@ -1,8 +1,13 @@ import type { ReactNode } from 'react' import { Button } from '../button/button' -import Modal from '../modal' -import { IconLoading } from '../loading/icon-loading' +import { Modal } from './modal' +import { IconLoading } from '../loading/loading' import { Icon } from '@/src/icons' +import { cn } from '@/common/utils/cn' +import { + confirmationConfirmButtonVariants, + confirmationIconVariants, +} from './confirmation-modal.variants' interface ConfirmationModalProps { isOpen: boolean @@ -18,39 +23,11 @@ interface ConfirmationModalProps { direction?: 'rtl' | 'ltr' } -const variantConfig = { - danger: { - icon: , - accentBar: 'bg-error', - iconBg: 'bg-error/10', - iconColor: 'text-error', - confirmBg: 'bg-error hover:bg-error/90', - confirmText: 'text-white', - }, - warning: { - icon: , - accentBar: 'bg-warning', - iconBg: 'bg-warning/10', - iconColor: 'text-warning', - confirmBg: 'bg-warning hover:bg-warning/90', - confirmText: 'text-white', - }, - info: { - icon: , - accentBar: 'bg-info', - iconBg: 'bg-info/10', - iconColor: 'text-info', - confirmBg: 'bg-info/80 hover:bg-info/90', - confirmText: 'text-white', - }, - primary: { - icon: , - accentBar: 'bg-primary', - iconBg: 'bg-primary/10', - iconColor: 'text-primary', - confirmBg: 'bg-primary/80 hover:bg-primary/90', - confirmText: 'text-white', - }, +const variantIcon = { + danger: , + warning: , + info: , + primary: , } export function ConfirmationModal({ @@ -66,8 +43,7 @@ export function ConfirmationModal({ icon, direction = 'rtl', }: ConfirmationModalProps) { - const config = variantConfig[variant] - const displayIcon = icon || config.icon + const displayIcon = icon || variantIcon[variant] const handleConfirm = () => { if (!isLoading) { @@ -92,9 +68,12 @@ export function ConfirmationModal({ title={
-
{displayIcon}
+
{displayIcon}
{title && (

{title}

@@ -129,7 +108,10 @@ export function ConfirmationModal({ در حال انجام...
} - className={`${config.confirmBg} ${config.confirmText} w-fit px-8 border-none rounded-2xl`} + className={cn( + confirmationConfirmButtonVariants({ variant }), + 'w-fit px-8 border-none rounded-2xl' + )} > {confirmText} diff --git a/src/components/ui/modal/confirmation-modal.variants.ts b/src/components/ui/modal/confirmation-modal.variants.ts new file mode 100644 index 00000000..d473dc7f --- /dev/null +++ b/src/components/ui/modal/confirmation-modal.variants.ts @@ -0,0 +1,42 @@ +import { cva } from 'class-variance-authority' + +export const confirmationAccentBarVariants = cva(['h-1', 'w-full'], { + variants: { + variant: { + danger: ['bg-error'], + warning: ['bg-warning'], + info: ['bg-info'], + primary: ['bg-primary'], + }, + }, + defaultVariants: { variant: 'danger' }, +}) + +export const confirmationIconVariants = cva( + ['flex', 'items-center', 'justify-center', 'rounded-full'], + { + variants: { + variant: { + danger: ['bg-error/10', 'text-error'], + warning: ['bg-warning/10', 'text-warning'], + info: ['bg-info/10', 'text-info'], + primary: ['bg-primary/10', 'text-primary'], + }, + }, + defaultVariants: { variant: 'danger' }, + } +) + +export const confirmationConfirmButtonVariants = cva([], { + variants: { + variant: { + danger: ['bg-error', 'hover:bg-error/90!', 'text-error-content'], + warning: ['bg-warning', 'hover:bg-warning/90!', 'text-warning-content'], + info: ['bg-info/80', 'hover:bg-info/90!', 'text-info-content'], + primary: ['bg-primary/80', 'hover:bg-primary/90!', 'text-white'], + }, + }, + defaultVariants: { variant: 'danger' }, +}) + +export type ConfirmationVariant = typeof confirmationAccentBarVariants diff --git a/src/components/modal.tsx b/src/components/ui/modal/modal.tsx similarity index 68% rename from src/components/modal.tsx rename to src/components/ui/modal/modal.tsx index f328805b..8c9563ed 100644 --- a/src/components/modal.tsx +++ b/src/components/ui/modal/modal.tsx @@ -1,12 +1,14 @@ +import type { VariantProps } from 'class-variance-authority' import React, { type ReactNode, useEffect, useRef } from 'react' import { createPortal } from 'react-dom' -import { Icon } from '../icons' +import { cn } from '@/common/utils/cn' +import { Icon } from '@/src/icons' +import { modalBoxVariants, modalScrollVariants } from './modal.variants' -type ModalProps = { +export type ModalProps = VariantProps & { isOpen: boolean onClose: () => void title?: React.ReactNode - size?: 'sm' | 'md' | 'lg' | 'xl' | 'full' children: ReactNode direction?: 'rtl' | 'ltr' closeOnBackdropClick?: boolean @@ -14,47 +16,18 @@ type ModalProps = { className?: string } -const sizeClasses = { - sm: { - w: 'w-[calc(100vw-2rem)] max-w-sm', - h: 'max-h-[calc(100vh-4rem)] md:max-h-[560px]', - minH: 'min-h-[180px]', - }, - md: { - w: 'w-[calc(100vw-2rem)] max-w-md', - h: 'max-h-[calc(100vh-4rem)] md:max-h-[640px]', - minH: 'min-h-[200px]', - }, - lg: { - w: 'w-[calc(100vw-2rem)] max-w-lg', - h: 'max-h-[calc(100vh-4rem)] md:max-h-[720px]', - minH: 'min-h-[240px]', - }, - xl: { - w: 'w-[calc(100vw-2rem)] max-w-4xl', - h: 'max-h-[calc(100vh-4rem)] md:max-h-[800px]', - minH: 'min-h-[280px]', - }, - full: { - w: 'w-[calc(100vw-1rem)] max-w-5xl', - h: 'h-[calc(100vh-4rem)] md:h-[calc(100vh-6rem)]', - minH: 'min-h-[calc(100vh-4rem)]', - }, -} as const - -export default function Modal({ +export function Modal({ isOpen, onClose, title, - size = 'md', + size, children, closeOnBackdropClick = true, direction = 'ltr', showCloseButton = true, - className = '', + className, }: ModalProps) { const modalRef = useRef(null) - const sizeValue = sizeClasses[size] || sizeClasses.md // Lock body scroll when modal is open useEffect(() => { @@ -97,10 +70,7 @@ export default function Modal({ } }, [isOpen]) - const modalBoxClasses = ` - modal-box overflow-hidden rounded-xl md:rounded-2xl p-3 md:p-4 shadow-xl transition-all duration-200 - ${sizeValue.w} ${sizeValue.minH} ${size === 'full' ? sizeValue.h : ''} ${className} - ` + const modalBoxClasses = cn(modalBoxVariants({ size }), className) if (!isOpen) return null @@ -116,7 +86,7 @@ export default function Modal({
e.stopPropagation()} - className={`${modalBoxClasses} animate-modal-in`} + className={cn(modalBoxClasses, 'animate-modal-in')} > {(title || showCloseButton) && (
@@ -145,11 +115,7 @@ export default function Modal({ )}
)} -
- {children} -
+
{children}
, document.body diff --git a/src/components/ui/modal/modal.variants.ts b/src/components/ui/modal/modal.variants.ts new file mode 100644 index 00000000..f45d5d6e --- /dev/null +++ b/src/components/ui/modal/modal.variants.ts @@ -0,0 +1,60 @@ +import { cva } from 'class-variance-authority' + +export const modalBoxVariants = cva( + [ + 'modal-box', + 'overflow-hidden', + 'rounded-widget', + 'p-3', + 'md:p-4', + 'elevation-lg', + 'transition-all', + 'duration-200', + ], + { + variants: { + size: { + sm: ['w-[calc(100vw-2rem)]', 'max-w-sm', 'min-h-[180px]'], + md: ['w-[calc(100vw-2rem)]', 'max-w-md', 'min-h-[200px]'], + lg: ['w-[calc(100vw-2rem)]', 'max-w-lg', 'min-h-[240px]'], + xl: ['w-[calc(100vw-2rem)]', 'max-w-4xl', 'min-h-[280px]'], + full: [ + 'w-[calc(100vw-1rem)]', + 'max-w-5xl', + 'min-h-[calc(100vh-4rem)]', + 'h-[calc(100vh-4rem)]', + 'md:h-[calc(100vh-6rem)]', + ], + }, + }, + defaultVariants: { + size: 'md', + }, + } +) + +export type ModalBoxVariant = typeof modalBoxVariants + +/** + * The scrollable content area. This is what carries the per-size max-height — + * `full` stretches to the box instead of capping. + */ +export const modalScrollVariants = cva( + ['overflow-y-auto', 'overflow-x-hidden', 'pr-0.5', 'md:pr-1'], + { + variants: { + size: { + sm: ['max-h-[calc(100vh-4rem)]', 'md:max-h-[560px]'], + md: ['max-h-[calc(100vh-4rem)]', 'md:max-h-[640px]'], + lg: ['max-h-[calc(100vh-4rem)]', 'md:max-h-[720px]'], + xl: ['max-h-[calc(100vh-4rem)]', 'md:max-h-[800px]'], + full: ['h-full'], + }, + }, + defaultVariants: { + size: 'md', + }, + } +) + +export type ModalScrollVariant = typeof modalScrollVariants diff --git a/src/components/offline-indicator.tsx b/src/components/ui/offline-indicator/offline-indicator.tsx similarity index 97% rename from src/components/offline-indicator.tsx rename to src/components/ui/offline-indicator/offline-indicator.tsx index 663b2a54..97d94e3e 100644 --- a/src/components/offline-indicator.tsx +++ b/src/components/ui/offline-indicator/offline-indicator.tsx @@ -1,4 +1,4 @@ -import { Icon } from '../icons' +import { Icon } from '@/src/icons' type OfflineIndicatorMode = 'badge' | 'status' | 'notification' diff --git a/src/components/pagination/pagination.tsx b/src/components/ui/pagination/pagination.tsx similarity index 84% rename from src/components/pagination/pagination.tsx rename to src/components/ui/pagination/pagination.tsx index c8a20e36..f4c5638b 100644 --- a/src/components/pagination/pagination.tsx +++ b/src/components/ui/pagination/pagination.tsx @@ -1,5 +1,6 @@ -import { Button } from '@/components/button/button' +import { twMerge } from 'tailwind-merge' import { Icon } from '@/src/icons' +import { Button } from '../button/button' export interface PaginationProps { currentPage: number @@ -23,7 +24,12 @@ export function Pagination({ } return ( -
+
diff --git a/src/components/updater/updater.tsx b/src/components/updater/updater.tsx index 9d728ab2..5ebd046f 100644 --- a/src/components/updater/updater.tsx +++ b/src/components/updater/updater.tsx @@ -1,6 +1,5 @@ import { useEffect, useState } from 'react' -import Modal from '@/components/modal' -import { Button } from '@/components/button/button' +import { Button, Modal } from '@/components/ui' import { getMainClient } from '@/services/api' import { Icon } from '@/src/icons' @@ -90,7 +89,7 @@ export function UpdateChecker() { return ( <> {showNotification && ( -
+
diff --git a/src/components/user/user-card.tsx b/src/components/user/user-card.tsx index 8686c091..62954c95 100644 --- a/src/components/user/user-card.tsx +++ b/src/components/user/user-card.tsx @@ -1,8 +1,7 @@ import { useAuth } from '@/context/auth.context' import { useSendFriendRequest } from '@/services/hooks/friends/friend-service.hook' import { translateError } from '@/common/utils/translate-error' -import { AvatarComponent } from '../avatar.component' -import { Button } from '../button/button' +import { AvatarComponent, Button } from '@/components/ui' import type { UserCardUser } from './user-card-portal' import { showToast } from '@/common/toast' import { Icon } from '@/src/icons' @@ -43,10 +42,10 @@ export function UserCard({ user, className = '' }: UserCardProps) {
-
+
@@ -55,7 +54,7 @@ export function UserCard({ user, className = '' }: UserCardProps) { url={user.avatar} placeholder={user.username || ''} size="xl" - className="w-16 h-16 overflow-hidden border-2 border-gray-800 rounded-full" + className="w-16 h-16 overflow-hidden border-2 border-content rounded-full" /> {showManageFriend ? (
@@ -64,7 +63,7 @@ export function UserCard({ user, className = '' }: UserCardProps) { @@ -186,8 +186,9 @@ export const WelcomeWizard = ({ isOpen, onClose }: WelcomeWizardProps) => { size="sm" onClick={nextStep} disabled={!selectedOccupation} - className="flex-1 h-12 font-bold text-white rounded-2xl" - isPrimary + className="flex-1 h-12 font-bold" + variant={'primary'} + rounded={'2xl'} > تایید و ادامه @@ -253,8 +254,9 @@ export const WelcomeWizard = ({ isOpen, onClose }: WelcomeWizardProps) => { size="sm" onClick={nextStep} disabled={selectedInterests.length === 0} - className="flex-1 h-12 font-bold text-white rounded-2xl" - isPrimary + className="flex-1 h-12 font-bold" + variant={'primary'} + rounded={'2xl'} > ادامه @@ -329,8 +331,9 @@ export const WelcomeWizard = ({ isOpen, onClose }: WelcomeWizardProps) => { onClick={() => save()} disabled={!selectedReferralSource || isPending} loading={isPending} - className="w-full h-12 mt-4 text-base font-bold text-white shadow-lg rounded-2xl" - isPrimary + className="flex-1 h-12 font-bold mt-4" + variant={'primary'} + rounded={'2xl'} > ادامه @@ -358,8 +361,9 @@ export const WelcomeWizard = ({ isOpen, onClose }: WelcomeWizardProps) => { diff --git a/src/index.css b/src/index.css index 79e71d59..ebd64704 100644 --- a/src/index.css +++ b/src/index.css @@ -246,4 +246,12 @@ img { .animate-slide-in-right { animation: slide-in-right 0.3s ease-out; +} + +.rounded-widget { + @apply rounded-2xl +} + +.z-popover { + z-index: 9999 !important; } \ No newline at end of file diff --git a/src/layouts/bookmark/bookmark-grid.tsx b/src/layouts/bookmark/bookmark-grid.tsx index 62b784b1..0dd6029b 100644 --- a/src/layouts/bookmark/bookmark-grid.tsx +++ b/src/layouts/bookmark/bookmark-grid.tsx @@ -1,7 +1,7 @@ import { rectSortingStrategy, SortableContext } from '@dnd-kit/sortable' import { useIsMutating } from '@tanstack/react-query' import Analytics from '@/analytics' -import { ConfirmationModal } from '@/components/modal/confirmation-modal' +import { ConfirmationModal } from '@/components/ui' import { useGeneralSetting } from '@/context/general-setting.context' import type { Bookmark, FolderPathItem } from './types/bookmark.types' import { openBookmarksOptimized } from './utils/tab-manager' diff --git a/src/layouts/bookmark/components/bookmark-empty-slot.tsx b/src/layouts/bookmark/components/bookmark-empty-slot.tsx index 5c2cfc0d..50327231 100644 --- a/src/layouts/bookmark/components/bookmark-empty-slot.tsx +++ b/src/layouts/bookmark/components/bookmark-empty-slot.tsx @@ -31,7 +31,7 @@ export function EmptyBookmarkSlot({
) : ( -
+
)}
diff --git a/src/layouts/bookmark/components/bookmark-folder.tsx b/src/layouts/bookmark/components/bookmark-folder.tsx index 9b4ef2e5..d55dd3d0 100644 --- a/src/layouts/bookmark/components/bookmark-folder.tsx +++ b/src/layouts/bookmark/components/bookmark-folder.tsx @@ -47,9 +47,9 @@ export function FolderBookmarkItem({ } return isHovered ? ( - + ) : ( - + ) } diff --git a/src/layouts/bookmark/components/bookmark-icon.picker.tsx b/src/layouts/bookmark/components/bookmark-icon.picker.tsx index 6e880a77..0a3468a6 100644 --- a/src/layouts/bookmark/components/bookmark-icon.picker.tsx +++ b/src/layouts/bookmark/components/bookmark-icon.picker.tsx @@ -72,7 +72,7 @@ export function BookmarkIconPicker({ value, url, onChange }: Props) { onDragLeave={() => setIsDragging(false)} onDrop={handleDrop} className={`relative w-12 h-10 flex items-center justify-center cursor-pointer border-2 rounded-xl transition - ${isDragging ? 'border-blue-400' : 'border-base-300'} + ${isDragging ? 'border-primary' : 'border-base-300'} `} > {iconSrc && !error ? ( diff --git a/src/layouts/bookmark/components/bookmark-suggestions.tsx b/src/layouts/bookmark/components/bookmark-suggestions.tsx index 334bbb8b..4206b1b8 100644 --- a/src/layouts/bookmark/components/bookmark-suggestions.tsx +++ b/src/layouts/bookmark/components/bookmark-suggestions.tsx @@ -1,4 +1,4 @@ -import { SectionPanel } from '@/components/section-panel' +import { SectionPanel } from '@/components/ui' import { type BookmarkSuggestion, useGetSuggestedBookmarks, diff --git a/src/layouts/bookmark/components/folder-header.tsx b/src/layouts/bookmark/components/folder-header.tsx index e162f602..c489fe04 100644 --- a/src/layouts/bookmark/components/folder-header.tsx +++ b/src/layouts/bookmark/components/folder-header.tsx @@ -1,11 +1,8 @@ import { useState } from 'react' import Analytics from '@/analytics' -import { Button } from '@/components/button/button' -import Modal from '@/components/modal' -import Tooltip from '@/components/tool-tip' +import { Modal } from '@/components/ui' import type { FolderPathItem } from '../types/bookmark.types' import { FolderPath } from './folder-path' -import { Icon } from '@/src/icons' interface FolderHeaderProps { folderPath: FolderPathItem[] @@ -27,24 +24,6 @@ export function FolderHeader({ folderPath, onNavigate }: FolderHeaderProps) { onNavigate={onNavigate} className="w-full " /> - - - - - -
onNavigate(item.id, index)} className={ - 'cursor-pointer transition-colors text-blue-400 hover:text-blue-300' + 'cursor-pointer transition-colors text-primary hover:text-primary/70' } aria-label={`Go to ${item.title} folder`} > diff --git a/src/layouts/bookmark/components/modal/add-bookmark.modal.tsx b/src/layouts/bookmark/components/modal/add-bookmark.modal.tsx index 846303be..4030f68a 100644 --- a/src/layouts/bookmark/components/modal/add-bookmark.modal.tsx +++ b/src/layouts/bookmark/components/modal/add-bookmark.modal.tsx @@ -1,7 +1,6 @@ import { useEffect, useState } from 'react' -import { Button } from '@/components/button/button' -import Modal from '@/components/modal' -import { TextInput } from '@/components/text-input' +import { Button, Modal } from '@/components/ui' +import { TextInput } from '@/components/ui' import { Icon } from '@/src/icons' import type { BookmarkType } from '../../types/bookmark.types' import { BookmarkSuggestions } from '../bookmark-suggestions' @@ -243,7 +242,7 @@ export function AddBookmarkModal({ setShowAdvanced={setShowAdvanced} /> -
+
diff --git a/src/layouts/bookmark/components/modal/advanced.modal.tsx b/src/layouts/bookmark/components/modal/advanced.modal.tsx index 85e42d42..078e387f 100644 --- a/src/layouts/bookmark/components/modal/advanced.modal.tsx +++ b/src/layouts/bookmark/components/modal/advanced.modal.tsx @@ -1,8 +1,7 @@ import { useCallback, useEffect, useRef, useState } from 'react' import Analytics from '@/analytics' -import { Button } from '@/components/button/button' -import Modal from '@/components/modal' -import PopoverColorPicker from '@/components/popover-color-picker' +import { Button, Modal } from '@/components/ui' +import { ColorPicker } from '@/components/ui' import { TextInput } from '@/components/text-input' import { getEmojiList } from '@/services/emoji/emoji-api' import { BookmarkItem } from '../bookmark-item' @@ -100,7 +99,7 @@ export function AdvancedModal({ title, onClose, isOpen, bookmark }: AdvancedModa if (isLoadingEmojis) { return (
-
+
) } @@ -114,8 +113,8 @@ export function AdvancedModal({ title, onClose, isOpen, bookmark }: AdvancedModa className={`flex items-center justify-center w-7 h-7 cursor-pointer rounded-lg transition-all duration-150 ease-in-out ${ sticker === url - ? 'bg-blue-500/25 border-2 border-blue-500 transform scale-110' - : 'border border-transparent hover:bg-gray-500/10 active:bg-gray-500/20' + ? 'bg-primary/25 border-2 border-primary transform scale-110' + : 'border border-transparent hover:bg-base-content/10 active:bg-base-content/20' }`} >
- @@ -182,7 +181,9 @@ export function AdvancedModal({ title, onClose, isOpen, bookmark }: AdvancedModa type="button" onClick={resetBackground} size="md" - className="rounded-2xl p-3!" + className="p-3!" + rounded={'2xl'} + variant={'default'} > @@ -203,7 +204,7 @@ export function AdvancedModal({ title, onClose, isOpen, bookmark }: AdvancedModa debounce={true} />
- @@ -212,7 +213,9 @@ export function AdvancedModal({ title, onClose, isOpen, bookmark }: AdvancedModa type="button" onClick={resetTextColor} size="md" - className="rounded-2xl p-3!" + className="p-3!" + rounded={'2xl'} + variant={'default'} > @@ -229,9 +232,9 @@ export function AdvancedModal({ title, onClose, isOpen, bookmark }: AdvancedModa size="md" type="button" onClick={toggleEmojiPopover} - className={ - 'btn !w-fit px-8 border-none shadow-none bg-base-300 text-muted rounded-xl transition-colors duration-300 ease-in-out' - } + className={'btn !w-fit px-8'} + rounded={'2xl'} + variant={'default'} > {sticker ? ( <> @@ -266,7 +269,7 @@ export function AdvancedModal({ title, onClose, isOpen, bookmark }: AdvancedModa type="button" onClick={() => handleEmojiSelect(sticker)} className={ - 'px-3 py-1.5 cursor-pointer text-xs rounded-md text-red-600 hover:bg-red-50' + 'px-3 py-1.5 cursor-pointer text-xs rounded-md text-error hover:bg-error/10' } > حذف @@ -326,9 +329,8 @@ export function AdvancedModal({ title, onClose, isOpen, bookmark }: AdvancedModa @@ -336,10 +338,9 @@ export function AdvancedModal({ title, onClose, isOpen, bookmark }: AdvancedModa type="submit" onClick={() => handleClose()} size="md" - isPrimary={true} - className={ - 'btn btn-circle !w-fit px-8 border-none shadow-none text-secondary !rounded-2xl transition-colors duration-300 ease-in-out' - } + variant={'primary'} + rounded={'2xl'} + className={'w-fit px-8 border-none'} > ذخیره diff --git a/src/layouts/bookmark/components/modal/bookmark-context-menu.tsx b/src/layouts/bookmark/components/modal/bookmark-context-menu.tsx index 52901a10..d53e172c 100644 --- a/src/layouts/bookmark/components/modal/bookmark-context-menu.tsx +++ b/src/layouts/bookmark/components/modal/bookmark-context-menu.tsx @@ -1,4 +1,4 @@ -import { ContextMenu } from '@/components/context-menu.component' +import { ContextMenu } from '@/components/ui' import { Icon } from '@/src/icons' interface BookmarkContextMenuProps { diff --git a/src/layouts/bookmark/components/modal/edit-bookmark.modal.tsx b/src/layouts/bookmark/components/modal/edit-bookmark.modal.tsx index 603620ff..15ceab11 100644 --- a/src/layouts/bookmark/components/modal/edit-bookmark.modal.tsx +++ b/src/layouts/bookmark/components/modal/edit-bookmark.modal.tsx @@ -1,7 +1,6 @@ import { getFaviconFromUrl } from '@/common/utils/icon' -import { Button } from '@/components/button/button' -import Modal from '@/components/modal' -import { TextInput } from '@/components/text-input' +import { Button, Modal } from '@/components/ui' +import { TextInput } from '@/components/ui' import { useEffect, useState } from 'react' import type { Bookmark } from '../../types/bookmark.types' import { type IconSourceType, ShowAdvancedButton } from '../shared' @@ -216,7 +215,8 @@ export function EditBookmarkModal({ onClick={onClose} size="md" disabled={isUpdating} - className="w-20 transition-colors duration-300 ease-in-out border-none shadow-none btn bg-base-300 hover:bg-error/10 text-base-content/80 hover:text-error rounded-2xl" + className="w-20 transition-colors duration-300 ease-in-out border-none shadow-none btn bg-base-300 hover:bg-error/10 text-base-content/80 hover:text-error" + rounded={'2xl'} > لغو @@ -228,9 +228,10 @@ export function EditBookmarkModal({ isUpdating } size="md" - isPrimary={true} loading={isUpdating} - className="transition-colors duration-300 ease-in-out border-none shadow-none btn w-28 text-secondary rounded-2xl" + variant={'primary'} + rounded={'2xl'} + className="transition-colors duration-300 ease-in-out border-none shadow-none btn w-28" > ذخیره diff --git a/src/layouts/bookmark/components/modal/import-browser-bookmarks.modal.tsx b/src/layouts/bookmark/components/modal/import-browser-bookmarks.modal.tsx index 61ff111f..01ac65a9 100644 --- a/src/layouts/bookmark/components/modal/import-browser-bookmarks.modal.tsx +++ b/src/layouts/bookmark/components/modal/import-browser-bookmarks.modal.tsx @@ -4,8 +4,7 @@ import { showToast } from '@/common/toast' import { getFaviconFromUrl } from '@/common/utils/icon' import { useGeneralSetting } from '@/context/general-setting.context' import { Icon } from '@/src/icons' -import { Button } from '@/components/button/button' -import Modal from '@/components/modal' +import { Button, Modal } from '@/components/ui' import { useBookmarkStore } from '../../context/bookmark.context' import { MAX_BROWSER_IMPORT_ITEMS } from '../../constants/browser-import.constant' import type { BrowserImportNode } from '../../types/bookmark.types' @@ -299,8 +298,8 @@ export function ImportBrowserBookmarksModal({ @@ -348,20 +347,21 @@ export function ImportBrowserBookmarksModal({ onClick={onClose} size="md" disabled={isImporting} - className="w-20 transition-colors duration-300 ease-in-out border-none shadow-none btn bg-base-300 hover:bg-error/10 text-base-content/80 hover:text-error rounded-2xl" + className="w-20 transition-colors duration-300 ease-in-out bg-base-300 hover:bg-error/10 text-base-content/80 hover:text-error rounded-2xl" > انصراف diff --git a/src/layouts/bookmark/components/shared.tsx b/src/layouts/bookmark/components/shared.tsx index d1bb2925..8e2474fb 100644 --- a/src/layouts/bookmark/components/shared.tsx +++ b/src/layouts/bookmark/components/shared.tsx @@ -1,4 +1,4 @@ -import { ItemSelector } from '@/components/item-selector' +import { Button, ItemSelector } from '@/components/ui' import type { BookmarkType } from '../types/bookmark.types' import { Icon } from '@/src/icons' @@ -54,12 +54,13 @@ export function ShowAdvancedButton({ showAdvanced, }: ShowAdvancedButtonProps) { return ( - + ) } diff --git a/src/layouts/explorer/components/content-site.tsx b/src/layouts/explorer/components/content-site.tsx index 11a4e842..50f89d7f 100644 --- a/src/layouts/explorer/components/content-site.tsx +++ b/src/layouts/explorer/components/content-site.tsx @@ -1,4 +1,4 @@ -import { NewBadge } from '@/components/badges/new.badge' +import { NewBadge } from '@/components/ui' import type { CatalogItem } from '../interfaces/catalog-item.interface' interface SiteProp { diff --git a/src/layouts/friends/components/activities.tsx b/src/layouts/friends/components/activities.tsx index 6587f34e..112d5873 100644 --- a/src/layouts/friends/components/activities.tsx +++ b/src/layouts/friends/components/activities.tsx @@ -4,7 +4,7 @@ import { useAuth } from '@/context/auth.context' import { ActivityCard } from './activity-card/activity-card' import { ManageActivityBottomSheet } from './activity-card/manage-activity.bottom-sheet' import { EmptyActivityCard } from './activity-card/empty-activity-card' -import { Dropdown } from '@/components/dropdown' +import { Dropdown } from '@/components/ui' export const ActiveFriendsHorizontal = () => { const { user } = useAuth() diff --git a/src/layouts/friends/components/activity-card/activity-card.tsx b/src/layouts/friends/components/activity-card/activity-card.tsx index ef21a11f..d871fd47 100644 --- a/src/layouts/friends/components/activity-card/activity-card.tsx +++ b/src/layouts/friends/components/activity-card/activity-card.tsx @@ -1,5 +1,5 @@ -import { AvatarComponent } from '@/components/avatar.component' -import { Dropdown } from '@/components/dropdown' +import { AvatarComponent } from '@/components/ui' +import { Dropdown } from '@/components/ui' import { type AttachmentReaction, type ReactionKey, diff --git a/src/layouts/friends/components/activity-card/empty-activity-card.tsx b/src/layouts/friends/components/activity-card/empty-activity-card.tsx index 1c8d9e2c..00c77ccc 100644 --- a/src/layouts/friends/components/activity-card/empty-activity-card.tsx +++ b/src/layouts/friends/components/activity-card/empty-activity-card.tsx @@ -1,4 +1,4 @@ -import { AvatarComponent } from '@/components/avatar.component' +import { AvatarComponent } from '@/components/ui' import { Icon } from '@/src/icons' interface EmptyActivityCardProps { diff --git a/src/layouts/friends/components/activity-card/manage-activity.bottom-sheet.tsx b/src/layouts/friends/components/activity-card/manage-activity.bottom-sheet.tsx index 645060c2..6cfbcbf9 100644 --- a/src/layouts/friends/components/activity-card/manage-activity.bottom-sheet.tsx +++ b/src/layouts/friends/components/activity-card/manage-activity.bottom-sheet.tsx @@ -1,8 +1,10 @@ import { useState } from 'react' -import { Button } from '@/components/button/button' import { showToast } from '@/common/toast' -import Modal from '@/components/modal' -import { useRemoveActivity, useSetActivity } from '@/services/hooks/user/user-service.hook' +import { Button, Modal } from '@/components/ui' +import { + useRemoveActivity, + useSetActivity, +} from '@/services/hooks/user/user-service.hook' import { translateError } from '@/common/utils/translate-error' import { playAlarm } from '@/common/play-alarm' import { @@ -11,11 +13,11 @@ import { } from '@/services/hooks/friends/friend-service.hook' import { MakeSkeletonFriendItem } from '../friend-item/friend-item.skeleton' import { GetContentFromReactions, RenderReactionContent } from './activity-reaction' -import { AvatarComponent } from '@/components/avatar.component' +import { AvatarComponent } from '@/components/ui' import { callEvent } from '@/common/utils/call-event' -import { Chip } from '@/components/chip.component' -import { SelectBox } from '@/components/selectbox/selectbox' -import Tooltip from '@/components/tool-tip' +import { Chip } from '@/components/ui' +import { SelectBox } from '@/components/ui' +import { Tooltip } from '@/components/ui' import { Icon } from '@/src/icons' interface ManageActivityBottomSheetProps { @@ -248,8 +250,9 @@ export function ManageActivityBottomSheet({ onClick={handleSave} disabled={isSubmitting || !activity.trim()} size="sm" - className="w-full mt-1 rounded-xl" - isPrimary + className="w-full mt-1" + variant={'primary'} + rounded={'2xl'} loading={isSubmitting} > انتشار نوشته diff --git a/src/layouts/friends/components/add-friend.bottom-sheet.tsx b/src/layouts/friends/components/add-friend.bottom-sheet.tsx index d12a40eb..f5baea82 100644 --- a/src/layouts/friends/components/add-friend.bottom-sheet.tsx +++ b/src/layouts/friends/components/add-friend.bottom-sheet.tsx @@ -1,11 +1,10 @@ import { useState } from 'react' -import { Button } from '@/components/button/button' import { TextInput } from '@/components/text-input' import { useAuth } from '@/context/auth.context' import { useSendFriendRequest } from '@/services/hooks/friends/friend-service.hook' import { translateError } from '@/common/utils/translate-error' import { showToast } from '@/common/toast' -import Modal from '@/components/modal' +import { Button, Modal } from '@/components/ui' import { Icon } from '@/src/icons' interface AddFriendBottomSheetProps { @@ -93,10 +92,10 @@ export function AddFriendBottomSheet({ isOpen, onClose }: AddFriendBottomSheetPr
{!canSendRequest && ( -
+

برای ارسال درخواست دوستی، ابتدا باید نام کاربری خود را در بخش @@ -127,7 +126,7 @@ export function AddFriendBottomSheet({ isOpen, onClose }: AddFriendBottomSheetPr /> {translatedError && ( -

+

{translatedError}

diff --git a/src/layouts/friends/components/buttons/friend-requests.button.tsx b/src/layouts/friends/components/buttons/friend-requests.button.tsx index de9f5cba..ea795d33 100644 --- a/src/layouts/friends/components/buttons/friend-requests.button.tsx +++ b/src/layouts/friends/components/buttons/friend-requests.button.tsx @@ -19,7 +19,7 @@ export function FriendRequestsButton({ size, pendingCount }: Prop) { درخواست‌ها {pendingCount ? ( -
+
{pendingCount}
) : ( @@ -36,7 +36,7 @@ export function FriendRequestsButton({ size, pendingCount }: Prop) { className="w-4 h-4 text-base-content/90 group-hover:text-base-content/70" /> {pendingCount ? ( -
+
{pendingCount}
) : ( diff --git a/src/layouts/friends/components/friend-item/friend.item.tsx b/src/layouts/friends/components/friend-item/friend.item.tsx index ef8cc9da..08eb7387 100644 --- a/src/layouts/friends/components/friend-item/friend.item.tsx +++ b/src/layouts/friends/components/friend-item/friend.item.tsx @@ -1,4 +1,4 @@ -import { AvatarComponent } from '@/components/avatar.component' +import { AvatarComponent } from '@/components/ui' interface Prop { avatar: string diff --git a/src/layouts/friends/components/friend-requests.bottom-sheet.tsx b/src/layouts/friends/components/friend-requests.bottom-sheet.tsx index eb4785d8..3ed9bd87 100644 --- a/src/layouts/friends/components/friend-requests.bottom-sheet.tsx +++ b/src/layouts/friends/components/friend-requests.bottom-sheet.tsx @@ -5,9 +5,8 @@ import { import { RemoveFriendButton } from './remove-button' import { FriendsList } from './friends-list' -import { Button } from '@/components/button/button' import { showToast } from '@/common/toast' -import Modal from '@/components/modal' +import { Button, Modal } from '@/components/ui' import { Icon } from '@/src/icons' interface Prop { @@ -46,11 +45,7 @@ export const FriendRequestsBottomSheet = ({ isOpen, onClose }: Prop) => { size="sm" onClick={() => acceptFriend(friend.id)} disabled={isProcessing} - className="flex items-center justify-center gap-1 - h-9 px-3 - text-success bg-success/10 border border-success/20 - rounded-lg transition-all - active:scale-[0.97]" + className="flex items-center justify-center gap-1 h-9 px-3 text-success bg-success/10 border border-success/20 rounded-lg transition-all active:scale-[0.97]" > دوست شیم diff --git a/src/layouts/friends/components/friends-list.tsx b/src/layouts/friends/components/friends-list.tsx index 1f2ebc88..1d907081 100644 --- a/src/layouts/friends/components/friends-list.tsx +++ b/src/layouts/friends/components/friends-list.tsx @@ -1,4 +1,4 @@ -import { AvatarComponent } from '@/components/avatar.component' +import { AvatarComponent } from '@/components/ui' import { type Friend, useGetFriends } from '@/services/hooks/friends/friend-service.hook' import { useInfiniteScroll } from '@/hooks/use-infinite-scroll' import { FriendEmptyList } from './empty-list.friend' diff --git a/src/layouts/friends/components/remove-button.tsx b/src/layouts/friends/components/remove-button.tsx index 52bb8bd7..0670f41d 100644 --- a/src/layouts/friends/components/remove-button.tsx +++ b/src/layouts/friends/components/remove-button.tsx @@ -1,4 +1,4 @@ -import { Button } from '@/components/button/button' +import { Button } from '@/components/ui' import type { Friend } from '@/services/hooks/friends/friend-service.hook' import { Icon } from '@/src/icons' diff --git a/src/layouts/friends/components/select-friend.layout.tsx b/src/layouts/friends/components/select-friend.layout.tsx index 16f9ca7c..9e228926 100644 --- a/src/layouts/friends/components/select-friend.layout.tsx +++ b/src/layouts/friends/components/select-friend.layout.tsx @@ -1,4 +1,4 @@ -import { AvatarComponent } from '@/components/avatar.component' +import { AvatarComponent } from '@/components/ui' import { useGetFriends, type Friend } from '@/services/hooks/friends/friend-service.hook' import { FriendEmptyList } from './empty-list.friend' diff --git a/src/layouts/friends/friends.tsx b/src/layouts/friends/friends.tsx index f4cbe8ce..bcc94a65 100644 --- a/src/layouts/friends/friends.tsx +++ b/src/layouts/friends/friends.tsx @@ -5,7 +5,7 @@ import { showToast } from '@/common/toast' import { RemoveFriendButton } from './components/remove-button' import { FriendsList } from './components/friends-list' import { AddFriendBottomSheet } from './components/add-friend.bottom-sheet' -import { ConfirmationModal } from '@/components/modal/confirmation-modal' +import { ConfirmationModal } from '@/components/ui' import { FriendRequestsButton } from './components/buttons/friend-requests.button' import { useAuth } from '@/context/auth.context' import { Icon } from '@/src/icons' diff --git a/src/layouts/market/market-coins/components/coin-package-card.tsx b/src/layouts/market/market-coins/components/coin-package-card.tsx index 971553c3..b7322a0c 100644 --- a/src/layouts/market/market-coins/components/coin-package-card.tsx +++ b/src/layouts/market/market-coins/components/coin-package-card.tsx @@ -1,6 +1,6 @@ -import { Button } from '@/components/button/button' import { ConfigKey } from '@/common/constant/config.key' -import { CoinPackage } from '@/services/hooks/market/market-coins.interface' +import { Button } from '@/components/ui' +import type { CoinPackage } from '@/services/hooks/market/market-coins.interface' import { Icon } from '@/src/icons' interface CoinPackageCardProps { @@ -60,7 +60,9 @@ export function CoinPackageCard({ package: pkg, onPurchase }: CoinPackageCardPro @@ -125,7 +125,9 @@ export function CoinPackagePurchaseModal({ disabled={isPending} loading={isPending} loadingText="در حال انتقال..." - className="flex-1 text-white rounded-2xl bg-primary hover:bg-primary/90" + className="flex-1" + variant={'primary'} + rounded={'2xl'} > تایید و پرداخت diff --git a/src/layouts/market/market-coins/index.tsx b/src/layouts/market/market-coins/index.tsx index 0d0ee409..706e53e6 100644 --- a/src/layouts/market/market-coins/index.tsx +++ b/src/layouts/market/market-coins/index.tsx @@ -1,6 +1,6 @@ import { useState } from 'react' import Analytics from '@/analytics' -import { Pagination } from '@/components/pagination' +import { Pagination } from '@/components/ui' import { useAuth } from '@/context/auth.context' import { CoinPackageCard } from './components/coin-package-card' import { CoinPackagePurchaseModal } from './components/coin-package-purchase-modal' diff --git a/src/layouts/market/market-container.tsx b/src/layouts/market/market-container.tsx index 23a111c2..1174abd1 100644 --- a/src/layouts/market/market-container.tsx +++ b/src/layouts/market/market-container.tsx @@ -4,7 +4,7 @@ import { MarketWallpaper } from './market-wallpaper' import { MarketOtherItems } from './other-items' import { UserCoin } from '../setting/tabs/account/components/user-coin' import Analytics from '@/analytics' -import { TabNavigation } from '@/components/tab-navigation' +import { TabNavigation } from '@/components/ui' import { MarketCoins } from './market-coins' import { listenEvent } from '@/common/utils/call-event' import { Icon } from '@/src/icons' diff --git a/src/layouts/market/market-wallpaper/index.tsx b/src/layouts/market/market-wallpaper/index.tsx index b4a57eb5..af686de6 100644 --- a/src/layouts/market/market-wallpaper/index.tsx +++ b/src/layouts/market/market-wallpaper/index.tsx @@ -1,6 +1,6 @@ import { useState } from 'react' import Analytics from '@/analytics' -import { Pagination } from '@/components/pagination' +import { Pagination } from '@/components/ui' import { WallpaperItem } from '@/layouts/setting/tabs/wallpapers/tab/gallery/components/wallpaper-item/wallpaper-item' import { useGetWallpapers } from '@/services/hooks/wallpapers/get-wallpaper-categories.hook' import { useWallpaperContext } from '@/context/wallpaper.context' diff --git a/src/layouts/market/other-items/components/market-item-card.tsx b/src/layouts/market/other-items/components/market-item-card.tsx index 61efc80b..3f29a1f8 100644 --- a/src/layouts/market/other-items/components/market-item-card.tsx +++ b/src/layouts/market/other-items/components/market-item-card.tsx @@ -1,10 +1,10 @@ -import { Button } from '@/components/button/button' import { ItemPrice } from '@/components/item-price/item-price' import { getItemTypeEmoji } from '@/components/market/get-item-type-emoji' import { type MarketItem, MarketItemType } from '@/services/hooks/market/market.interface' import { showToast } from '@/common/toast' import { RenderPreview } from './render-preview' import { Icon } from '@/src/icons' +import { Button } from '@/components/ui' interface MarketItemCardProps { item: MarketItem @@ -90,7 +90,9 @@ export function MarketItemCard({ diff --git a/src/layouts/mini-apps/states/mini-app-error.tsx b/src/layouts/mini-apps/states/mini-app-error.tsx index d2d5c93b..8ff1bf2f 100644 --- a/src/layouts/mini-apps/states/mini-app-error.tsx +++ b/src/layouts/mini-apps/states/mini-app-error.tsx @@ -1,4 +1,4 @@ -import { Button } from '@/components/button/button' +import { Button } from '@/components/ui' interface Prop { handleReload: () => void @@ -33,8 +33,9 @@ export function MiniAppError({ handleReload, onClickToBack }: Prop) { diff --git a/src/layouts/navbar/profile/profile.tsx b/src/layouts/navbar/profile/profile.tsx index 6677e944..215cb9d1 100644 --- a/src/layouts/navbar/profile/profile.tsx +++ b/src/layouts/navbar/profile/profile.tsx @@ -1,7 +1,7 @@ import { useState, useEffect } from 'react' import { listenEvent } from '@/common/utils/call-event' -import { AvatarComponent } from '@/components/avatar.component' -import Tooltip from '@/components/tool-tip' +import { AvatarComponent } from '@/components/ui' +import { Tooltip } from '@/components/ui' import { useAuth } from '@/context/auth.context' import { UserAccountModal } from '../../setting/tabs/account/user-account.modal' import { WelcomeWizard } from '@/components/welcome-wizard' diff --git a/src/layouts/search/browser-bookmark/bookmark-popover.tsx b/src/layouts/search/browser-bookmark/bookmark-popover.tsx index f6cfc935..a604fd7d 100644 --- a/src/layouts/search/browser-bookmark/bookmark-popover.tsx +++ b/src/layouts/search/browser-bookmark/bookmark-popover.tsx @@ -7,8 +7,8 @@ import { getBrowserBookmarks, } from '@/layouts/bookmark/utils/browser-bookmarks.util' import Analytics from '@/analytics' -import { Button } from '@/components/button/button' import { Icon } from '@/src/icons' +import { Button } from '@/components/ui' interface BookmarkPopoverProps { isOpen: boolean @@ -76,7 +76,7 @@ export function BookmarkPopover({ isOpen, onClose, coords }: BookmarkPopoverProp return createPortal(
handlePermission()} - className="w-full rounded-2xl" - isPrimary + className="w-full" + variant={'primary'} + rounded={'2xl'} > فعال‌سازی دسترسی
) : ( -
+
{c} {currentFolderId && ( diff --git a/src/layouts/search/select-engine/engine-selector.tsx b/src/layouts/search/select-engine/engine-selector.tsx index 6019dc6b..093c1f3a 100644 --- a/src/layouts/search/select-engine/engine-selector.tsx +++ b/src/layouts/search/select-engine/engine-selector.tsx @@ -1,6 +1,6 @@ import { getFromStorage, setToStorage } from '@/common/storage' import { callEvent } from '@/common/utils/call-event' -import { Dropdown } from '@/components/dropdown' +import { Dropdown } from '@/components/ui' import { useAuth } from '@/context/auth.context' import { useChangeSearchEngine } from '@/services/hooks/extension/update-setting.hook' import { type EngineMeta, useGetSearchboxData } from '@/services/hooks/trends/get-trends' diff --git a/src/layouts/search/suggestion/autocomplete-consent.modal.tsx b/src/layouts/search/suggestion/autocomplete-consent.modal.tsx index 70b2d205..713215cc 100644 --- a/src/layouts/search/suggestion/autocomplete-consent.modal.tsx +++ b/src/layouts/search/suggestion/autocomplete-consent.modal.tsx @@ -1,6 +1,5 @@ import { autoFormatErrorToast } from '@/common/toast' -import { Button } from '@/components/button/button' -import Modal from '@/components/modal' +import { Button, Modal } from '@/components/ui' import { safeAwait } from '@/services/api' import { useUpdateSearchAutocomplete } from '@/services/hooks/extension/update-setting.hook' @@ -39,9 +38,8 @@ export function AutocompleteConsentModal({ diff --git a/src/layouts/search/voice/voice-search.button.tsx b/src/layouts/search/voice/voice-search.button.tsx index f801dcfd..86d0531f 100644 --- a/src/layouts/search/voice/voice-search.button.tsx +++ b/src/layouts/search/voice/voice-search.button.tsx @@ -1,5 +1,5 @@ import Analytics from '@/analytics' -import Tooltip from '@/components/tool-tip' +import { Tooltip } from '@/components/ui' export function VoiceSearchButton({ onClick }: { onClick: () => void }) { const onClickHandle = () => { diff --git a/src/layouts/search/voice/voice-search.portal.tsx b/src/layouts/search/voice/voice-search.portal.tsx index 7bf6f8b2..a46a3edf 100644 --- a/src/layouts/search/voice/voice-search.portal.tsx +++ b/src/layouts/search/voice/voice-search.portal.tsx @@ -1,6 +1,6 @@ import { useEffect, useState } from 'react' import { useVoiceSearch } from './use-voice-search' -import { Portal } from '@/components/portal/portal' +import { Portal } from '@/components/ui' import { Icon } from '@/src/icons' interface VoiceSearchPortalProps { diff --git a/src/layouts/setting/setting-modal.tsx b/src/layouts/setting/setting-modal.tsx index 9b57d268..22c6ade3 100644 --- a/src/layouts/setting/setting-modal.tsx +++ b/src/layouts/setting/setting-modal.tsx @@ -1,6 +1,6 @@ import Analytics from '@/analytics' import { callEvent } from '@/common/utils/call-event' -import Modal from '@/components/modal' +import { Modal } from '@/components/ui' import { type TabItem, TabManager } from '@/components/tab-manager' import { UpdateReleaseNotesModal } from '@/components/update-release-notes-modal' import { AboutUsTab } from './tabs/about-us/about-us' diff --git a/src/layouts/setting/tabs/about-us/about-us.tsx b/src/layouts/setting/tabs/about-us/about-us.tsx index 64f2c905..eaedc275 100644 --- a/src/layouts/setting/tabs/about-us/about-us.tsx +++ b/src/layouts/setting/tabs/about-us/about-us.tsx @@ -1,4 +1,4 @@ -import { SectionPanel } from '@/components/section-panel' +import { SectionPanel } from '@/components/ui' import { ConfigKey } from '../../../../common/constant/config.key' import { Icon } from '@/src/icons' @@ -8,7 +8,7 @@ export function AboutUsTab() {

ویجتیفای diff --git a/src/layouts/setting/tabs/account/auth-form/auth-otp.tsx b/src/layouts/setting/tabs/account/auth-form/auth-otp.tsx index a5e7a933..88bd5d3d 100644 --- a/src/layouts/setting/tabs/account/auth-form/auth-otp.tsx +++ b/src/layouts/setting/tabs/account/auth-form/auth-otp.tsx @@ -1,6 +1,5 @@ import { useState } from 'react' import { TextInput } from '@/components/text-input' -import { Button } from '@/components/button/button' import { useGetAuthStatus, useRequestOtp, @@ -14,6 +13,7 @@ import OtpInput from './components/otp-input' import { callEvent } from '@/common/utils/call-event' import { sleep } from '@/common/utils/timeout' import { Icon } from '@/src/icons' +import { Button } from '@/components/ui' type AuthOtpProps = { step: 'enter-email' | 'enter-otp' @@ -181,11 +181,12 @@ const AuthOtp: React.FC = ({ step, setStep }) => {

diff --git a/src/layouts/setting/tabs/account/auth-form/components/input-text-error.tsx b/src/layouts/setting/tabs/account/auth-form/components/input-text-error.tsx index ddb36cda..83048623 100644 --- a/src/layouts/setting/tabs/account/auth-form/components/input-text-error.tsx +++ b/src/layouts/setting/tabs/account/auth-form/components/input-text-error.tsx @@ -9,7 +9,7 @@ const InputTextError: React.FC = ({ message, className }) = const hasError = Boolean(message) const classes = twMerge( - 'text-xs text-red-500 flex items-center gap-1.5 transition-all duration-300 ease-in-out overflow-hidden', + 'text-xs text-error flex items-center gap-1.5 transition-all duration-300 ease-in-out overflow-hidden', hasError ? 'opacity-100 translate-y-0 mt-1 min-h-[20px]' : 'opacity-0 -translate-y-1 pointer-events-none', @@ -27,7 +27,7 @@ const InputTextError: React.FC = ({ message, className }) = <>
) return ( - <> - - - - + setIsOpen(!isOpen)} + className="flex items-center justify-between w-full py-2 text-right transition-colors hover:bg-content" + > + {triggerElement} + + } + className="w-full" + > + {content} + ) } diff --git a/src/layouts/setting/tabs/account/components/profile-date-picker.tsx b/src/layouts/setting/tabs/account/components/profile-date-picker.tsx index f621724b..ced5d3db 100644 --- a/src/layouts/setting/tabs/account/components/profile-date-picker.tsx +++ b/src/layouts/setting/tabs/account/components/profile-date-picker.tsx @@ -1,5 +1,5 @@ -import { Button } from '@/components/button/button' -import { ClickableTooltip } from '@/components/clickable-tooltip' +import { callEvent } from '@/common/utils/call-event' +import { Button, ClickableTooltip, Dropdown } from '@/components/ui' import { Icon } from '@/src/icons' import { useRef, useState, useEffect } from 'react' @@ -34,7 +34,6 @@ export default function JalaliDatePicker({ enable, }: JalaliDatePickerProps) { const currentYear = 1403 - const [isOpen, setIsOpen] = useState(false) const triggerRef = useRef(null) const [tempDate, setTempDate] = useState({ year: 1380, month: 1, day: 1 }) @@ -51,11 +50,11 @@ export default function JalaliDatePicker({ } useEffect(() => { - if (isOpen) { + if (value) { const parsed = parseValue(value) setTempDate(parsed) } - }, [isOpen, value]) + }, [value]) const getDaysInMonth = (m: number, y: number) => { if (m === 12) { @@ -84,97 +83,89 @@ export default function JalaliDatePicker({ const handleConfirm = () => { const formattedDate = `${tempDate.year}-${tempDate.month.toString().padStart(2, '0')}-${tempDate.day.toString().padStart(2, '0')}` onChange(formattedDate) - setIsOpen(false) + callEvent('closeAllDropdowns') } const handleCancel = () => { - setIsOpen(false) - } - - const onClickToOpen = () => { - if (!enable) { - return - } - - setIsOpen(true) + callEvent('closeAllDropdowns') } return ( - <> - - - -
- - +
+ - -
- -
- - + + {value || 'انتخاب تاریخ'} +
+
- } - position="bottom" - offset={8} - closeOnClickOutside={true} - /> - + + } + className="w-full" + > +
+
+ + + +
+ +
+ + +
+
+ ) } diff --git a/src/layouts/setting/tabs/account/components/profile-display.tsx b/src/layouts/setting/tabs/account/components/profile-display.tsx index bdc34e8c..683beae5 100644 --- a/src/layouts/setting/tabs/account/components/profile-display.tsx +++ b/src/layouts/setting/tabs/account/components/profile-display.tsx @@ -1,10 +1,9 @@ import moment from 'jalali-moment' -import { AvatarComponent } from '@/components/avatar.component' -import { Button } from '@/components/button/button' -import { OfflineIndicator } from '@/components/offline-indicator' +import { AvatarComponent, Button } from '@/components/ui' +import { OfflineIndicator } from '@/components/ui' import { UserCoin } from './user-coin' import type React from 'react' -import { Chip } from '@/components/chip.component' +import { Chip } from '@/components/ui' import { AddPhoneModal } from './modals/add-phone.modal' import { useAuth } from '@/context/auth.context' import Analytics from '@/analytics' @@ -155,7 +154,7 @@ export const ProfileDisplay = () => { ) : ( diff --git a/src/layouts/setting/tabs/account/tabs/rewards/components/tasks.tsx b/src/layouts/setting/tabs/account/tabs/rewards/components/tasks.tsx index 4fddaeba..14e64597 100644 --- a/src/layouts/setting/tabs/account/tabs/rewards/components/tasks.tsx +++ b/src/layouts/setting/tabs/account/tabs/rewards/components/tasks.tsx @@ -1,5 +1,5 @@ import { ConfigKey } from '@/common/constant/config.key' -import { SectionPanel } from '@/components/section-panel' +import { SectionPanel } from '@/components/ui' import type { Task } from '@/services/hooks/user/referrals-service.hook' import { Icon } from '@/src/icons' diff --git a/src/layouts/setting/tabs/account/tabs/rewards/rewards-tab.tsx b/src/layouts/setting/tabs/account/tabs/rewards/rewards-tab.tsx index 363c9aad..ebf3fa3c 100644 --- a/src/layouts/setting/tabs/account/tabs/rewards/rewards-tab.tsx +++ b/src/layouts/setting/tabs/account/tabs/rewards/rewards-tab.tsx @@ -1,5 +1,5 @@ import { ConfigKey } from '@/common/constant/config.key' -import { SectionPanel } from '@/components/section-panel' +import { SectionPanel } from '@/components/ui' import { useGetReferrals } from '@/services/hooks/user/referrals-service.hook' import { ReferralCodeSection } from './components/referral-code-section' import { RewardTasks } from './components/tasks' @@ -34,7 +34,7 @@ export const RewardsTab = () => { } size="xs" > -
+
- +
diff --git a/src/layouts/setting/tabs/account/tabs/user-profile/user-profile.tsx b/src/layouts/setting/tabs/account/tabs/user-profile/user-profile.tsx index 4bb46033..ec9b8ad7 100644 --- a/src/layouts/setting/tabs/account/tabs/user-profile/user-profile.tsx +++ b/src/layouts/setting/tabs/account/tabs/user-profile/user-profile.tsx @@ -1,6 +1,5 @@ import { useEffect } from 'react' -import { Button } from '@/components/button/button' -import { SectionPanel } from '@/components/section-panel' +import { Button, SectionPanel } from '@/components/ui' import { useAuth } from '@/context/auth.context' import { useGetOrCreateReferralCode } from '@/services/hooks/user/referrals-service.hook' import { @@ -12,7 +11,7 @@ import { ProfileDisplay } from '../../components/profile-display' import { ReferralCodeSection } from '../rewards/components/referral-code-section' import { showToast } from '@/common/toast' import { translateError } from '@/common/utils/translate-error' -import { ConfirmationModal } from '@/components/modal/confirmation-modal' +import { ConfirmationModal } from '@/components/ui' import { Icon } from '@/src/icons' export const UserProfile = () => { @@ -60,7 +59,7 @@ export const UserProfile = () => { if (isLoading) { return (
-
+
) } @@ -71,7 +70,8 @@ export const UserProfile = () => {

{getMessageError()}

{' '} +
diff --git a/src/layouts/setting/tabs/account/user-account.modal.tsx b/src/layouts/setting/tabs/account/user-account.modal.tsx index 742a0765..05c1ea84 100644 --- a/src/layouts/setting/tabs/account/user-account.modal.tsx +++ b/src/layouts/setting/tabs/account/user-account.modal.tsx @@ -1,4 +1,4 @@ -import Modal from '@/components/modal' +import { Modal } from '@/components/ui' import { useAuth } from '@/context/auth.context' import AuthForm from './auth-form/auth-form' import { SettingModal } from '../../setting-modal' diff --git a/src/layouts/setting/tabs/appearance/components/browser-title-selector.tsx b/src/layouts/setting/tabs/appearance/components/browser-title-selector.tsx index 86bb4266..e0192c11 100644 --- a/src/layouts/setting/tabs/appearance/components/browser-title-selector.tsx +++ b/src/layouts/setting/tabs/appearance/components/browser-title-selector.tsx @@ -3,9 +3,9 @@ import { useEffect, useState } from 'react' import Analytics from '@/analytics' import { getFromStorage, setToStorage } from '@/common/storage' import { callEvent } from '@/common/utils/call-event' -import { ItemSelector } from '@/components/item-selector' +import { ItemSelector } from '@/components/ui' import { renderBrowserTitlePreview } from '@/components/market/title/title-render-preview' -import { SectionPanel } from '@/components/section-panel' +import { SectionPanel } from '@/components/ui' import { safeAwait } from '@/services/api' import { useChangeBrowserTitle } from '@/services/hooks/extension/update-setting.hook' import type { UserInventoryItem } from '@/services/hooks/market/market.interface' diff --git a/src/layouts/setting/tabs/appearance/components/content-alignment-settings.tsx b/src/layouts/setting/tabs/appearance/components/content-alignment-settings.tsx index cc6e80a9..b03df9af 100644 --- a/src/layouts/setting/tabs/appearance/components/content-alignment-settings.tsx +++ b/src/layouts/setting/tabs/appearance/components/content-alignment-settings.tsx @@ -1,5 +1,5 @@ -import { ItemSelector } from '@/components/item-selector' -import { SectionPanel } from '@/components/section-panel' +import { ItemSelector } from '@/components/ui' +import { SectionPanel } from '@/components/ui' import { UI, useAppearanceSetting } from '@/context/appearance.context' export function ContentAlignmentSettings() { diff --git a/src/layouts/setting/tabs/appearance/components/font-selector.tsx b/src/layouts/setting/tabs/appearance/components/font-selector.tsx index f5e0bc1b..222419d2 100644 --- a/src/layouts/setting/tabs/appearance/components/font-selector.tsx +++ b/src/layouts/setting/tabs/appearance/components/font-selector.tsx @@ -1,8 +1,8 @@ import { useEffect, useState } from 'react' import Analytics from '@/analytics' import { callEvent } from '@/common/utils/call-event' -import { ItemSelector } from '@/components/item-selector' -import { SectionPanel } from '@/components/section-panel' +import { ItemSelector } from '@/components/ui' +import { SectionPanel } from '@/components/ui' import { useAppearanceSetting } from '@/context/appearance.context' import type { UserInventoryItem } from '@/services/hooks/market/market.interface' import { Icon } from '@/src/icons' diff --git a/src/layouts/setting/tabs/appearance/components/theme-selector.tsx b/src/layouts/setting/tabs/appearance/components/theme-selector.tsx index dde4cedb..b772bf27 100644 --- a/src/layouts/setting/tabs/appearance/components/theme-selector.tsx +++ b/src/layouts/setting/tabs/appearance/components/theme-selector.tsx @@ -2,8 +2,8 @@ import type React from 'react' import { useEffect, useState } from 'react' import Analytics from '@/analytics' import { callEvent } from '@/common/utils/call-event' -import { ItemSelector } from '@/components/item-selector' -import { SectionPanel } from '@/components/section-panel' +import { ItemSelector } from '@/components/ui' +import { SectionPanel } from '@/components/ui' import { useTheme } from '@/context/theme.context' import type { UserInventoryItem } from '@/services/hooks/market/market.interface' import { Icon } from '@/src/icons' diff --git a/src/layouts/setting/tabs/appearance/components/ui-selector.tsx b/src/layouts/setting/tabs/appearance/components/ui-selector.tsx index ea52d0da..d366c056 100644 --- a/src/layouts/setting/tabs/appearance/components/ui-selector.tsx +++ b/src/layouts/setting/tabs/appearance/components/ui-selector.tsx @@ -1,5 +1,5 @@ -import { ItemSelector } from '@/components/item-selector' -import { SectionPanel } from '@/components/section-panel' +import { ItemSelector } from '@/components/ui' +import { SectionPanel } from '@/components/ui' import { UI, useAppearanceSetting } from '@/context/appearance.context' import { Icon } from '@/src/icons' diff --git a/src/layouts/setting/tabs/general/components/select-city.tsx b/src/layouts/setting/tabs/general/components/select-city.tsx index eedb8fe8..1fda723e 100644 --- a/src/layouts/setting/tabs/general/components/select-city.tsx +++ b/src/layouts/setting/tabs/general/components/select-city.tsx @@ -1,8 +1,8 @@ import { useState, useMemo } from 'react' import Analytics from '@/analytics' -import { IconLoading } from '@/components/loading/icon-loading' -import Modal from '@/components/modal' -import { SectionPanel } from '@/components/section-panel' +import { IconLoading } from '@/components/ui' +import { Modal } from '@/components/ui' +import { SectionPanel } from '@/components/ui' import { useGetCitiesList } from '@/services/hooks/cities/get-cities-list' import { useAuth } from '@/context/auth.context' import { AuthRequiredModal } from '@/components/auth/auth-required-modal' diff --git a/src/layouts/setting/tabs/general/components/timezone-settings.tsx b/src/layouts/setting/tabs/general/components/timezone-settings.tsx index 4587524b..6e9c1592 100644 --- a/src/layouts/setting/tabs/general/components/timezone-settings.tsx +++ b/src/layouts/setting/tabs/general/components/timezone-settings.tsx @@ -1,4 +1,4 @@ -import { SectionPanel } from '@/components/section-panel' +import { SectionPanel } from '@/components/ui' import { useGeneralSetting } from '@/context/general-setting.context' import { useTimezones } from '@/services/hooks/timezone/get-timezones.hook' @@ -22,10 +22,10 @@ export function TimezoneSettings() {
{isLoading ? (
-
+
) : error ? ( -
+
خطا در دریافت اطلاعات مناطق زمانی
) : ( @@ -33,7 +33,7 @@ export function TimezoneSettings() { value={timezone.value} onChange={handleSelectTimezone} className={ - 'w-full rounded-lg appearance-none border-content border select focus:outline-none focus:ring-2 focus:ring-blue-500' + 'w-full rounded-lg appearance-none border-content border select focus:outline-none focus:ring-2 focus:ring-primary' } > {!timezone && ( diff --git a/src/layouts/setting/tabs/general/general.tsx b/src/layouts/setting/tabs/general/general.tsx index 05b62eb1..de6b45fd 100644 --- a/src/layouts/setting/tabs/general/general.tsx +++ b/src/layouts/setting/tabs/general/general.tsx @@ -1,8 +1,8 @@ -import { ToggleSwitch } from '@/components/toggle-switch.component' +import { ToggleSwitch } from '@/components/ui' import { SelectCity } from './components/select-city' import { TimezoneSettings } from './components/timezone-settings' import { useGeneralSetting } from '@/context/general-setting.context' -import { SectionPanel } from '@/components/section-panel' +import { SectionPanel } from '@/components/ui' import Analytics from '@/analytics' export function GeneralSettingTab() { diff --git a/src/layouts/setting/tabs/privacy/components/search-autocomplete.switch.tsx b/src/layouts/setting/tabs/privacy/components/search-autocomplete.switch.tsx index 6e5010a0..5cedac4b 100644 --- a/src/layouts/setting/tabs/privacy/components/search-autocomplete.switch.tsx +++ b/src/layouts/setting/tabs/privacy/components/search-autocomplete.switch.tsx @@ -1,5 +1,5 @@ import { autoFormatErrorToast } from '@/common/toast' -import { ToggleSwitch } from '@/components/toggle-switch.component' +import { ToggleSwitch } from '@/components/ui' import { useAuth } from '@/context/auth.context' import { safeAwait } from '@/services/api' import { useUpdateSearchAutocomplete } from '@/services/hooks/extension/update-setting.hook' diff --git a/src/layouts/setting/tabs/privacy/privacy-settings.tsx b/src/layouts/setting/tabs/privacy/privacy-settings.tsx index 5f556ed3..35b4d922 100644 --- a/src/layouts/setting/tabs/privacy/privacy-settings.tsx +++ b/src/layouts/setting/tabs/privacy/privacy-settings.tsx @@ -1,5 +1,5 @@ -import { SectionPanel } from '@/components/section-panel' -import { ToggleSwitch } from '@/components/toggle-switch.component' +import { SectionPanel } from '@/components/ui' +import { ToggleSwitch } from '@/components/ui' import { useGeneralSetting } from '@/context/general-setting.context' import { SearchAutocompleteSwitch } from './components/search-autocomplete.switch' diff --git a/src/layouts/setting/tabs/shortcuts/shortcuts.tsx b/src/layouts/setting/tabs/shortcuts/shortcuts.tsx index 43c08f06..2a311d45 100644 --- a/src/layouts/setting/tabs/shortcuts/shortcuts.tsx +++ b/src/layouts/setting/tabs/shortcuts/shortcuts.tsx @@ -1,4 +1,4 @@ -import { SectionPanel } from '@/components/section-panel' +import { SectionPanel } from '@/components/ui' import React from 'react' import { useEffect, useState } from 'react' diff --git a/src/layouts/setting/tabs/wallpapers/components/coin-purchase-modal.tsx b/src/layouts/setting/tabs/wallpapers/components/coin-purchase-modal.tsx index 9f0cf411..3fe106b5 100644 --- a/src/layouts/setting/tabs/wallpapers/components/coin-purchase-modal.tsx +++ b/src/layouts/setting/tabs/wallpapers/components/coin-purchase-modal.tsx @@ -1,7 +1,6 @@ import { callEvent } from '@/common/utils/call-event' import type { Wallpaper } from '@/common/wallpaper.interface' -import { Button } from '@/components/button/button' -import Modal from '@/components/modal' +import { Button, Modal } from '@/components/ui' import { useAuth } from '@/context/auth.context' import { UserCoin } from '@/layouts/setting/tabs/account/components/user-coin' import { HoverPlayVideo } from '../tab/gallery/components/hover-play-video' @@ -82,29 +81,35 @@ export function CoinPurchaseModal({
{isAuthenticated ? ( <> - + ) : ( diff --git a/src/layouts/setting/tabs/wallpapers/components/upload-area.component.tsx b/src/layouts/setting/tabs/wallpapers/components/upload-area.component.tsx index d9810d1e..82d271b5 100644 --- a/src/layouts/setting/tabs/wallpapers/components/upload-area.component.tsx +++ b/src/layouts/setting/tabs/wallpapers/components/upload-area.component.tsx @@ -1,9 +1,9 @@ import { useRef } from 'react' import type { Wallpaper } from '@/common/wallpaper.interface' -import { Button } from '@/components/button/button' import { useWallpaperUpload } from '../hooks/use-wallpaper-upload' import { MediaPreview } from './media-preview.component' import { Icon } from '@/src/icons' +import { Button } from '@/components/ui' const MAX_SIZE = 2 const MAX_FILE_SIZE = MAX_SIZE * 1024 * 1024 @@ -76,7 +76,7 @@ export function UploadArea({ customWallpaper, onWallpaperChange }: UploadAreaPro
-
+
{customWallpaper.type === 'IMAGE' ? 'تصویر' : 'ویدیو'}
@@ -89,11 +89,7 @@ export function UploadArea({ customWallpaper, onWallpaperChange }: UploadAreaPro
- diff --git a/src/layouts/setting/tabs/wallpapers/components/wallpaper-sidebar.tsx b/src/layouts/setting/tabs/wallpapers/components/wallpaper-sidebar.tsx index c0885b0a..d2858f72 100644 --- a/src/layouts/setting/tabs/wallpapers/components/wallpaper-sidebar.tsx +++ b/src/layouts/setting/tabs/wallpapers/components/wallpaper-sidebar.tsx @@ -1,8 +1,7 @@ import { useState } from 'react' import type { Category } from '@/common/wallpaper.interface' import { Icon } from '@/src/icons' -import { NewBadge } from '@/components/badges/new.badge' -import { TabNavigation } from '@/components/tab-navigation' +import { NewBadge, TabNavigation } from '@/components/ui' type FilterType = 'all' | 'image' | 'video' type FilterAccess = 'all' | 'free' | 'coin' diff --git a/src/layouts/setting/tabs/wallpapers/tab/gallery/components/wallpaper-item/wallpaper-item.tsx b/src/layouts/setting/tabs/wallpapers/tab/gallery/components/wallpaper-item/wallpaper-item.tsx index b7e08287..13c8c831 100644 --- a/src/layouts/setting/tabs/wallpapers/tab/gallery/components/wallpaper-item/wallpaper-item.tsx +++ b/src/layouts/setting/tabs/wallpapers/tab/gallery/components/wallpaper-item/wallpaper-item.tsx @@ -3,7 +3,7 @@ import type { Wallpaper } from '@/common/wallpaper.interface' import { UserCoin } from '@/layouts/setting/tabs/account/components/user-coin' import { CoinPurchaseModal } from '@/layouts/setting/tabs/wallpapers/components/coin-purchase-modal' import { useLazyLoad } from '../../../../hooks/use-lazy-load' -import Tooltip from '@/components/tool-tip' +import { Tooltip } from '@/components/ui' import { HoverPlayVideo } from '../hover-play-video' import { Icon } from '@/src/icons' import { UI } from '@/context/appearance.context' @@ -41,7 +41,7 @@ function WallpaperItemFu({ const itemOutlineStyle = isSelected ? 'ring-2 ring-primary/80 ring-offset-blue-100' - : 'ring-1 ring-base-content/10 group-hover:ring-blue-300/70' + : 'ring-1 ring-base-content/10 group-hover:ring-primary/70' useEffect(() => { if (loaded && videoRef.current && isSelected) { @@ -90,14 +90,14 @@ function WallpaperItemFu({ onClick={handleSelect} > {!loaded && ( -
-
+
+
)} {error && ( -
- -

خطا در بارگذاری

+
+ +

خطا در بارگذاری

)} diff --git a/src/layouts/simplify/tools-simplify.tsx b/src/layouts/simplify/tools-simplify.tsx index 8eec2716..023ce3a5 100644 --- a/src/layouts/simplify/tools-simplify.tsx +++ b/src/layouts/simplify/tools-simplify.tsx @@ -1,6 +1,6 @@ import Analytics from '@/analytics' import { WidgetContainer } from '../widgets/widget-container' -import { TabNavigation } from '@/components/tab-navigation' +import { TabNavigation } from '@/components/ui' import React, { useState, Suspense } from 'react' import { DateProvider } from '@/context/date.context' import { getFromStorage, setToStorage } from '@/common/storage' @@ -98,7 +98,7 @@ export function SimpleTools() { {ElementData && ( +
در حال بارگذاری...
} diff --git a/src/layouts/simplify/widgets/news-simplify.tsx b/src/layouts/simplify/widgets/news-simplify.tsx index 57b219c0..6eb8393e 100644 --- a/src/layouts/simplify/widgets/news-simplify.tsx +++ b/src/layouts/simplify/widgets/news-simplify.tsx @@ -1,5 +1,5 @@ import { callEvent } from '@/common/utils/call-event' -import { Button } from '@/components/button/button' +import { Button } from '@/components/ui' import { WidgetTabKeys } from '@/layouts/widgets-settings/constant/tab-keys' import { NewsLayout } from '@/layouts/widgets/news/news.layout' import { Icon } from '@/src/icons' @@ -16,7 +16,8 @@ export function NewsSimplify() { diff --git a/src/layouts/widgetify-card/pets/setting/pet-setting.tsx b/src/layouts/widgetify-card/pets/setting/pet-setting.tsx index f83c881b..79b3e1ff 100644 --- a/src/layouts/widgetify-card/pets/setting/pet-setting.tsx +++ b/src/layouts/widgetify-card/pets/setting/pet-setting.tsx @@ -1,9 +1,9 @@ import { useEffect, useState } from 'react' import { getFromStorage } from '@/common/storage' import { callEvent } from '@/common/utils/call-event' -import { ItemSelector } from '@/components/item-selector' +import { ItemSelector } from '@/components/ui' import { TextInput } from '@/components/text-input' -import { ToggleSwitch } from '@/components/toggle-switch.component' +import { ToggleSwitch } from '@/components/ui' import { BASE_PET_OPTIONS, PetTypes } from '@/layouts/widgetify-card/pets/pet.context' export function PetSettings() { diff --git a/src/layouts/widgetify-card/profile-progress.tsx b/src/layouts/widgetify-card/profile-progress.tsx index 9af5599b..bdf24dc1 100644 --- a/src/layouts/widgetify-card/profile-progress.tsx +++ b/src/layouts/widgetify-card/profile-progress.tsx @@ -73,7 +73,7 @@ const RadialProgressSmall = ({ percentage }: any) => { cy={size / 2} r={radius} fill="none" - // className="stroke-blue-100" + // className="stroke-primary" className="stroke-base-content/10" strokeWidth={strokeWidth} /> diff --git a/src/layouts/widgets-settings/manage-widgets/manage-widgets.tsx b/src/layouts/widgets-settings/manage-widgets/manage-widgets.tsx index b33759d6..cee22246 100644 --- a/src/layouts/widgets-settings/manage-widgets/manage-widgets.tsx +++ b/src/layouts/widgets-settings/manage-widgets/manage-widgets.tsx @@ -1,4 +1,4 @@ -import { SectionPanel } from '@/components/section-panel' +import { SectionPanel } from '@/components/ui' import { useAuth } from '@/context/auth.context' import { MAX_VISIBLE_WIDGETS, @@ -7,7 +7,7 @@ import { type WidgetKeys, widgetItems, } from '@/context/widget-visibility.context' -import { ItemSelector } from '../../../components/item-selector' +import { ItemSelector } from '@/components/ui' import { WidgetSettingWrapper } from '../widget-settings-wrapper' import { UI, useAppearanceSetting } from '@/context/appearance.context' @@ -66,7 +66,7 @@ function WidgetItemComponent({ let extraClasses = '' if (isDisabled) { - extraClasses += ' border-red-500/50 bg-red-500/10' + extraClasses += ' border-error/50 bg-error/10' } if (isSoon) { extraClasses += 'border border-warning/50' diff --git a/src/layouts/widgets-settings/widget-settings-modal.tsx b/src/layouts/widgets-settings/widget-settings-modal.tsx index 1ab3d0e9..f4a4fcb3 100644 --- a/src/layouts/widgets-settings/widget-settings-modal.tsx +++ b/src/layouts/widgets-settings/widget-settings-modal.tsx @@ -1,6 +1,6 @@ import Analytics from '@/analytics' import { callEvent } from '@/common/utils/call-event' -import Modal from '@/components/modal' +import { Modal } from '@/components/ui' import { type TabItem, TabManager } from '@/components/tab-manager' import { PetSettings } from '../widgetify-card/pets/setting/pet-setting' import { RssFeedSetting } from '../widgets/news/rss-feed-setting' diff --git a/src/layouts/widgets/calendar/components/calendar-grid.tsx b/src/layouts/widgets/calendar/components/calendar-grid.tsx index 3b60e216..0adc8120 100644 --- a/src/layouts/widgets/calendar/components/calendar-grid.tsx +++ b/src/layouts/widgets/calendar/components/calendar-grid.tsx @@ -5,7 +5,7 @@ import type React from 'react' import { useState } from 'react' import { type WidgetifyDate, formatDateStr } from '../utils' import { DayItem } from './day/day' -import { ClickableTooltip } from '@/components/clickable-tooltip' +import { ClickableTooltip } from '@/components/ui' import { CalendarDayDetails } from './day/tool-tip-content' import { useGetCalendarData } from '@/services/hooks/calendar/get-calendar-data.hook' diff --git a/src/layouts/widgets/calendar/components/day/day.tsx b/src/layouts/widgets/calendar/components/day/day.tsx index 0483d410..f41b61c2 100644 --- a/src/layouts/widgets/calendar/components/day/day.tsx +++ b/src/layouts/widgets/calendar/components/day/day.tsx @@ -90,7 +90,7 @@ export function DayItem({ const getHoverStyle = () => { if (isHoliday) { - return 'hover:bg-red-400/10' + return 'hover:bg-error/10' } return 'hover:bg-primary/10' @@ -132,7 +132,7 @@ export function DayItem({
{hasEvent && ( )}
diff --git a/src/layouts/widgets/calendar/components/day/tool-tip-content.tsx b/src/layouts/widgets/calendar/components/day/tool-tip-content.tsx index 1f176fd2..27c8d011 100644 --- a/src/layouts/widgets/calendar/components/day/tool-tip-content.tsx +++ b/src/layouts/widgets/calendar/components/day/tool-tip-content.tsx @@ -193,15 +193,12 @@ export const CalendarDayDetails: React.FC = ({ {dayEvent.map((event, idx) => (
-
{event.title}
diff --git a/src/layouts/widgets/calendar/components/google-calendar/google-calendar-view.tsx b/src/layouts/widgets/calendar/components/google-calendar/google-calendar-view.tsx index 506c002e..bf6f58c3 100644 --- a/src/layouts/widgets/calendar/components/google-calendar/google-calendar-view.tsx +++ b/src/layouts/widgets/calendar/components/google-calendar/google-calendar-view.tsx @@ -5,11 +5,11 @@ import { useGetGoogleCalendarEvents } from '@/services/hooks/date/get-google-cal import { useDate } from '@/context/date.context' import { CalendarEvent } from './google-event.item' import { useAuth } from '@/context/auth.context' -import { Button } from '@/components/button/button' import { callEvent } from '@/common/utils/call-event' import type { WidgetifyDate } from '../../utils' import { GoogleEventItemSkeleton } from './google-event.item-skeleton' import { Icon } from '@/src/icons' +import { Button } from '@/components/ui' export const GoogleCalendarView: React.FC = () => { const { user, isAuthenticated } = useAuth() diff --git a/src/layouts/widgets/calendar/components/google-calendar/google-event.item.tsx b/src/layouts/widgets/calendar/components/google-calendar/google-event.item.tsx index fa543002..9af938d9 100644 --- a/src/layouts/widgets/calendar/components/google-calendar/google-event.item.tsx +++ b/src/layouts/widgets/calendar/components/google-calendar/google-event.item.tsx @@ -1,4 +1,4 @@ -import Tooltip from '@/components/tool-tip' +import { Tooltip } from '@/components/ui' import { Icon } from '@/src/icons' interface CalendarEventProps { diff --git a/src/layouts/widgets/combo-widget/combo-widget.layout.tsx b/src/layouts/widgets/combo-widget/combo-widget.layout.tsx index a27f3be0..dc81354c 100644 --- a/src/layouts/widgets/combo-widget/combo-widget.layout.tsx +++ b/src/layouts/widgets/combo-widget/combo-widget.layout.tsx @@ -2,12 +2,11 @@ import { useEffect, useState } from 'react' import Analytics from '@/analytics' import { getFromStorage, setToStorage } from '@/common/storage' import { callEvent } from '@/common/utils/call-event' -import { Button } from '@/components/button/button' import { WidgetTabKeys } from '@/layouts/widgets-settings/constant/tab-keys' import { NewsLayout } from '../news/news.layout' import { WidgetContainer } from '../widget-container' import { WigiArzLayout } from '../wigi-arz/wigi_arz.layout' -import { TabNavigation } from '@/components/tab-navigation' +import { Button, TabNavigation } from '@/components/ui' import { Icon } from '@/src/icons' export type ComboTabType = 'news' | 'currency' @@ -83,7 +82,8 @@ export function ComboWidget() { diff --git a/src/layouts/widgets/habit/components/habit-calendar-heatmap.tsx b/src/layouts/widgets/habit/components/habit-calendar-heatmap.tsx index 98790db6..bdbfc5e1 100644 --- a/src/layouts/widgets/habit/components/habit-calendar-heatmap.tsx +++ b/src/layouts/widgets/habit/components/habit-calendar-heatmap.tsx @@ -7,7 +7,7 @@ import { useLogHabitProgress } from '@/services/hooks/habit/log-habit-progress.h import { autoFormatErrorToast, showToast } from '@/common/toast' import { HABIT_UNIT_STEP } from '@/common/constant/habit-options' import { useQueryClient } from '@tanstack/react-query' -import { IconLoading } from '@/components/loading/icon-loading' +import { IconLoading } from '@/components/ui' import { Icon } from '@/src/icons' interface HabitCalendarProps { diff --git a/src/layouts/widgets/habit/components/habit-detail.modal.tsx b/src/layouts/widgets/habit/components/habit-detail.modal.tsx index 38761b3b..373b0cac 100644 --- a/src/layouts/widgets/habit/components/habit-detail.modal.tsx +++ b/src/layouts/widgets/habit/components/habit-detail.modal.tsx @@ -1,10 +1,9 @@ -import Modal from '@/components/modal' +import { Button, Modal } from '@/components/ui' import { useGetHabitDetail } from '@/services/hooks/habit/get-habit-detail.hook' import { HabitCalendar } from './habit-calendar-heatmap' import { useAuth } from '@/context/auth.context' import { formatHabitGoal } from '../utils' -import { Button } from '@/components/button/button' -import { Dropdown } from '@/components/dropdown' +import { Dropdown } from '@/components/ui' import type { Habit } from '@/services/hooks/habit/habit.interface' import { callEvent } from '@/common/utils/call-event' import { Icon } from '@/src/icons' @@ -45,7 +44,7 @@ export function HabitDetailModal({ error, } = useGetHabitDetail(habitId || '', isOpen && isAuthenticated) - const color = habit?.color || '#3b82f6' + const color = habit?.color || '#536dfe' const title = isLoading || !habit ? ( @@ -74,7 +73,8 @@ export function HabitDetailModal({ trigger={ diff --git a/src/layouts/widgets/habit/components/item/habit.item.tsx b/src/layouts/widgets/habit/components/item/habit.item.tsx index 9dc94ec9..84e22feb 100644 --- a/src/layouts/widgets/habit/components/item/habit.item.tsx +++ b/src/layouts/widgets/habit/components/item/habit.item.tsx @@ -12,7 +12,7 @@ import { formatHabitGoal } from '../../utils' import { SegmentedProgressRing } from './button.progress-ring' import { SimpleProgressRing } from './button.simple-progress-ring' import { Icon } from '@/src/icons' -import { IconLoading } from '@/components/loading/icon-loading' +import { IconLoading } from '@/components/ui' interface HabitItemProps { habit: Habit @@ -24,7 +24,7 @@ interface HabitItemProps { export function HabitItem({ habit, today, onChanged, onViewDetails }: HabitItemProps) { const { mutateAsync: logProgress, isPending } = useLogHabitProgress() - const color = habit.color || '#3b82f6' + const color = habit.color || '#536dfe' const target = habit.target || 1 const value = habit.today.value const isSimpleHabit = target === 1 diff --git a/src/layouts/widgets/habit/habits.layout.tsx b/src/layouts/widgets/habit/habits.layout.tsx index 75890774..9df848f2 100644 --- a/src/layouts/widgets/habit/habits.layout.tsx +++ b/src/layouts/widgets/habit/habits.layout.tsx @@ -1,9 +1,8 @@ import { useState } from 'react' import Analytics from '@/analytics' import { autoFormatErrorToast, showToast } from '@/common/toast' -import { Button } from '@/components/button/button' -import { ConfirmationModal } from '@/components/modal/confirmation-modal' -import Tooltip from '@/components/tool-tip' +import { Button, ConfirmationModal } from '@/components/ui' +import { Tooltip } from '@/components/ui' import { useAuth } from '@/context/auth.context' import { useDate } from '@/context/date.context' import { useGeneralSetting } from '@/context/general-setting.context' @@ -106,7 +105,9 @@ export function HabitsContent() {
diff --git a/src/layouts/widgets/notes/components/note-navigation.tsx b/src/layouts/widgets/notes/components/note-navigation.tsx index d5cd1500..2f3d7333 100644 --- a/src/layouts/widgets/notes/components/note-navigation.tsx +++ b/src/layouts/widgets/notes/components/note-navigation.tsx @@ -1,10 +1,9 @@ import { useMemo } from 'react' -import { Button } from '@/components/button/button' -import Tooltip from '@/components/tool-tip' +import { Button, ConfirmationModal, Tooltip } from '@/components/ui' import { useNotes } from '@/context/notes.context' import { useAuth } from '@/context/auth.context' import Analytics from '@/analytics' -import { IconLoading } from '@/components/loading/icon-loading' +import { IconLoading } from '@/components/ui' import { callEvent } from '@/common/utils/call-event' import { Icon } from '@/src/icons' @@ -58,38 +57,20 @@ export function NoteNavigation() { {isSaving && } {activeNoteId ? ( <> - setShowDeleteConfirm(false)} - /> - ) : ( - 'حذف یادداشت' - ) - } - position="bottom" + - + + @@ -101,8 +82,9 @@ export function NoteNavigation() { disabled={isCreatingNote} loading={isCreatingNote} loadingText={} - className={`h-6 w-fit px-2! text-xs font-medium hover:scale-95 rounded-xl`} - isPrimary={true} + className={`h-6 w-fit px-2! text-xs font-medium hover:scale-95`} + variant={'primary'} + rounded={'xl'} > چیزی بنویس @@ -111,8 +93,9 @@ export function NoteNavigation() {
- ) -} -interface Props { - onConfirm: () => void - onCancel: () => void -} -function ToolTipConfirmContent({ onConfirm, onCancel }: Props) { - return ( -
-

- آیا از حذف این یادداشت مطمئن هستید؟ -

-
- - -
+ + setShowDeleteConfirm(false)} + onConfirm={() => onDelete()} + message="از حذف این یادداشت مطمعنی؟" + />
) } diff --git a/src/layouts/widgets/todos/components/friend-item.todo.tsx b/src/layouts/widgets/todos/components/friend-item.todo.tsx index 355a7684..3350e490 100644 --- a/src/layouts/widgets/todos/components/friend-item.todo.tsx +++ b/src/layouts/widgets/todos/components/friend-item.todo.tsx @@ -1,5 +1,5 @@ -import { AvatarComponent } from '@/components/avatar.component' -import Tooltip from '@/components/tool-tip' +import { AvatarComponent } from '@/components/ui' +import { Tooltip } from '@/components/ui' import { Icon } from '@/src/icons' interface UserItemProp { diff --git a/src/layouts/widgets/todos/components/priority.dropdown.tsx b/src/layouts/widgets/todos/components/priority.dropdown.tsx index 511224b3..c5f7332f 100644 --- a/src/layouts/widgets/todos/components/priority.dropdown.tsx +++ b/src/layouts/widgets/todos/components/priority.dropdown.tsx @@ -1,5 +1,4 @@ -import { Dropdown } from '@/components/dropdown' -import { Button } from '@/components/button/button' +import { Button, Dropdown } from '@/components/ui' import { TodoPriority } from '@/services/hooks/todo/todo.interface' import { Icon } from '@/src/icons' @@ -40,7 +39,8 @@ export function PriorityDropdown({ priority, setPriority }: PriorityDropdownProp trigger={ diff --git a/src/layouts/widgets/todos/expandable-todo-input.tsx b/src/layouts/widgets/todos/expandable-todo-input.tsx index 73da3557..70953a5f 100644 --- a/src/layouts/widgets/todos/expandable-todo-input.tsx +++ b/src/layouts/widgets/todos/expandable-todo-input.tsx @@ -1,17 +1,15 @@ import { Motion as motion, Presence } from '@/common/motion' import { useEffect, useRef, useState, useCallback } from 'react' -import { Button } from '@/components/button/button' import { TextInput } from '@/components/text-input' -import { IconLoading } from '@/components/loading/icon-loading' -import { ClickableTooltip } from '@/components/clickable-tooltip' +import { Button, Dropdown, IconLoading } from '@/components/ui' import jalaliMoment from 'jalali-moment' import Analytics from '@/analytics' -import { Chip } from '@/components/chip.component' +import { Chip } from '@/components/ui' import { useGetTags } from '@/services/hooks/todo/get-tags.hook' import { useAuth } from '@/context/auth.context' import { useDate } from '@/context/date.context' -import { DatePicker } from '@/components/date-picker/date-picker' +import { DatePicker } from '@/components/ui' import { PriorityDropdown } from './components/priority.dropdown' import type { FetchedTodo, TodoPriority } from '@/services/hooks/todo/todo.interface' import { type TodoCreationPayload, useAddTodo } from '@/services/hooks/todo/add-todo.hook' @@ -51,15 +49,11 @@ export function ExpandableTodoInput({ const [priority, setPriority] = useState(undefined) const [category, setCategory] = useState('') const { data: fetchedTags } = useGetTags(isAuthenticated && isExpanded) - const [isTagTooltipOpen, setIsTagTooltipOpen] = useState(false) const [selectedDate, setSelectedDate] = useState(today) - const [showDatePicker, setShowDatePicker] = useState(false) const inputRef = useRef(null) const notesRef = useRef(null) const containerRef = useRef(null) - const dateButtonRef = useRef(null) - const categoryInputRef = useRef(null) const notesInputRef = useRef(null) const [selectedFriends, setSelectedFriends] = useState([]) @@ -117,7 +111,7 @@ export function ExpandableTodoInput({ const onSelectCategory = (v: string) => { setCategory(v) - setIsTagTooltipOpen(false) + callEvent('closeAllDropdowns') Analytics.event('todo_category_select') } @@ -164,7 +158,6 @@ export function ExpandableTodoInput({ if (notesInputRef.current) { notesInputRef.current.value = '' } - setIsTagTooltipOpen(false) setCategory('') setPriority(undefined) setSelectedDate(today.clone()) @@ -257,7 +250,9 @@ export function ExpandableTodoInput({ disabled={isPending} loading={isPending} size="sm" - className="rounded-full px-0! w-8 btn-ghost" + rounded={'full'} + variant={'ghost'} + className="px-0! w-8" > @@ -268,8 +263,9 @@ export function ExpandableTodoInput({ loading={isPending} loadingText={} size="sm" - isPrimary={true} - className="rounded-full px-0! w-8" + variant={'primary'} + rounded={'full'} + className="px-0! w-8" > {isEdit ? ( @@ -308,32 +304,93 @@ export function ExpandableTodoInput({ priority={priority} setPriority={setPriority} /> - + } > - -

- {selectedDate - ? formatJalaliDateForDisplay( - selectedDate - ) - : 'تاریخ انجامش'} -

- - + } > - -

- {category || 'دسته‌بندی'} -

- +
+
+ + setCategory(val) + } + placeholder="مثلا: کارهای خونه" + className="duration-75 border-0 bg-transparent!" + /> + +
+
+
+ {fetchedTags + ?.filter((tag) => tag.trim()) + ?.map((tag) => ( + + onSelectCategory(tag) + } + className="flex gap-1 text-xs px-2! py-1!" + > + + {tag} + + ))} +
+
+ {!isEdit && isAuthenticated && (
- -
- setCategory(val)} - placeholder="مثلا: کارهای خونه" - className="duration-75 border-0 bg-transparent!" - /> - -
-
-
- {fetchedTags - ?.filter((tag) => tag.trim()) - ?.map((tag) => ( - - onSelectCategory(tag) - } - className="flex gap-1 text-xs px-2! py-1!" - > - - {tag} - - ))} -
-
- } - /> - { - setSelectedDate(date) - setShowDatePicker(false) - }} - /> - } - />
)} diff --git a/src/layouts/widgets/todos/todo.item.tsx b/src/layouts/widgets/todos/todo.item.tsx index 0891358b..a9e1b92a 100644 --- a/src/layouts/widgets/todos/todo.item.tsx +++ b/src/layouts/widgets/todos/todo.item.tsx @@ -1,8 +1,8 @@ import type React from 'react' import { useState } from 'react' -import CustomCheckbox from '@/components/checkbox' +import { Checkbox } from '@/components/ui' import type { FetchedTodo, Todo } from '@/services/hooks/todo/todo.interface' -import { ConfirmationModal } from '@/components/modal/confirmation-modal' +import { ConfirmationModal } from '@/components/ui' import { useAuth } from '@/context/auth.context' import { showToast } from '@/common/toast' import { useRemoveTodo } from '@/services/hooks/todo/remove-todo.hook' @@ -10,11 +10,11 @@ import { safeAwait } from '@/services/api' import { translateError } from '@/common/utils/translate-error' import { validate } from 'uuid' import Analytics from '@/analytics' -import { IconLoading } from '@/components/loading/icon-loading' +import { IconLoading } from '@/components/ui' import { parseTodoDate } from './tools/parse-date' import { useUpdateTodo } from '@/services/hooks/todo/update-todo.hook' import { playAlarm } from '@/common/play-alarm' -import Tooltip from '@/components/tool-tip' +import { Tooltip } from '@/components/ui' import { TodoFriends } from './components/friends.todo' import { Icon } from '@/src/icons' @@ -118,7 +118,7 @@ export function TodoItem({ todo, blurMode = false, onEdit, onUpdated }: Prop) { >
- @@ -254,7 +254,7 @@ function NoteLinkRenderer({ note }: { note: string }) { href={urls[0]} target="_blank" rel="noopener noreferrer" - className="block text-blue-500 underline break-all" + className="block text-primary underline break-all" > {urls[0]} diff --git a/src/layouts/widgets/todos/todos.tsx b/src/layouts/widgets/todos/todos.tsx index e1992510..41da87e4 100644 --- a/src/layouts/widgets/todos/todos.tsx +++ b/src/layouts/widgets/todos/todos.tsx @@ -2,14 +2,13 @@ import { useState } from 'react' import { ExpandableTodoInput } from './expandable-todo-input' import { useAuth } from '@/context/auth.context' import Analytics from '@/analytics' -import { IconLoading } from '@/components/loading/icon-loading' -import { FilterTooltip } from '@/components/filter-tooltip' +import { Button, IconLoading } from '@/components/ui' +import { FilterTooltip } from '@/components/ui' import { useGetTags } from '@/services/hooks/todo/get-tags.hook' import type { Todo } from '@/services/hooks/todo/todo.interface' import { getFromStorage, setToStorage } from '@/common/storage' import { useGeneralSetting } from '@/context/general-setting.context' -import { Button } from '@/components/button/button' -import Tooltip from '@/components/tool-tip' +import { Tooltip } from '@/components/ui' import { useGetTodos } from '@/services/hooks/todo/get-todos.hook' import { TodoItem } from './todo.item' import { Icon } from '@/src/icons' @@ -245,12 +244,12 @@ export function TodosLayout() { diff --git a/src/layouts/widgets/tools/currency/currency-converter.tsx b/src/layouts/widgets/tools/currency/currency-converter.tsx index deef28c8..d658d204 100644 --- a/src/layouts/widgets/tools/currency/currency-converter.tsx +++ b/src/layouts/widgets/tools/currency/currency-converter.tsx @@ -1,7 +1,7 @@ import { Motion as motion } from "@/common/motion"; import type React from 'react' import { useEffect, useState } from 'react' -import { SelectBox } from '@/components/selectbox/selectbox' +import { SelectBox } from '@/components/ui' import { TextInput } from '@/components/text-input' import { useGetCurrencyByCode } from '@/services/hooks/currency/get-currency-by-code.hook' import { useGetSupportCurrencies } from '@/services/hooks/currency/get-support-currencies.hook' diff --git a/src/layouts/widgets/tools/pomodoro/components/control-button.tsx b/src/layouts/widgets/tools/pomodoro/components/control-button.tsx index 279c196a..c58e4a17 100644 --- a/src/layouts/widgets/tools/pomodoro/components/control-button.tsx +++ b/src/layouts/widgets/tools/pomodoro/components/control-button.tsx @@ -1,4 +1,4 @@ -import { Button } from '@/components/button/button' +import { Button } from '@/components/ui' import type React from 'react' interface ControlButtonProps { diff --git a/src/layouts/widgets/tools/pomodoro/components/mode-button.tsx b/src/layouts/widgets/tools/pomodoro/components/mode-button.tsx index 3a7e1598..9508995a 100644 --- a/src/layouts/widgets/tools/pomodoro/components/mode-button.tsx +++ b/src/layouts/widgets/tools/pomodoro/components/mode-button.tsx @@ -1,5 +1,5 @@ +import { Button } from '@/components/ui' import type React from 'react' -import { Button } from '@/components/button/button' interface ModeButtonProps { label: string diff --git a/src/layouts/widgets/tools/pomodoro/components/request-notification-modal.tsx b/src/layouts/widgets/tools/pomodoro/components/request-notification-modal.tsx index e6e52ad9..26acd330 100644 --- a/src/layouts/widgets/tools/pomodoro/components/request-notification-modal.tsx +++ b/src/layouts/widgets/tools/pomodoro/components/request-notification-modal.tsx @@ -1,6 +1,5 @@ import Analytics from '@/analytics' -import { Button } from '@/components/button/button' -import Modal from '@/components/modal' +import { Button, Modal } from '@/components/ui' import { showToast } from '@/common/toast' interface Prop { @@ -67,7 +66,6 @@ export function RequestNotificationModal({
- {/* Content */}

برای اینکه به شما یادآوری کنیم، نیاز داریم اعلان‌ها را فعال @@ -77,24 +75,26 @@ export function RequestNotificationModal({

- {/* Actions */}
diff --git a/src/layouts/widgets/tools/pomodoro/components/settings-panel.tsx b/src/layouts/widgets/tools/pomodoro/components/settings-panel.tsx index 85ddfff9..460eacd2 100644 --- a/src/layouts/widgets/tools/pomodoro/components/settings-panel.tsx +++ b/src/layouts/widgets/tools/pomodoro/components/settings-panel.tsx @@ -1,7 +1,6 @@ import type React from 'react' -import { Button } from '@/components/button/button' -import CustomCheckbox from '@/components/checkbox' -import Modal from '@/components/modal' +import { Button, Checkbox } from '@/components/ui' +import { Modal } from '@/components/ui' import { TextInput } from '@/components/text-input' import type { PomodoroSettings } from '../types' @@ -101,7 +100,7 @@ export const PomodoroSettingsPanel: React.FC = ({ max={30} />
- handleSettingChange( @@ -133,8 +132,9 @@ export const PomodoroSettingsPanel: React.FC = ({ diff --git a/src/layouts/widgets/tools/pomodoro/components/timer-display.tsx b/src/layouts/widgets/tools/pomodoro/components/timer-display.tsx index 86182961..2eb4858c 100644 --- a/src/layouts/widgets/tools/pomodoro/components/timer-display.tsx +++ b/src/layouts/widgets/tools/pomodoro/components/timer-display.tsx @@ -32,7 +32,7 @@ export const TimerDisplay: React.FC = ({ cy="50" r="45" fill="none" - stroke="#f3f4f6" + className="stroke-base-content/10" strokeWidth="5" filter="url(#shadow)" /> @@ -55,7 +55,7 @@ export const TimerDisplay: React.FC = ({ cy="50" r="40" fill="none" - stroke="#ffffff10" + className="stroke-base-content/[0.06]" strokeWidth="1" /> = ({ type }) => { if (isLoading) { return (
-
+
) } diff --git a/src/layouts/widgets/tools/tools.layout.tsx b/src/layouts/widgets/tools/tools.layout.tsx index 5181dbef..d1a0180a 100644 --- a/src/layouts/widgets/tools/tools.layout.tsx +++ b/src/layouts/widgets/tools/tools.layout.tsx @@ -4,7 +4,7 @@ import Analytics from '@/analytics' import { getFromStorage, setToStorage } from '@/common/storage' import { useDate } from '@/context/date.context' import { WidgetContainer } from '../widget-container' -import { TabNavigation } from '@/components/tab-navigation' +import { TabNavigation } from '@/components/ui' import { MdOutlineCurrencyExchange, MdOutlineMosque, diff --git a/src/layouts/widgets/weather/current/current-box.weather.tsx b/src/layouts/widgets/weather/current/current-box.weather.tsx index f998281e..32371662 100644 --- a/src/layouts/widgets/weather/current/current-box.weather.tsx +++ b/src/layouts/widgets/weather/current/current-box.weather.tsx @@ -1,6 +1,6 @@ import type { FetchedWeather } from '@/layouts/widgets/weather/weather.interface' import { unitsFlag } from '../unit-symbols' -import Tooltip from '@/components/tool-tip' +import { Tooltip } from '@/components/ui' import { Icon } from '@/src/icons' interface CurrentWeatherBoxProps { diff --git a/src/layouts/widgets/widget-container.tsx b/src/layouts/widgets/widget-container.tsx index 473850f8..ebfc5ce4 100644 --- a/src/layouts/widgets/widget-container.tsx +++ b/src/layouts/widgets/widget-container.tsx @@ -12,7 +12,7 @@ export function WidgetContainer({ }: WidgetContainerProps) { return (
{children} diff --git a/src/layouts/widgets/wigi-arz/components/arz-header.tsx b/src/layouts/widgets/wigi-arz/components/arz-header.tsx index 7c07002f..8824e2ed 100644 --- a/src/layouts/widgets/wigi-arz/components/arz-header.tsx +++ b/src/layouts/widgets/wigi-arz/components/arz-header.tsx @@ -1,4 +1,4 @@ -import { Button } from '@/components/button/button' +import { Button } from '@/components/ui' import { Icon } from '@/src/icons' interface ArzHeaderProps { @@ -17,7 +17,8 @@ export const ArzHeader = ({ title, onSettingsClick }: ArzHeaderProps) => {

- ارزهای مورد نظر خود را اضافه کنید. + ارزهای مورد نظر خود را اضافه کنید

diff --git a/src/layouts/widgets/wigi-pad/clock-display/clock-display.tsx b/src/layouts/widgets/wigi-pad/clock-display/clock-display.tsx index 73f33047..1e3fe0ea 100644 --- a/src/layouts/widgets/wigi-pad/clock-display/clock-display.tsx +++ b/src/layouts/widgets/wigi-pad/clock-display/clock-display.tsx @@ -1,13 +1,10 @@ import { useEffect, useState } from 'react' import { getFromStorage } from '@/common/storage' -import { callEvent, listenEvent } from '@/common/utils/call-event' -import { Button } from '@/components/button/button' +import { listenEvent } from '@/common/utils/call-event' import { useGeneralSetting } from '@/context/general-setting.context' -import { WidgetTabKeys } from '@/layouts/widgets-settings/constant/tab-keys' import { type ClockSettings, ClockType } from './clock-setting.interface' import { AnalogClock } from './clocks/analog.clock' import { DigitalClock } from './clocks/digital.clock' -import { Icon } from '@/src/icons' export function ClockDisplay() { const [clockSettings, setClockSettings] = useState(null) @@ -48,22 +45,8 @@ export function ClockDisplay() { return null } - function onClickSettings() { - callEvent('openWidgetsSettings', { tab: WidgetTabKeys.wigiPad }) - } - return (
-
- -
-
{clockSettings.clockType === 'analog' ? ( diff --git a/src/layouts/widgets/wigi-pad/clock-display/clock-setting.tsx b/src/layouts/widgets/wigi-pad/clock-display/clock-setting.tsx index dda93e0e..003d58e1 100644 --- a/src/layouts/widgets/wigi-pad/clock-display/clock-setting.tsx +++ b/src/layouts/widgets/wigi-pad/clock-display/clock-setting.tsx @@ -2,8 +2,8 @@ import { useEffect, useState } from 'react' import Analytics from '@/analytics' import { getFromStorage, setToStorage } from '@/common/storage' import { callEvent } from '@/common/utils/call-event' -import { CheckBoxWithDescription } from '@/components/checkbox-description.component' -import { ItemSelector } from '@/components/item-selector' +import { CheckBoxWithDescription } from '@/components/ui' +import { ItemSelector } from '@/components/ui' import { type ClockSettings, ClockType } from './clock-setting.interface' const CLOCK_OPTIONS = [ diff --git a/src/layouts/widgets/wigi-pad/clock-display/clocks/analog.clock.tsx b/src/layouts/widgets/wigi-pad/clock-display/clocks/analog.clock.tsx index b0a56670..80395f0d 100644 --- a/src/layouts/widgets/wigi-pad/clock-display/clocks/analog.clock.tsx +++ b/src/layouts/widgets/wigi-pad/clock-display/clocks/analog.clock.tsx @@ -98,7 +98,7 @@ export function AnalogClock({ timezone, setting }: AnalogClockProps) { x2={60 + 50 * Math.cos(((minuteAngle - 90) * Math.PI) / 180)} y2={60 + 50 * Math.sin(((minuteAngle - 90) * Math.PI) / 180)} strokeWidth="4" - className="transition-transform duration-300 ease-out stroke-gray-400" + className="transition-transform duration-300 ease-out stroke-base-content/40" strokeLinecap="round" /> diff --git a/src/layouts/widgets/wigi-pad/date-display/date-setting.tsx b/src/layouts/widgets/wigi-pad/date-display/date-setting.tsx index 823192fa..4dc85d71 100644 --- a/src/layouts/widgets/wigi-pad/date-display/date-setting.tsx +++ b/src/layouts/widgets/wigi-pad/date-display/date-setting.tsx @@ -2,7 +2,7 @@ import { useState } from 'react' import Analytics from '@/analytics' import { getFromStorage, setToStorage } from '@/common/storage' import { callEvent } from '@/common/utils/call-event' -import { ItemSelector } from '@/components/item-selector' +import { ItemSelector } from '@/components/ui' import { WigiPadDateType } from './date-setting.interface' const DateOptions = [ diff --git a/src/layouts/widgets/wigi-pad/date-display/date.display.tsx b/src/layouts/widgets/wigi-pad/date-display/date.display.tsx index e644c0f9..92cfe6e0 100644 --- a/src/layouts/widgets/wigi-pad/date-display/date.display.tsx +++ b/src/layouts/widgets/wigi-pad/date-display/date.display.tsx @@ -1,11 +1,8 @@ import { getFromStorage } from '@/common/storage' -import { callEvent, listenEvent } from '@/common/utils/call-event' -import { Button } from '@/components/button/button' -import { WidgetTabKeys } from '@/layouts/widgets-settings/constant/tab-keys' +import { listenEvent } from '@/common/utils/call-event' import { type WigiPadDateSetting, WigiPadDateType } from './date-setting.interface' import { GregorianDate } from './dates/gregorian.date' import { JalaliDate } from './dates/jalali.date' -import { Icon } from '@/src/icons' export function DateDisplay() { const [wigiPadDateSettings, setWigiPadDateSettings] = @@ -37,26 +34,12 @@ export function DateDisplay() { return null } - const onClickSettings = () => { - callEvent('openWidgetsSettings', { tab: WidgetTabKeys.wigiPad }) - } - return (
-
- -
- {wigiPadDateSettings.dateType === WigiPadDateType.Jalali ? ( ) : ( diff --git a/src/layouts/widgets/wigi-pad/wigi-pad-setting.tsx b/src/layouts/widgets/wigi-pad/wigi-pad-setting.tsx index 9da578e8..7651c23e 100644 --- a/src/layouts/widgets/wigi-pad/wigi-pad-setting.tsx +++ b/src/layouts/widgets/wigi-pad/wigi-pad-setting.tsx @@ -1,4 +1,4 @@ -import { SectionPanel } from '@/components/section-panel' +import { SectionPanel } from '@/components/ui' import { WidgetSettingWrapper } from '@/layouts/widgets-settings/widget-settings-wrapper' import { ClockSetting } from './clock-display/clock-setting' import { WigiPadDateSettingsModal } from './date-display/date-setting' diff --git a/src/layouts/widgets/yadkar/yadkar.tsx b/src/layouts/widgets/yadkar/yadkar.tsx index d9124f13..40db406f 100644 --- a/src/layouts/widgets/yadkar/yadkar.tsx +++ b/src/layouts/widgets/yadkar/yadkar.tsx @@ -2,7 +2,7 @@ import { useState } from 'react' import Analytics from '@/analytics' import { NotesLayout } from '../notes/notes.layout' import { TodosLayout } from '../todos/todos' -import { TabNavigation } from '@/components/tab-navigation' +import { TabNavigation } from '@/components/ui' import { WidgetContainer } from '../widget-container' import { HabitsContent } from '../habit/habits.layout' import { getFromStorage, setToStorage } from '@/common/storage' diff --git a/src/pages/home/dialog/dialog.tsx b/src/pages/home/dialog/dialog.tsx index ba4f938e..734f138f 100644 --- a/src/pages/home/dialog/dialog.tsx +++ b/src/pages/home/dialog/dialog.tsx @@ -1,8 +1,7 @@ import Analytics from '@/analytics' import { getContrastingTextColor } from '@/common/color' import { callEvent } from '@/common/utils/call-event' -import { Button } from '@/components/button/button' -import Modal from '@/components/modal' +import { Button, Modal } from '@/components/ui' import { useAuth } from '@/context/auth.context' import { safeAwait } from '@/services/api' import { diff --git a/src/pages/home/home.page.tsx b/src/pages/home/home.page.tsx index 9cd04c42..790f780d 100644 --- a/src/pages/home/home.page.tsx +++ b/src/pages/home/home.page.tsx @@ -151,7 +151,7 @@ export function HomePage() { options={{ showProgress: true, skipBeacon: true, - primaryColor: '#3b82f6', + primaryColor: '#536dfe', dismissKeyAction: 'close', buttons: ['skip', 'primary', 'back'], }} diff --git a/src/pages/root.tsx b/src/pages/root.tsx index 6efcabfb..09fd787d 100644 --- a/src/pages/root.tsx +++ b/src/pages/root.tsx @@ -25,7 +25,7 @@ export function RootLayout() { useWallpaperApply() return ( -
+
@@ -36,14 +36,14 @@ export function RootLayout() { toastOptions={{ error: { style: { - backgroundColor: '#f8d7da', - color: '#721c24', + backgroundColor: 'var(--color-error)', + color: 'var(--color-error-content)', }, }, success: { style: { - backgroundColor: '#d4edda', - color: '#155724', + backgroundColor: 'var(--color-success)', + color: 'var(--color-success-content)', }, }, duration: 5000,