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
45 changes: 32 additions & 13 deletions src/context/todo.context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { useUpdateTodo } from '@/services/hooks/todo/update-todo.hook'
import { useGetTodos } from '@/services/hooks/todo/get-todos.hook'
import type { FetchedTodo, Todo } from '@/services/hooks/todo/todo.interface'
import { playAlarm } from '@/common/playAlarm'
import { sleep } from '@/common/utils/timeout'

export enum TodoViewType {
Day = 'day',
Expand Down Expand Up @@ -159,17 +160,21 @@ export function TodoProvider({ children }: { children: React.ReactNode }) {
? Math.max(...sameDateTodos.map((t) => t.order || 0))
: 0

const [err, _] = await safeAwait(
addTodoAsync({
text: input.text,
completed: false,
date: input.date,
priority: input.priority || TodoPriority.Low,
category: input.category || '',
order: maxOrder + 1,
description: input.notes || '',
})
)
const item: any = {
text: input.text,
completed: false,
date: input.date,
priority: input.priority || TodoPriority.Low,
category: input.category || '',
order: maxOrder + 1,
description: input.notes || '',
}
const id = `temp-${Date.now()}`
old.unshift({ ...item, order: 0, id })
setTodos(() => old)

await sleep(3000)
const [err, _] = await safeAwait(addTodoAsync(item))
if (err) {
const content = translateError(err)
if (typeof content === 'string') {
Expand Down Expand Up @@ -201,6 +206,20 @@ export function TodoProvider({ children }: { children: React.ReactNode }) {
)
}
const isCompleted = !current.completed

setTodos((prev) => {
if (!prev) return prev
return prev.map((todo) => {
if (todo.id === id || todo.onlineId === id) {
return {
...todo,
completed: isCompleted,
}
}
return todo
})
})

const [err, _] = await safeAwait(
updateTodoAsync({
id: onlineId,
Expand All @@ -214,9 +233,9 @@ export function TodoProvider({ children }: { children: React.ReactNode }) {
showToast(translateError(err) as string, 'error')
return
}
refetch()
Analytics.event('todo_toggled')

if (isCompleted) playAlarm('done_todo')
Analytics.event('todo_toggled')
}

const updateTodo = async (id: string, updates: Partial<Omit<Todo, 'id'>>) => {
Expand Down
27 changes: 6 additions & 21 deletions src/context/widget-visibility.context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ import CalendarLayout from '@/layouts/widgets/calendar/calendar'
import { ComboWidget } from '@/layouts/widgets/comboWidget/combo-widget.layout'
import { NetworkLayout } from '@/layouts/widgets/network/network.layout'
import { NewsLayout } from '@/layouts/widgets/news/news.layout'
import { NotesLayout } from '@/layouts/widgets/notes/notes.layout'
import { TodosLayout } from '@/layouts/widgets/todos/todos'
import { ToolsLayout } from '@/layouts/widgets/tools/tools.layout'
import { WeatherLayout } from '@/layouts/widgets/weather/weather.layout'
import { WigiArzLayout } from '@/layouts/widgets/wigiArz/wigi_arz.layout'
Expand All @@ -22,6 +20,7 @@ import { useAuth } from './auth.context'
import { CurrencyProvider } from './currency.context'
import { showToast } from '@/common/toast'
import { YadkarWidget } from '@/layouts/widgets/yadkar/yadkar'
import { TodoProvider } from './todo.context'

export enum WidgetKeys {
comboWidget = 'comboWidget',
Expand Down Expand Up @@ -65,7 +64,11 @@ export const widgetItems: WidgetItem[] = [
emoji: '📒',
label: 'یادکار (وظایف و یادداشت)',
order: 0,
node: <YadkarWidget />,
node: (
<TodoProvider>
<YadkarWidget />
</TodoProvider>
),
canToggle: true,
isNew: true,
},
Expand Down Expand Up @@ -139,24 +142,6 @@ export const widgetItems: WidgetItem[] = [
disabled: true,
soon: true,
},
{
id: WidgetKeys.todos,
emoji: '✅',
label: 'وظایف',
order: 2,
node: <TodosLayout />,
canToggle: false,
disabled: true,
},
{
id: WidgetKeys.notes,
emoji: '📝',
label: 'یادداشت‌ها',
order: 7,
node: <NotesLayout />,
canToggle: false,
disabled: true,
},
]

interface WidgetVisibilityContextType {
Expand Down
4 changes: 1 addition & 3 deletions src/layouts/widgetify-card/widgetify.layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { useAuth } from '@/context/auth.context'
import { useGeneralSetting } from '@/context/general-setting.context'
import { WidgetContainer } from '../widgets/widget-container'
import { NotificationCenter } from './notification-center/notification-center'
import { TodoOverviewCard } from './overviewCards/todo-overviewCard'
import { Pet } from './pets/pet'
import { PetProvider } from './pets/pet.context'
import Snowfall from 'react-snowfall'
Expand All @@ -26,7 +25,6 @@ export const WidgetifyLayout = () => {
const newBlurMode = !blurMode
updateSetting('blurMode', newBlurMode)
}

return (
<WidgetContainer className="overflow-hidden !h-72 !min-h-72 !max-h-72">
<div className="relative w-full h-full">
Expand Down Expand Up @@ -60,7 +58,7 @@ export const WidgetifyLayout = () => {
<div
className={`flex flex-col gap-1 ${blurMode ? 'blur-mode' : 'disabled-blur-mode'}`}
>
<TodoOverviewCard />
{/* <TodoOverviewCard /> */}
{/* <GoogleOverviewCard /> */}
</div>
<NotificationCenter />
Expand Down
120 changes: 98 additions & 22 deletions src/layouts/widgets/calendar/calendar.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,112 @@
import type React from 'react'
import { type ReactNode, useState } from 'react'
import GoogleCalendar from '@/assets/google-calendar.png'
import { useDate } from '@/context/date.context'
import { WidgetContainer } from '../widget-container'
import { CalendarGrid } from './components/calendar-grid'
import { CalendarHeader } from './components/calendar-header'
import { DaySummary } from './components/day-summary'
import { GoogleCalendarView } from './components/google-calendar/google-calendar-view'
import { FcCalendar } from 'react-icons/fc' // استفاده از لوگوی رنگی گوگل برای جلوه بهتر
import Analytics from '@/analytics'

const CalendarLayout: React.FC<any> = () => {
const { currentDate, selectedDate, setCurrentDate, setSelectedDate, goToToday } =
useDate()
interface TabItem {
label: string
value: string
icon?: ReactNode
}

interface CalendarTabSelectorProps {
tabs: TabItem[]
activeTab: string
setActiveTab: (tab: string) => void
}

const CalendarTabSelector: React.FC<CalendarTabSelectorProps> = ({
tabs,
activeTab,
setActiveTab,
}) => {
return (
<WidgetContainer
className={
'flex flex-col overflow-hidden md:flex-1 w-full transition-all duration-300'
}
>
<CalendarHeader
currentDate={currentDate}
setCurrentDate={setCurrentDate}
selectedDate={selectedDate}
goToToday={goToToday}
/>
<div className="p-1 mt-1 shrink-0">
<div
role="tablist"
className="flex w-full gap-2 p-1.5 bg-base-200/50 rounded-2xl border border-base-300/30"
>
{tabs.map((tab) => (
<button
key={tab.value}
onClick={() => setActiveTab(tab.value)}
className={`flex-1 flex items-center justify-center gap-2 h-9 rounded-xl text-[11px] cursor-pointer font-bold transition-all duration-200 ${
activeTab === tab.value
? 'bg-base-100/30 text-primary-content border border-base-300 shadow-md scale-[1.02]'
: 'text-base-content border border-transparent opacity-60 hover:opacity-100 hover:bg-base-100/50'
}`}
>
{tab.icon}
{tab.label}
</button>
))}
</div>
</div>
)
}

<CalendarGrid
currentDate={currentDate}
selectedDate={selectedDate}
setSelectedDate={setSelectedDate}
const tabs = [
{
label: 'تقویم',
value: 'calendar',
icon: <FcCalendar size={18} />,
},
{
label: 'گوگل‌کلندر',
value: 'google',
icon: (
<img
src={GoogleCalendar}
alt="Google Calendar"
className="w-5 h-5 rounded-sm"
/>
),
},
]
const CalendarLayout: React.FC = () => {
const { currentDate, selectedDate, setCurrentDate, setSelectedDate, goToToday } =
useDate()
const [activeTab, setActiveTab] = useState<string>('calendar')

const onSetActiveTab = (tab: string) => {
setActiveTab(tab)
Analytics.event(`calendar_tab_switch_to_${tab}`)
}

<div className="flex-1 mt-2">
<DaySummary selectedDate={selectedDate} />
return (
<WidgetContainer className="flex flex-col w-full overflow-hidden transition-all duration-300 md:flex-1">
<div className="flex flex-col flex-1 overflow-hidden">
{activeTab === 'calendar' ? (
<>
<CalendarHeader
currentDate={currentDate}
selectedDate={selectedDate}
setCurrentDate={setCurrentDate}
goToToday={goToToday}
/>
<div className="h-full">
<CalendarGrid
currentDate={currentDate}
selectedDate={selectedDate}
setSelectedDate={setSelectedDate}
/>
</div>
</>
) : (
<GoogleCalendarView />
)}
</div>

<CalendarTabSelector
tabs={tabs}
activeTab={activeTab}
setActiveTab={onSetActiveTab}
/>
</WidgetContainer>
)
}
Expand Down
14 changes: 8 additions & 6 deletions src/layouts/widgets/calendar/components/calendar-grid.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useAuth } from '@/context/auth.context'
import { useGeneralSetting } from '@/context/general-setting.context'
import { useTodoStore } from '@/context/todo.context'
import { useGetEvents } from '@/services/hooks/date/getEvents.hook'
import type React from 'react'
import { useState } from 'react'
Expand Down Expand Up @@ -29,7 +28,12 @@ export const CalendarGrid: React.FC<CalendarGridProps> = ({
const [clickedElement, setClickedElement] = useState<HTMLDivElement | null>(null)

const { data: events } = useGetEvents()
const { todos } = useTodoStore()

const eventsForCalendar = events || {
gregorianEvents: [],
hijriEvents: [],
shamsiEvents: [],
}

const { data: calendarData, refetch } = useGetCalendarData(
isAuthenticated,
Expand Down Expand Up @@ -76,11 +80,10 @@ export const CalendarGrid: React.FC<CalendarGridProps> = ({
key={`day-${i}`}
currentDate={currentDate}
day={i + 1}
events={events}
events={eventsForCalendar}
googleEvents={calendarData?.googleEvents || []}
selectedDateStr={selectedDateStr}
setSelectedDate={setSelectedDate}
todos={todos}
timezone={timezone.value}
moods={calendarData?.moods ?? []}
onClick={(element) => {
Expand Down Expand Up @@ -109,8 +112,7 @@ export const CalendarGrid: React.FC<CalendarGridProps> = ({
triggerRef={{ current: clickedElement }}
content={
<CalendarDayDetails
events={events}
googleEvents={calendarData?.googleEvents || []}
events={eventsForCalendar}
moods={calendarData?.moods ?? []}
onMoodChange={() => refetch()}
/>
Expand Down
Loading