Skip to content

Commit

Permalink
feat(agenda3): ✨ supports hide completed tasks in calendar view
Browse files Browse the repository at this point in the history
  • Loading branch information
haydenull committed Nov 6, 2023
1 parent de28728 commit 7715dd2
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 19 deletions.
2 changes: 1 addition & 1 deletion src/hooks/useSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const useSettings = () => {
const [settings, setAtomSettings] = useAtom(settingsAtom)
const { set: setLocalStorage, value: valueLocalStorage } = useLocalStorageValue<Settings>('settings')

const setSettings = (key: string, value: string) => {
const setSettings = (key: string, value: string | boolean | undefined) => {
const newSettings = set(clone(settings), key, value)
setLocalStorage(newSettings)
setAtomSettings(newSettings)
Expand Down
3 changes: 3 additions & 0 deletions src/newModel/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@ export type Settings = {
repo?: string
token?: string
}
viewOptions?: {
hideCompleted?: boolean
}
}
export const settingsAtom = atom<Settings>({})
11 changes: 8 additions & 3 deletions src/pages/NewDashboard/components/Calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import timeGridPlugin from '@fullcalendar/timegrid'
import { message } from 'antd'
import clsx from 'clsx'
import dayjs from 'dayjs'
import { useAtom } from 'jotai'
import { useAtomValue } from 'jotai'
import React, { forwardRef, useImperativeHandle, useRef, useState } from 'react'
import { IoIosCheckmarkCircle } from 'react-icons/io'

import useAgendaTasks from '@/hooks/useAgendaTasks'
import { deleteTask as deleteTaskBlock, genDurationString, updateDateInfo } from '@/newHelper/block'
import { transformAgendaTaskToCalendarEvent } from '@/newHelper/fullCalendar'
import { settingsAtom } from '@/newModel/settings'
import { tasksWithStartAtom } from '@/newModel/tasks'
import type { CalendarEvent } from '@/types/fullcalendar'
import type { AgendaTask, AgendaTaskWithStart } from '@/types/task'
Expand Down Expand Up @@ -45,9 +46,13 @@ const Calendar = ({ onCalendarTitleChange }: CalendarProps, ref) => {
// const [currentView, setCurrentView] = useState<CalendarView>('dayGridMonth')
const calendarRef = useRef<FullCalendar>(null)
const { updateTaskData, deleteTask, addNewTask } = useAgendaTasks()
const [tasksWithStart] = useAtom(tasksWithStartAtom)
const tasksWithStart = useAtomValue(tasksWithStartAtom)
const settings = useAtomValue(settingsAtom)
const showTasks = tasksWithStart?.filter((task) =>
settings.viewOptions?.hideCompleted ? task.status === 'todo' : true,
)
// const now = dayjs()
const calendarEvents = tasksWithStart?.map(transformAgendaTaskToCalendarEvent)
const calendarEvents = showTasks?.map(transformAgendaTaskToCalendarEvent)

const [editTaskModal, setEditTaskModal] = useState<{
open: boolean
Expand Down
77 changes: 62 additions & 15 deletions src/pages/NewDashboard/components/SettingsModal.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { CopyOutlined, QuestionCircleOutlined, QuestionOutlined } from '@ant-design/icons'
import { Input, Menu, Modal, Tooltip, Typography, message } from 'antd'
import { Checkbox, Input, Menu, Modal, Tooltip, Typography, message } from 'antd'
import type { MenuProps } from 'antd'
import copy from 'copy-to-clipboard'
import { useState } from 'react'

import useSettings from '@/hooks/useSettings'
import { cn } from '@/util/util'

import s from './settingsModal.module.less'

Expand All @@ -22,33 +23,36 @@ import s from './settingsModal.module.less'
// ],
// },
// ]

const tabs = [
{
key: 'viewOptions',
label: 'View Options',
},
{
key: 'shareAgenda',
label: 'Share Agenda',
},
] as const
const SettingsModal = ({ children }: { children?: React.ReactNode }) => {
const [open, setOpen] = useState(false)
const [activeTab, setActiveTab] = useState<(typeof tabs)[number]['key']>('viewOptions')
const { settings, setSettings } = useSettings()

const icsUrl = `https://agenda-ics.haydenhayden.com?repo=${settings.ics?.repo}&token=${settings.ics?.token}`

const onChange = (key: string, value: string) => {
const onChange = (key: string, value: string | boolean | undefined) => {
setSettings(key, value)
}
const onClickCopyIcsUrl = () => {
copy(icsUrl)
message.success('🎉 Copied!')
}

return (
<>
<span onClick={() => setOpen(true)}>{children}</span>
<Modal open={open} footer={null} width={900} onCancel={() => setOpen(false)} wrapClassName={s.modalWrapper}>
<div className="flex">
{/* sidebar */}
<div className="w-[300px] bg-gray-100 px-4 py-4">
<div className="font-semibold">APP SETTINGS</div>
<div className="cursor-pointer bg-gray-200 hover:bg-gray-200 rounded p-2 mt-1">Share Agenda</div>
</div>
{/* content */}
<div className="flex-1">
const renderForm = () => {
switch (activeTab) {
case 'shareAgenda':
return (
<>
<div className="h-14 pl-4 flex items-center font-semibold text-lg border-b">ICS File Setting</div>
<div className="px-4 mt-4 pb-8">
<div className="mt-4">
Expand Down Expand Up @@ -83,7 +87,50 @@ const SettingsModal = ({ children }: { children?: React.ReactNode }) => {
</div>
) : null}
</div>
</>
)
case 'viewOptions':
return (
<>
<div className="h-14 pl-4 flex items-center font-semibold text-lg border-b">View Options</div>
<div className="px-4 mt-4 pb-8">
<div className="mt-4">
<div className="text-gray-500">Calendar</div>
<Checkbox
checked={settings.viewOptions?.hideCompleted}
onChange={(e) => onChange('viewOptions.hideCompleted', e.target.checked)}
>
Hide Completed Tasks
</Checkbox>
</div>
</div>
</>
)
}
}

return (
<>
<span onClick={() => setOpen(true)}>{children}</span>
<Modal open={open} footer={null} width={900} onCancel={() => setOpen(false)} wrapClassName={s.modalWrapper}>
<div className="flex">
{/* sidebar */}
<div className="w-[300px] bg-gray-100 px-4 py-4">
<div className="font-semibold">APP SETTINGS</div>
{tabs.map((tab) => (
<div
key={tab.key}
className={cn('cursor-pointer hover:bg-gray-200 rounded p-2 mt-1', {
'bg-gray-200': tab.key === activeTab,
})}
onClick={() => setActiveTab(tab.key)}
>
{tab.label}
</div>
))}
</div>
{/* content */}
<div className="flex-1">{renderForm()}</div>
</div>
</Modal>
</>
Expand Down

0 comments on commit 7715dd2

Please sign in to comment.