Skip to content

Commit f92f25d

Browse files
authored
Merge pull request #349 from widgetify-app/feat/todo-api
Feat/todo api
2 parents f771141 + 7ff905d commit f92f25d

File tree

21 files changed

+614
-382
lines changed

21 files changed

+614
-382
lines changed

src/common/constant/store.key.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import type { TodoOptions } from '@/context/todo.context'
55
import type { WidgetItem } from '@/context/widget-visibility.context'
66
import type { Bookmark } from '@/layouts/bookmark/types/bookmark.types'
77
import type { PetSettings } from '@/layouts/widgetify-card/pets/pet.context'
8-
import type { Todo } from '@/layouts/widgets/calendar/interface/todo.interface'
98
import type { ComboTabType } from '@/layouts/widgets/comboWidget/combo-widget.layout'
109
import type { WigiNewsSetting } from '@/layouts/widgets/news/rss.interface'
1110
import type {
@@ -26,6 +25,7 @@ import type { RecommendedSite, TrendItem } from '@/services/hooks/trends/getTren
2625
import type { UserProfile } from '@/services/hooks/user/userService.hook'
2726
import type { FetchedYouTubeProfile } from '@/services/hooks/youtube/getYouTubeProfile.hook'
2827
import type { StoredWallpaper, Wallpaper } from '../wallpaper.interface'
28+
import type { Todo } from '@/services/hooks/todo/todo.interface'
2929

3030
export interface StorageKV {
3131
currencies: string[]

src/common/utils/call-event.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ import type { Theme } from '@/context/theme.context'
33
import type { Bookmark } from '@/layouts/bookmark/types/bookmark.types'
44
import type { SyncTarget } from '@/layouts/navbar/sync/sync'
55
import type { PetTypes } from '@/layouts/widgetify-card/pets/pet.context'
6-
import type { Todo } from '@/layouts/widgets/calendar/interface/todo.interface'
76
import type { WigiNewsSetting } from '@/layouts/widgets/news/rss.interface'
87
import type { WeatherSettings } from '@/layouts/widgets/weather/weather.interface'
98
import type { ClockSettings } from '@/layouts/widgets/wigiPad/clock-display/clock-setting.interface'
109
import type { WigiPadDateSetting } from '@/layouts/widgets/wigiPad/date-display/date-setting.interface'
1110
import type { WidgetTabKeys } from '@/layouts/widgets-settings/constant/tab-keys'
1211
import type { StoredWallpaper } from '../wallpaper.interface'
12+
import type { Todo } from '@/services/hooks/todo/todo.interface'
1313

1414
export interface EventName {
1515
startSync: SyncTarget

src/components/checkbox.tsx

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import { memo } from 'react'
22

33
interface CustomCheckboxProps {
44
checked: boolean
5-
onChange: (checked: boolean) => void
5+
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void
66
label?: string
7+
onClick?: (e: React.MouseEvent<HTMLInputElement>) => void
78
className?: string
89
disabled?: boolean
910
unCheckedCheckBoxClassName?: string
@@ -20,6 +21,7 @@ const CustomCheckbox = ({
2021
className = '',
2122
unCheckedCheckBoxClassName = '',
2223
checkedCheckBoxClassName = '',
24+
onClick,
2325
}: CustomCheckboxProps) => {
2426
const getCheckboxStyle = () => {
2527
if (checked) {
@@ -31,15 +33,30 @@ const CustomCheckbox = ({
3133
return 'border-content'
3234
}
3335

36+
const onChangeEvent = (e: React.ChangeEvent<HTMLInputElement>) => {
37+
e.preventDefault()
38+
if (!disabled) {
39+
onChange?.(e)
40+
}
41+
}
42+
43+
const onClickEvent = (e: React.MouseEvent<HTMLInputElement>) => {
44+
e.preventDefault()
45+
if (!disabled) {
46+
onClick?.(e)
47+
}
48+
}
49+
3450
return (
3551
<label className="relative flex items-center transition-transform cursor-pointer group active:scale95">
3652
<div className="relative">
3753
<input
3854
type="checkbox"
3955
className={'sr-only'}
4056
checked={checked}
41-
onChange={(e) => !disabled && onChange(e.target.checked)}
57+
onChange={onChangeEvent}
4258
disabled={disabled}
59+
onClick={onClickEvent}
4360
/>
4461
<div
4562
className={`w-5 h-5 border rounded-md flex items-center justify-center transition-colors duration-200 ${getCheckboxStyle()} ${className}`}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { FiLoader } from 'react-icons/fi'
2+
import Tooltip from '../toolTip'
3+
4+
interface IconLoadingProps {
5+
title?: string
6+
className?: string
7+
}
8+
export function IconLoading({ title, className }: IconLoadingProps) {
9+
if (!title) {
10+
return (
11+
<FiLoader
12+
className={`mx-2 block w-4 h-4 animate-spin text-content ${className}`}
13+
/>
14+
)
15+
}
16+
return (
17+
<Tooltip content={title} position="bottom">
18+
<FiLoader
19+
className={`mx-2 block w-4 h-4 animate-spin text-content ${className}`}
20+
/>
21+
</Tooltip>
22+
)
23+
}

src/components/modal/confirmation-modal.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import type { ReactNode } from 'react'
2-
import { FaSpinner } from 'react-icons/fa'
32
import { FiAlertTriangle, FiCheck, FiTrash2 } from 'react-icons/fi'
43
import { Button } from '../button/button'
54
import Modal from '../modal'
5+
import { IconLoading } from '../loading/icon-loading'
66

77
interface ConfirmationModalProps {
88
isOpen: boolean
99
onClose: () => void
1010
onConfirm: () => void
1111
title?: string
1212
message?: string | ReactNode
13-
confirmText?: string
13+
confirmText?: ReactNode
1414
cancelText?: string
1515
variant?: 'danger' | 'warning' | 'info'
1616
isLoading?: boolean
@@ -103,7 +103,7 @@ export function ConfirmationModal({
103103
loading={isLoading}
104104
loadingText={
105105
<div className="flex items-center gap-1">
106-
<FaSpinner className="animate-spin" size={12} />
106+
<IconLoading className="!mx-0 !text-white" />
107107
<span className="text-xs">در حال انجام...</span>
108108
</div>
109109
}

src/components/text-input.tsx

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useCallback, useEffect, useRef, useState } from 'react'
1+
import { useCallback, useEffect, useRef, useState, memo } from 'react'
22

33
enum TextInputSize {
44
XS = 'xs',
@@ -7,6 +7,7 @@ enum TextInputSize {
77
LG = 'lg',
88
XL = 'xl',
99
}
10+
1011
interface TextInputProps {
1112
id?: string
1213
value: string
@@ -28,7 +29,15 @@ interface TextInputProps {
2829
max?: number
2930
}
3031

31-
export function TextInput({
32+
const sizes: Record<TextInputSize, string> = {
33+
[TextInputSize.XS]: 'input-xs',
34+
[TextInputSize.SM]: 'input-sm',
35+
[TextInputSize.MD]: 'input-md',
36+
[TextInputSize.LG]: 'input-lg',
37+
[TextInputSize.XL]: 'input-xl',
38+
}
39+
40+
export const TextInput = memo(function TextInput({
3241
onChange,
3342
value,
3443
placeholder,
@@ -48,30 +57,27 @@ export function TextInput({
4857
min,
4958
max,
5059
}: TextInputProps) {
51-
const sizes: Record<TextInputSize, string> = {
52-
[TextInputSize.XS]: 'input-xs',
53-
[TextInputSize.SM]: 'input-sm',
54-
[TextInputSize.MD]: 'input-md',
55-
[TextInputSize.LG]: 'input-lg',
56-
[TextInputSize.XL]: 'input-xl',
57-
}
5860
const [localValue, setLocalValue] = useState(value)
5961
const debounceTimerRef = useRef<NodeJS.Timeout | null>(null)
6062

6163
useEffect(() => {
62-
setLocalValue(value)
63-
}, [value])
64+
if (debounce) {
65+
setLocalValue(value)
66+
}
67+
}, [value, debounce])
6468

6569
const handleChange = useCallback(
6670
(e: React.ChangeEvent<HTMLInputElement>) => {
6771
const newValue = e.target.value
68-
setLocalValue(newValue)
6972

7073
if (!debounce) {
74+
// بدون هیچ تاخیری مستقیم onChange را صدا بزن
7175
onChange(newValue)
7276
return
7377
}
7478

79+
setLocalValue(newValue)
80+
7581
if (debounceTimerRef.current) {
7682
clearTimeout(debounceTimerRef.current)
7783
}
@@ -85,13 +91,24 @@ export function TextInput({
8591
},
8692
[onChange, debounce, type, debounceTime]
8793
)
94+
95+
useEffect(() => {
96+
return () => {
97+
if (debounceTimerRef.current) {
98+
clearTimeout(debounceTimerRef.current)
99+
}
100+
}
101+
}, [])
102+
103+
const displayValue = debounce ? localValue : value
104+
88105
return (
89106
<input
90107
ref={ref}
91108
id={id}
92109
type={type}
93110
name={name}
94-
value={localValue}
111+
value={displayValue}
95112
disabled={disabled}
96113
onFocus={onFocus}
97114
onKeyDown={onKeyDown}
@@ -107,4 +124,6 @@ export function TextInput({
107124
max={max}
108125
/>
109126
)
110-
}
127+
})
128+
129+
TextInput.displayName = 'TextInput'

0 commit comments

Comments
 (0)