From 03ec7a8d9036f84473d9bbb6383a2261999ba00e Mon Sep 17 00:00:00 2001
From: Hemil
Date: Thu, 28 Aug 2025 16:36:23 +0530
Subject: [PATCH 1/4] Add InfoDialog component and integrate with Redux for
state management
---
frontend/src/App.tsx | 3 ++
frontend/src/app/store.ts | 3 ++
frontend/src/components/Dialog/InfoDialog.tsx | 49 +++++++++++++++++++
frontend/src/features/infoDialogSlice.ts | 33 +++++++++++++
frontend/src/pages/SettingsPage/Settings.tsx | 7 +++
frontend/src/types/infoDialog.ts | 5 ++
6 files changed, 100 insertions(+)
create mode 100644 frontend/src/components/Dialog/InfoDialog.tsx
create mode 100644 frontend/src/features/infoDialogSlice.ts
create mode 100644 frontend/src/types/infoDialog.ts
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index 62acd1c0c..c7f51fbff 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -5,10 +5,12 @@ import { AppRoutes } from '@/routes/AppRoutes';
import { ThemeProvider } from '@/contexts/ThemeContext';
import QueryClientProviders from '@/config/QueryClientProvider';
import { GlobalLoader } from './components/Loader/GlobalLoader';
+import { InfoDialog } from './components/Dialog/InfoDialog';
import { useSelector } from 'react-redux';
import { RootState } from './app/store';
const App: React.FC = () => {
const { loading, message } = useSelector((state: RootState) => state.loader);
+ const { isOpen, title, message: infoMessage } = useSelector((state: RootState) => state.infoDialog);
return (
@@ -16,6 +18,7 @@ const App: React.FC = () => {
+
);
diff --git a/frontend/src/app/store.ts b/frontend/src/app/store.ts
index d2849c5d8..4c4d02206 100644
--- a/frontend/src/app/store.ts
+++ b/frontend/src/app/store.ts
@@ -1,10 +1,13 @@
import { configureStore } from '@reduxjs/toolkit';
import loaderReducer from '@/features/loaderSlice';
import onboardingReducer from '@/features/onboardingSlice';
+import infoDialogReducer from '@/features/infoDialogSlice';
+
export const store = configureStore({
reducer: {
loader: loaderReducer,
onboarding: onboardingReducer,
+ infoDialog: infoDialogReducer,
},
});
diff --git a/frontend/src/components/Dialog/InfoDialog.tsx b/frontend/src/components/Dialog/InfoDialog.tsx
new file mode 100644
index 000000000..08e85bef9
--- /dev/null
+++ b/frontend/src/components/Dialog/InfoDialog.tsx
@@ -0,0 +1,49 @@
+import React from 'react';
+import { Info } from 'lucide-react';
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogHeader,
+ DialogTitle,
+ DialogFooter
+} from '@/components/ui/dialog';
+import { Button } from '@/components/ui/button';
+import { InfoDialogProps } from '@/types/infoDialog';
+import { useDispatch } from 'react-redux';
+import { hideInfoDialog } from '@/features/infoDialogSlice';
+
+export const InfoDialog: React.FC = ({
+ isOpen,
+ title,
+ message
+}) => {
+ const dispatch = useDispatch();
+
+ const handleClose = () => {
+ dispatch(hideInfoDialog());
+ };
+
+ return (
+
+ );
+};
diff --git a/frontend/src/features/infoDialogSlice.ts b/frontend/src/features/infoDialogSlice.ts
new file mode 100644
index 000000000..51ac9dd74
--- /dev/null
+++ b/frontend/src/features/infoDialogSlice.ts
@@ -0,0 +1,33 @@
+import { createSlice, PayloadAction } from '@reduxjs/toolkit';
+
+interface InfoDialogState {
+ isOpen: boolean;
+ title: string;
+ message: string;
+}
+
+const initialState: InfoDialogState = {
+ isOpen: false,
+ title: '',
+ message: '',
+};
+
+const infoDialogSlice = createSlice({
+ name: 'infoDialog',
+ initialState,
+ reducers: {
+ showInfoDialog(state, action: PayloadAction<{ title: string; message: string }>) {
+ state.isOpen = true;
+ state.title = action.payload.title;
+ state.message = action.payload.message;
+ },
+ hideInfoDialog(state) {
+ state.isOpen = false;
+ state.title = '';
+ state.message = '';
+ },
+ },
+});
+
+export const { showInfoDialog, hideInfoDialog } = infoDialogSlice.actions;
+export default infoDialogSlice.reducer;
\ No newline at end of file
diff --git a/frontend/src/pages/SettingsPage/Settings.tsx b/frontend/src/pages/SettingsPage/Settings.tsx
index 61a7b400a..980b7216c 100644
--- a/frontend/src/pages/SettingsPage/Settings.tsx
+++ b/frontend/src/pages/SettingsPage/Settings.tsx
@@ -17,6 +17,7 @@ import { usePictoMutation } from '@/hooks/useQueryExtensio';
import { useDispatch } from 'react-redux';
import { showLoader, hideLoader } from '@/features/loaderSlice';
+import { showInfoDialog } from '@/features/infoDialogSlice';
import {
deleteFolder,
@@ -84,6 +85,12 @@ const Settings: React.FC = () => {
const hasUpdate = await checkForUpdates();
if (hasUpdate) {
setUpdateDialogOpen(true);
+ } else {
+ // Show info dialog when no updates are available
+ dispatch(showInfoDialog({
+ title: 'No Updates Available',
+ message: 'Your application is already up to date with the latest version.'
+ }));
}
dispatch(hideLoader());
};
diff --git a/frontend/src/types/infoDialog.ts b/frontend/src/types/infoDialog.ts
new file mode 100644
index 000000000..de86c12c4
--- /dev/null
+++ b/frontend/src/types/infoDialog.ts
@@ -0,0 +1,5 @@
+export interface InfoDialogProps {
+ isOpen: boolean;
+ title: string;
+ message: string;
+}
From 67315f74a57b71b5bab836d26b4c1ac5ac28b0eb Mon Sep 17 00:00:00 2001
From: Hemil
Date: Thu, 28 Aug 2025 18:08:08 +0530
Subject: [PATCH 2/4] Refactor code for improved readability and formatting in
App, InfoDialog, and Settings components
---
frontend/src/App.tsx | 6 ++++-
frontend/src/components/Dialog/InfoDialog.tsx | 25 +++++++++----------
frontend/src/features/infoDialogSlice.ts | 7 ++++--
frontend/src/pages/SettingsPage/Settings.tsx | 11 +++++---
4 files changed, 29 insertions(+), 20 deletions(-)
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index c7f51fbff..305a01635 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -10,7 +10,11 @@ import { useSelector } from 'react-redux';
import { RootState } from './app/store';
const App: React.FC = () => {
const { loading, message } = useSelector((state: RootState) => state.loader);
- const { isOpen, title, message: infoMessage } = useSelector((state: RootState) => state.infoDialog);
+ const {
+ isOpen,
+ title,
+ message: infoMessage,
+ } = useSelector((state: RootState) => state.infoDialog);
return (
diff --git a/frontend/src/components/Dialog/InfoDialog.tsx b/frontend/src/components/Dialog/InfoDialog.tsx
index 08e85bef9..ce54e8ccb 100644
--- a/frontend/src/components/Dialog/InfoDialog.tsx
+++ b/frontend/src/components/Dialog/InfoDialog.tsx
@@ -1,12 +1,12 @@
import React from 'react';
import { Info } from 'lucide-react';
-import {
+import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
- DialogFooter
+ DialogFooter,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { InfoDialogProps } from '@/types/infoDialog';
@@ -16,7 +16,7 @@ import { hideInfoDialog } from '@/features/infoDialogSlice';
export const InfoDialog: React.FC = ({
isOpen,
title,
- message
+ message,
}) => {
const dispatch = useDispatch();
@@ -25,23 +25,22 @@ export const InfoDialog: React.FC = ({
};
return (
-
);
diff --git a/frontend/src/components/Dialog/InfoDialog.tsx b/frontend/src/components/Dialog/InfoDialog.tsx
index ce54e8ccb..7226aa9d5 100644
--- a/frontend/src/components/Dialog/InfoDialog.tsx
+++ b/frontend/src/components/Dialog/InfoDialog.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { Info } from 'lucide-react';
+import { Info, AlertTriangle } from 'lucide-react';
import {
Dialog,
DialogContent,
@@ -17,6 +17,7 @@ export const InfoDialog: React.FC = ({
isOpen,
title,
message,
+ variant = 'info',
}) => {
const dispatch = useDispatch();
@@ -24,6 +25,24 @@ export const InfoDialog: React.FC = ({
dispatch(hideInfoDialog());
};
+ // Define styles and icons based on variant
+ const variantStyles = {
+ info: {
+ iconColor: 'text-primary',
+ messageColor: '',
+ icon: ,
+ buttonVariant: 'default' as const,
+ },
+ error: {
+ iconColor: 'text-destructive',
+ messageColor: 'text-destructive',
+ icon: ,
+ buttonVariant: 'destructive' as const,
+ },
+ };
+
+ const { icon, iconColor, messageColor, buttonVariant } = variantStyles[variant];
+
return (
= ({
-
+ {icon}
{title}
- {message}
+ {message}
-
+
diff --git a/frontend/src/features/infoDialogSlice.ts b/frontend/src/features/infoDialogSlice.ts
index 26b3df75d..cd828ecce 100644
--- a/frontend/src/features/infoDialogSlice.ts
+++ b/frontend/src/features/infoDialogSlice.ts
@@ -1,15 +1,11 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
+import { InfoDialogProps, InfoDialogVariant } from '@/types/infoDialog';
-interface InfoDialogState {
- isOpen: boolean;
- title: string;
- message: string;
-}
-
-const initialState: InfoDialogState = {
+const initialState: InfoDialogProps = {
isOpen: false,
title: '',
message: '',
+ variant: 'info',
};
const infoDialogSlice = createSlice({
@@ -18,16 +14,22 @@ const infoDialogSlice = createSlice({
reducers: {
showInfoDialog(
state,
- action: PayloadAction<{ title: string; message: string }>,
+ action: PayloadAction<{
+ title: string;
+ message: string;
+ variant?: InfoDialogVariant;
+ }>,
) {
state.isOpen = true;
state.title = action.payload.title;
state.message = action.payload.message;
+ state.variant = action.payload.variant || 'info';
},
hideInfoDialog(state) {
state.isOpen = false;
state.title = '';
state.message = '';
+ state.variant = 'info';
},
},
});
diff --git a/frontend/src/pages/SettingsPage/Settings.tsx b/frontend/src/pages/SettingsPage/Settings.tsx
index d1410de3b..162125b09 100644
--- a/frontend/src/pages/SettingsPage/Settings.tsx
+++ b/frontend/src/pages/SettingsPage/Settings.tsx
@@ -92,6 +92,7 @@ const Settings: React.FC = () => {
title: 'No Updates Available',
message:
'Your application is already up to date with the latest version.',
+ variant: 'info',
}),
);
}
@@ -117,15 +118,38 @@ const Settings: React.FC = () => {
setCurrentPaths([...currentPaths, ...newPaths]);
await deleteCache();
};
+ const testErrorDialog = () => {
+ dispatch(
+ showInfoDialog({
+ title: 'Error Test',
+ message: 'This is a test error message to verify the error styling.',
+ variant: 'error',
+ })
+ );
+};
const handleDeleteCache = async () => {
try {
const result = await deleteCache();
if (result) {
console.log('Cache deleted');
+ dispatch(
+ showInfoDialog({
+ title: 'Cache Refreshed',
+ message: 'The application cache has been successfully refreshed.',
+ variant: 'info',
+ }),
+ );
}
} catch (error) {
console.error('Error deleting cache:', error);
+ dispatch(
+ showInfoDialog({
+ title: 'Cache Refresh Error',
+ message: 'Failed to refresh the application cache. Please try again.',
+ variant: 'error',
+ }),
+ );
}
};
@@ -144,10 +168,21 @@ const Settings: React.FC = () => {
};
const showErrorDialog = (title: string, err: unknown) => {
+ const errorMessage = err instanceof Error ? err.message : 'An unknown error occurred';
+
+ // Use the InfoDialog with error variant for consistent UI
+ dispatch(
+ showInfoDialog({
+ title,
+ message: errorMessage,
+ variant: 'error',
+ }),
+ );
+
+ // Also set the legacy error dialog content for backward compatibility
setErrorDialogContent({
title,
- description:
- err instanceof Error ? err.message : 'An unknown error occurred',
+ description: errorMessage,
});
};
@@ -245,7 +280,7 @@ const Settings: React.FC = () => {
-
+
setErrorDialogContent(null)}
diff --git a/frontend/src/types/infoDialog.ts b/frontend/src/types/infoDialog.ts
index de86c12c4..342654375 100644
--- a/frontend/src/types/infoDialog.ts
+++ b/frontend/src/types/infoDialog.ts
@@ -1,5 +1,8 @@
+export type InfoDialogVariant = 'info' | 'error';
+
export interface InfoDialogProps {
isOpen: boolean;
title: string;
message: string;
+ variant?: InfoDialogVariant;
}
From 6ece99bb9fc2d6c221808615a2ff3f7448249ada Mon Sep 17 00:00:00 2001
From: Hemil
Date: Thu, 28 Aug 2025 18:32:18 +0530
Subject: [PATCH 4/4] Remove test error dialog function and associated button
from Settings component
---
frontend/src/pages/SettingsPage/Settings.tsx | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/frontend/src/pages/SettingsPage/Settings.tsx b/frontend/src/pages/SettingsPage/Settings.tsx
index 162125b09..7635c8745 100644
--- a/frontend/src/pages/SettingsPage/Settings.tsx
+++ b/frontend/src/pages/SettingsPage/Settings.tsx
@@ -118,15 +118,6 @@ const Settings: React.FC = () => {
setCurrentPaths([...currentPaths, ...newPaths]);
await deleteCache();
};
- const testErrorDialog = () => {
- dispatch(
- showInfoDialog({
- title: 'Error Test',
- message: 'This is a test error message to verify the error styling.',
- variant: 'error',
- })
- );
-};
const handleDeleteCache = async () => {
try {
@@ -280,7 +271,6 @@ const Settings: React.FC = () => {
-
setErrorDialogContent(null)}