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
61 changes: 61 additions & 0 deletions src/components/Chatbot/TaskAdditionConfirmationDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { ConfirmationDialog } from '@/components/common'

interface TaskAdditionConfirmationDialogProps {
confirmationOpen: boolean
setConfirmationOpen: (open: boolean) => void
pendingTask: Task | null
confirmAddTask: () => void
}

const TaskAdditionConfirmationDialog = ({
confirmationOpen,
setConfirmationOpen,
pendingTask,
confirmAddTask,
}: TaskAdditionConfirmationDialogProps) => {
return (
<ConfirmationDialog
open={confirmationOpen}
onClose={() => setConfirmationOpen(false)}
onConfirm={confirmAddTask}
title="Confirm Task Addition"
description={(
<>
Do you want to add the task
{' '}
<strong>{pendingTask?.title}</strong>
{' '}
?
<br />
<strong>{pendingTask?.category}</strong>
{' '}
task with
{' '}
{' '}
<strong>{pendingTask?.priority}</strong>
{' '}
priority
<br />
<br />
On
{' '}
<strong>{pendingTask?.date}</strong>
<br />
From
{' '}
<strong>{pendingTask?.timeRange?.start}</strong>
{' '}
to
{' '}
<strong>{pendingTask?.timeRange?.end}</strong>
</>
)}
confirmText="Add Task"
cancelText="Cancel"
confirmColor="primary"
maxWidth="sm"
/>
)
}

export default TaskAdditionConfirmationDialog
3 changes: 2 additions & 1 deletion src/components/Chatbot/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ interface ChatbotProps {
}

const Chatbot = ({ open, onClose }: ChatbotProps) => {
const { messages, handleSend, isLoading, chatbotError } = useChatbot()
const { messages, handleSend, isLoading, chatbotError, confirmationDialog } = useChatbot()

useEffect(() => {
if (chatbotError != null) {
Expand All @@ -26,6 +26,7 @@ const Chatbot = ({ open, onClose }: ChatbotProps) => {
<MessageList messages={messages} />
<MessageInput onSend={handleSend} isLoading={isLoading} />
</Box>
{confirmationDialog}
</CustomDialog>
)
}
Expand Down
29 changes: 25 additions & 4 deletions src/components/Home/Calendar/TaskDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SmallLoadingCircle } from '@/components/common'
import { ConfirmationDialog, SmallLoadingCircle } from '@/components/common'
import { useScheduleStore } from '@/stores'
import EditIcon from '@mui/icons-material/Edit'
import { Button, Dialog, DialogActions, DialogContent, DialogTitle, IconButton, Typography } from '@mui/material'
Expand All @@ -17,6 +17,7 @@ const TaskDialog = ({ open, selectedTask, handleClose }: TaskDialogProps) => {
const deleteTask = useScheduleStore(state => state.deleteTask)
const [loading, setLoading] = useState(false)
const [editDialogOpen, toggleEditDialog] = useToggle()
const [deleteConfirmationOpen, toggleDeleteConfirmation] = useToggle()

let actualDateTime = dayjs(selectedTask?.date).format('MMMM D, YYYY')
if (selectedTask?.timeRange) {
Expand All @@ -40,8 +41,9 @@ const TaskDialog = ({ open, selectedTask, handleClose }: TaskDialogProps) => {
finally {
handleClose()
setLoading(false)
toggleDeleteConfirmation()
}
}, [deleteTask, handleClose, selectedTask])
}, [deleteTask, handleClose, selectedTask, toggleDeleteConfirmation])

const getRecurrenceText = (pattern: RecurrencePattern): string => {
const intervalText = pattern.interval === 1 ? '' : `every ${pattern.interval} `
Expand Down Expand Up @@ -109,10 +111,20 @@ const TaskDialog = ({ open, selectedTask, handleClose }: TaskDialogProps) => {
</DialogContent>

<DialogActions>
<Button onClick={handleDeleteTask} color="error">
<Button
onClick={() => {
toggleDeleteConfirmation()
setLoading(true)
}}
color="error"
>
{loading ? <SmallLoadingCircle text="Delete..." /> : 'Delete'}
</Button>
<Button onClick={handleClose} color="primary">
<Button
onClick={handleClose}
color="primary"
disabled={loading}
>
Close
</Button>
</DialogActions>
Expand All @@ -128,6 +140,15 @@ const TaskDialog = ({ open, selectedTask, handleClose }: TaskDialogProps) => {
action="Edit"
currentTask={selectedTask}
/>

<ConfirmationDialog
open={deleteConfirmationOpen}
title="Delete Task"
description="Are you sure you want to delete this task?"
onConfirm={handleDeleteTask}
onClose={toggleDeleteConfirmation}
maxWidth="xs"
/>
</>
)
}
Expand Down
5 changes: 4 additions & 1 deletion src/components/common/ConfirmationDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ interface ConfirmationDialogProps {
onClose: () => void
onConfirm: () => void
title: string
description?: string
description?: string | React.ReactNode
confirmText?: string
cancelText?: string
confirmColor?: 'primary' | 'error'
maxWidth?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | false
}

const ConfirmationDialog = ({
Expand All @@ -20,6 +21,7 @@ const ConfirmationDialog = ({
confirmText = 'Confirm',
cancelText = 'Cancel',
confirmColor = 'error',
maxWidth,
}: ConfirmationDialogProps) => {
return (
<CustomDialog
Expand All @@ -38,6 +40,7 @@ const ConfirmationDialog = ({
color: confirmColor,
},
]}
maxWidth={maxWidth}
/>
)
}
Expand Down
16 changes: 10 additions & 6 deletions src/components/common/CustomDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ interface CustomDialogProps {
open: boolean
onClose: () => void
title: string
description?: string
description?: string | React.ReactNode
actions?: DialogAction[] // Array of actions for buttons
children?: React.ReactNode // Custom content
maxWidth?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | false
Expand Down Expand Up @@ -47,11 +47,15 @@ const CustomDialog = ({
>
<DialogTitle id="custom-dialog-title">{title}</DialogTitle>
<DialogContent>
{description?.trim() ?? (
<DialogContentText id="custom-dialog-description">
{description}
</DialogContentText>
)}
{
typeof description === 'string'
? description?.trim() ?? (
<DialogContentText id="custom-dialog-description">
{description}
</DialogContentText>
)
: description
}
{children}
</DialogContent>
<DialogActions>
Expand Down
28 changes: 25 additions & 3 deletions src/hooks/useChatbot.ts → src/hooks/useChatbot.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import TaskAdditionConfirmationDialog from '@/components/Chatbot/TaskAdditionConfirmationDialog'
import { useScheduleStore } from '@/stores'
import { DEEPSEEK_API_KEY, DEEPSEEK_API_URL, SYSTEM_PROMPT } from '@/utils/chatbotConst'
import { auth } from '@/utils/firebase'
import { generateUniqueId } from '@zl-asica/react'
import { useCallback, useReducer } from 'react'
import { useCallback, useReducer, useState } from 'react'
import { z } from 'zod'

const chatbotResponseContentSchema = z.object({
Expand Down Expand Up @@ -48,6 +49,8 @@ const useChatbot = () => {
const addTask = useScheduleStore(state => state.addTask)
const [messages, dispatchMessage] = useReducer(messageReducer, [])
const [state, dispatchChatbot] = useReducer(chatbotReducer, { isLoading: false, chatbotError: null })
const [pendingTask, setPendingTask] = useState<Task | null>(null)
const [confirmationOpen, setConfirmationOpen] = useState(false)

const addMessage = useCallback((text: string, sender: 'user' | 'bot') => {
dispatchMessage({
Expand All @@ -61,6 +64,14 @@ const useChatbot = () => {
})
}, [])

const confirmAddTask = async () => {
if (pendingTask) {
await addTask(pendingTask)
setPendingTask(null)
}
setConfirmationOpen(false)
}

const handleSend = useCallback(
async (input: string) => {
if (!DEEPSEEK_API_KEY) {
Expand Down Expand Up @@ -166,7 +177,10 @@ const useChatbot = () => {
isRecurring: false,
recurrencePattern: null,
}
await addTask(newTask)

// Store the task in the state and open the confirmation dialog
setPendingTask(newTask)
setConfirmationOpen(true)
}
}
catch (error_) {
Expand All @@ -179,14 +193,22 @@ const useChatbot = () => {
dispatchChatbot({ type: 'setLoading', payload: false })
}
},
[addMessage, addTask],
[addMessage, setPendingTask, setConfirmationOpen],
)

return {
messages,
handleSend,
isLoading: state.isLoading,
chatbotError: state.chatbotError,
confirmationDialog: (
<TaskAdditionConfirmationDialog
confirmationOpen={confirmationOpen}
setConfirmationOpen={setConfirmationOpen}
pendingTask={pendingTask}
confirmAddTask={confirmAddTask}
/>
),
}
}

Expand Down
Loading