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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/common/constant/store.key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import type { TodoOptions } from '@/context/todo.context'
import type { WidgetItem } from '@/context/widget-visibility.context'
import type { Bookmark } from '@/layouts/bookmark/types/bookmark.types'
import type { PetSettings } from '@/layouts/widgetify-card/pets/pet.context'
import type { Todo } from '@/layouts/widgets/calendar/interface/todo.interface'
import type { ComboTabType } from '@/layouts/widgets/comboWidget/combo-widget.layout'
import type { WigiNewsSetting } from '@/layouts/widgets/news/rss.interface'
import type {
Expand All @@ -26,6 +25,7 @@ import type { RecommendedSite, TrendItem } from '@/services/hooks/trends/getTren
import type { UserProfile } from '@/services/hooks/user/userService.hook'
import type { FetchedYouTubeProfile } from '@/services/hooks/youtube/getYouTubeProfile.hook'
import type { StoredWallpaper, Wallpaper } from '../wallpaper.interface'
import type { Todo } from '@/services/hooks/todo/todo.interface'

export interface StorageKV {
currencies: string[]
Expand Down
2 changes: 1 addition & 1 deletion src/common/utils/call-event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import type { Theme } from '@/context/theme.context'
import type { Bookmark } from '@/layouts/bookmark/types/bookmark.types'
import type { SyncTarget } from '@/layouts/navbar/sync/sync'
import type { PetTypes } from '@/layouts/widgetify-card/pets/pet.context'
import type { Todo } from '@/layouts/widgets/calendar/interface/todo.interface'
import type { WigiNewsSetting } from '@/layouts/widgets/news/rss.interface'
import type { WeatherSettings } from '@/layouts/widgets/weather/weather.interface'
import type { ClockSettings } from '@/layouts/widgets/wigiPad/clock-display/clock-setting.interface'
import type { WigiPadDateSetting } from '@/layouts/widgets/wigiPad/date-display/date-setting.interface'
import type { WidgetTabKeys } from '@/layouts/widgets-settings/constant/tab-keys'
import type { StoredWallpaper } from '../wallpaper.interface'
import type { Todo } from '@/services/hooks/todo/todo.interface'

export interface EventName {
startSync: SyncTarget
Expand Down
21 changes: 19 additions & 2 deletions src/components/checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { memo } from 'react'

interface CustomCheckboxProps {
checked: boolean
onChange: (checked: boolean) => void
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void
label?: string
onClick?: (e: React.MouseEvent<HTMLInputElement>) => void
className?: string
disabled?: boolean
unCheckedCheckBoxClassName?: string
Expand All @@ -20,6 +21,7 @@ const CustomCheckbox = ({
className = '',
unCheckedCheckBoxClassName = '',
checkedCheckBoxClassName = '',
onClick,
}: CustomCheckboxProps) => {
const getCheckboxStyle = () => {
if (checked) {
Expand All @@ -31,15 +33,30 @@ const CustomCheckbox = ({
return 'border-content'
}

const onChangeEvent = (e: React.ChangeEvent<HTMLInputElement>) => {
e.preventDefault()
if (!disabled) {
onChange?.(e)
}
}

const onClickEvent = (e: React.MouseEvent<HTMLInputElement>) => {
e.preventDefault()
if (!disabled) {
onClick?.(e)
}
}

return (
<label className="relative flex items-center transition-transform cursor-pointer group active:scale95">
<div className="relative">
<input
type="checkbox"
className={'sr-only'}
checked={checked}
onChange={(e) => !disabled && onChange(e.target.checked)}
onChange={onChangeEvent}
disabled={disabled}
onClick={onClickEvent}
/>
<div
className={`w-5 h-5 border rounded-md flex items-center justify-center transition-colors duration-200 ${getCheckboxStyle()} ${className}`}
Expand Down
23 changes: 23 additions & 0 deletions src/components/loading/icon-loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { FiLoader } from 'react-icons/fi'
import Tooltip from '../toolTip'

interface IconLoadingProps {
title?: string
className?: string
}
export function IconLoading({ title, className }: IconLoadingProps) {
if (!title) {
return (
<FiLoader
className={`mx-2 block w-4 h-4 animate-spin text-content ${className}`}
/>
)
}
return (
<Tooltip content={title} position="bottom">
<FiLoader
className={`mx-2 block w-4 h-4 animate-spin text-content ${className}`}
/>
</Tooltip>
)
}
6 changes: 3 additions & 3 deletions src/components/modal/confirmation-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import type { ReactNode } from 'react'
import { FaSpinner } from 'react-icons/fa'
import { FiAlertTriangle, FiCheck, FiTrash2 } from 'react-icons/fi'
import { Button } from '../button/button'
import Modal from '../modal'
import { IconLoading } from '../loading/icon-loading'

interface ConfirmationModalProps {
isOpen: boolean
onClose: () => void
onConfirm: () => void
title?: string
message?: string | ReactNode
confirmText?: string
confirmText?: ReactNode
cancelText?: string
variant?: 'danger' | 'warning' | 'info'
isLoading?: boolean
Expand Down Expand Up @@ -103,7 +103,7 @@ export function ConfirmationModal({
loading={isLoading}
loadingText={
<div className="flex items-center gap-1">
<FaSpinner className="animate-spin" size={12} />
<IconLoading className="!mx-0 !text-white" />
<span className="text-xs">در حال انجام...</span>
</div>
}
Expand Down
47 changes: 33 additions & 14 deletions src/components/text-input.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useCallback, useEffect, useRef, useState } from 'react'
import { useCallback, useEffect, useRef, useState, memo } from 'react'

enum TextInputSize {
XS = 'xs',
Expand All @@ -7,6 +7,7 @@ enum TextInputSize {
LG = 'lg',
XL = 'xl',
}

interface TextInputProps {
id?: string
value: string
Expand All @@ -28,7 +29,15 @@ interface TextInputProps {
max?: number
}

export function TextInput({
const sizes: Record<TextInputSize, string> = {
[TextInputSize.XS]: 'input-xs',
[TextInputSize.SM]: 'input-sm',
[TextInputSize.MD]: 'input-md',
[TextInputSize.LG]: 'input-lg',
[TextInputSize.XL]: 'input-xl',
}

export const TextInput = memo(function TextInput({
onChange,
value,
placeholder,
Expand All @@ -48,30 +57,27 @@ export function TextInput({
min,
max,
}: TextInputProps) {
const sizes: Record<TextInputSize, string> = {
[TextInputSize.XS]: 'input-xs',
[TextInputSize.SM]: 'input-sm',
[TextInputSize.MD]: 'input-md',
[TextInputSize.LG]: 'input-lg',
[TextInputSize.XL]: 'input-xl',
}
const [localValue, setLocalValue] = useState(value)
const debounceTimerRef = useRef<NodeJS.Timeout | null>(null)

useEffect(() => {
setLocalValue(value)
}, [value])
if (debounce) {
setLocalValue(value)
}
}, [value, debounce])

const handleChange = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
const newValue = e.target.value
setLocalValue(newValue)

if (!debounce) {
// بدون هیچ تاخیری مستقیم onChange را صدا بزن
onChange(newValue)
return
}

setLocalValue(newValue)

if (debounceTimerRef.current) {
clearTimeout(debounceTimerRef.current)
}
Expand All @@ -85,13 +91,24 @@ export function TextInput({
},
[onChange, debounce, type, debounceTime]
)

useEffect(() => {
return () => {
if (debounceTimerRef.current) {
clearTimeout(debounceTimerRef.current)
}
}
}, [])

const displayValue = debounce ? localValue : value

return (
<input
ref={ref}
id={id}
type={type}
name={name}
value={localValue}
value={displayValue}
disabled={disabled}
onFocus={onFocus}
onKeyDown={onKeyDown}
Expand All @@ -107,4 +124,6 @@ export function TextInput({
max={max}
/>
)
}
})

TextInput.displayName = 'TextInput'
Loading