From 6a13605d0c6eb613c8c987c9c67ac8988dcbb1c7 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 17:10:33 +0530 Subject: [PATCH 01/37] feat: change dark mode default bg --- src/context/theme-provider.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/context/theme-provider.tsx b/src/context/theme-provider.tsx index 75dd4b8b5..93d984a35 100644 --- a/src/context/theme-provider.tsx +++ b/src/context/theme-provider.tsx @@ -93,8 +93,8 @@ const darkTheme = createTheme({ contrastText: '#ffffff', }, background: { - default: '#121212', - paper: '#1e1e1e', + default: '#000000ff', + paper: '#080808ff', }, text: { primary: '#ffffff', From 8c5b2856aa785b2e8fbcad428a86f7338ad2f692 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 17:13:08 +0530 Subject: [PATCH 02/37] feat: change dark mode bg colors --- src/context/theme-provider.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/context/theme-provider.tsx b/src/context/theme-provider.tsx index 93d984a35..748d36d1a 100644 --- a/src/context/theme-provider.tsx +++ b/src/context/theme-provider.tsx @@ -202,21 +202,21 @@ const darkTheme = createTheme({ MuiPaper: { styleOverrides: { root: { - backgroundColor: '#1e1e1e', + backgroundColor: '#080808ff', }, }, }, MuiAppBar: { styleOverrides: { root: { - backgroundColor: '#121212', + backgroundColor: '#080808ff', }, }, }, MuiDrawer: { styleOverrides: { paper: { - backgroundColor: '#121212', + backgroundColor: '#080808ff', }, }, }, From 46c217446acecd93ebd0cd04e3daf301049343e9 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 17:14:02 +0530 Subject: [PATCH 03/37] feat: sync dark mode bg navbar --- src/components/dashboard/NavBar.tsx | 2 +- src/components/robot/RobotDuplicate.tsx | 172 ------- src/components/robot/RobotEdit.tsx | 586 ---------------------- src/components/robot/RobotSettings.tsx | 173 ------- src/components/robot/ScheduleSettings.tsx | 314 ------------ 5 files changed, 1 insertion(+), 1246 deletions(-) delete mode 100644 src/components/robot/RobotDuplicate.tsx delete mode 100644 src/components/robot/RobotEdit.tsx delete mode 100644 src/components/robot/RobotSettings.tsx delete mode 100644 src/components/robot/ScheduleSettings.tsx diff --git a/src/components/dashboard/NavBar.tsx b/src/components/dashboard/NavBar.tsx index 24e11d09f..7526de70c 100644 --- a/src/components/dashboard/NavBar.tsx +++ b/src/components/dashboard/NavBar.tsx @@ -601,7 +601,7 @@ export const NavBar: React.FC = ({ const NavBarWrapper = styled.div<{ mode: 'light' | 'dark' }>` grid-area: navbar; - background-color: ${({ mode }) => (mode === 'dark' ? '#1e2124' : '#ffffff')}; + background-color: ${({ mode }) => (mode === 'dark' ? '#080808ff' : '#ffffff')}; padding: 5px; display: flex; justify-content: space-between; diff --git a/src/components/robot/RobotDuplicate.tsx b/src/components/robot/RobotDuplicate.tsx deleted file mode 100644 index bee1ef5bc..000000000 --- a/src/components/robot/RobotDuplicate.tsx +++ /dev/null @@ -1,172 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import { GenericModal } from "../ui/GenericModal"; -import { TextField, Typography, Box, Button } from "@mui/material"; -import { modalStyle } from "../recorder/AddWhereCondModal"; -import { useGlobalInfoStore } from '../../context/globalInfo'; -import { duplicateRecording, getStoredRecording } from '../../api/storage'; -import { WhereWhatPair } from 'maxun-core'; -import { useTranslation } from 'react-i18next'; - -interface RobotMeta { - name: string; - id: string; - createdAt: string; - pairs: number; - updatedAt: string; - params: any[]; -} - -interface RobotWorkflow { - workflow: WhereWhatPair[]; -} - -interface ScheduleConfig { - runEvery: number; - runEveryUnit: 'MINUTES' | 'HOURS' | 'DAYS' | 'WEEKS' | 'MONTHS'; - startFrom: 'SUNDAY' | 'MONDAY' | 'TUESDAY' | 'WEDNESDAY' | 'THURSDAY' | 'FRIDAY' | 'SATURDAY'; - atTimeStart?: string; - atTimeEnd?: string; - timezone: string; - lastRunAt?: Date; - nextRunAt?: Date; - cronExpression?: string; -} - -export interface RobotSettings { - id: string; - userId?: number; - recording_meta: RobotMeta; - recording: RobotWorkflow; - google_sheet_email?: string | null; - google_sheet_name?: string | null; - google_sheet_id?: string | null; - google_access_token?: string | null; - google_refresh_token?: string | null; - schedule?: ScheduleConfig | null; -} - -interface RobotSettingsProps { - isOpen: boolean; - handleStart: (settings: RobotSettings) => void; - handleClose: () => void; - initialSettings?: RobotSettings | null; - -} - -export const RobotDuplicationModal = ({ isOpen, handleStart, handleClose, initialSettings }: RobotSettingsProps) => { - const { t } = useTranslation(); - const [targetUrl, setTargetUrl] = useState(''); - const [robot, setRobot] = useState(null); - const { recordingId, notify, setRerenderRobots } = useGlobalInfoStore(); - - useEffect(() => { - if (isOpen) { - getRobot(); - } - }, [isOpen]); - - useEffect(() => { - if (robot) { - const lastPair = robot?.recording.workflow[robot?.recording.workflow.length - 1]; - const url = lastPair?.what.find(action => action.action === "goto")?.args?.[0]; - setTargetUrl(url); - } - }, [robot]); - - const getRobot = async () => { - if (recordingId) { - const robot = await getStoredRecording(recordingId); - setRobot(robot); - } else { - notify('error', t('robot_duplication.notifications.robot_not_found')); - } - } - - const handleTargetUrlChange = (e: React.ChangeEvent) => { - setTargetUrl(e.target.value); - }; - - const handleSave = async () => { - if (!robot || !targetUrl) { - notify('error', t('robot_duplication.notifications.url_required')); - return; - } - - try { - const success = await duplicateRecording(robot.recording_meta.id, targetUrl); - - if (success) { - setRerenderRobots(true); - - notify('success', t('robot_duplication.notifications.duplicate_success')); - handleStart(robot); - handleClose(); - } else { - notify('error', t('robot_duplication.notifications.duplicate_error')); - } - } catch (error) { - notify('error', t('robot_duplication.notifications.unknown_error')); - console.error('Error updating Target URL:', error); - } - }; - - return ( - - <> - - {t('robot_duplication.title')} - - - { - robot && ( - <> - - {t('robot_duplication.descriptions.purpose')} - -
- producthunt.com/topics/api', - url2: 'producthunt.com/topics/database' - }) - }} /> -
- - {t('robot_duplication.descriptions.warning')} - - - - - - - - ) - } -
- -
- ); -}; diff --git a/src/components/robot/RobotEdit.tsx b/src/components/robot/RobotEdit.tsx deleted file mode 100644 index 3b110ba17..000000000 --- a/src/components/robot/RobotEdit.tsx +++ /dev/null @@ -1,586 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import { useTranslation } from 'react-i18next'; -import { GenericModal } from "../ui/GenericModal"; -import { TextField, Typography, Box, Button, IconButton, InputAdornment } from "@mui/material"; -import { Visibility, VisibilityOff } from '@mui/icons-material'; -import { modalStyle } from "../recorder/AddWhereCondModal"; -import { useGlobalInfoStore } from '../../context/globalInfo'; -import { getStoredRecording, updateRecording } from '../../api/storage'; -import { WhereWhatPair } from 'maxun-core'; - -interface RobotMeta { - name: string; - id: string; - createdAt: string; - pairs: number; - updatedAt: string; - params: any[]; -} - -interface RobotWorkflow { - workflow: WhereWhatPair[]; -} - -interface ScheduleConfig { - runEvery: number; - runEveryUnit: 'MINUTES' | 'HOURS' | 'DAYS' | 'WEEKS' | 'MONTHS'; - startFrom: 'SUNDAY' | 'MONDAY' | 'TUESDAY' | 'WEDNESDAY' | 'THURSDAY' | 'FRIDAY' | 'SATURDAY'; - atTimeStart?: string; - atTimeEnd?: string; - timezone: string; - lastRunAt?: Date; - nextRunAt?: Date; - cronExpression?: string; -} - -export interface RobotSettings { - id: string; - userId?: number; - recording_meta: RobotMeta; - recording: RobotWorkflow; - google_sheet_email?: string | null; - google_sheet_name?: string | null; - google_sheet_id?: string | null; - google_access_token?: string | null; - google_refresh_token?: string | null; - schedule?: ScheduleConfig | null; -} - -interface RobotSettingsProps { - isOpen: boolean; - handleStart: (settings: RobotSettings) => void; - handleClose: () => void; - initialSettings?: RobotSettings | null; -} - -interface CredentialInfo { - value: string; - type: string; -} - -interface Credentials { - [key: string]: CredentialInfo; -} - -interface CredentialVisibility { - [key: string]: boolean; -} - -interface GroupedCredentials { - passwords: string[]; - emails: string[]; - usernames: string[]; - others: string[]; -} - -interface ScrapeListLimit { - pairIndex: number; - actionIndex: number; - argIndex: number; - currentLimit: number; -} - -export const RobotEditModal = ({ isOpen, handleStart, handleClose, initialSettings }: RobotSettingsProps) => { - const { t } = useTranslation(); - const [credentials, setCredentials] = useState({}); - const { recordingId, notify, setRerenderRobots } = useGlobalInfoStore(); - const [robot, setRobot] = useState(null); - const [credentialGroups, setCredentialGroups] = useState({ - passwords: [], - emails: [], - usernames: [], - others: [] - }); - const [showPasswords, setShowPasswords] = useState({}); - const [scrapeListLimits, setScrapeListLimits] = useState([]); - - const isEmailPattern = (value: string): boolean => { - return value.includes('@'); - }; - - const isUsernameSelector = (selector: string): boolean => { - return selector.toLowerCase().includes('username') || - selector.toLowerCase().includes('user') || - selector.toLowerCase().includes('email'); - }; - - const determineCredentialType = (selector: string, info: CredentialInfo): 'password' | 'email' | 'username' | 'other' => { - if (info.type === 'password' || selector.toLowerCase().includes('password')) { - return 'password'; - } - if (isEmailPattern(info.value) || selector.toLowerCase().includes('email')) { - return 'email'; - } - if (isUsernameSelector(selector)) { - return 'username'; - } - return 'other'; - }; - - useEffect(() => { - if (isOpen) { - getRobot(); - } - }, [isOpen]); - - useEffect(() => { - if (robot?.recording?.workflow) { - const extractedCredentials = extractInitialCredentials(robot.recording.workflow); - setCredentials(extractedCredentials); - setCredentialGroups(groupCredentialsByType(extractedCredentials)); - - findScrapeListLimits(robot.recording.workflow); - } - }, [robot]); - - const findScrapeListLimits = (workflow: WhereWhatPair[]) => { - const limits: ScrapeListLimit[] = []; - - workflow.forEach((pair, pairIndex) => { - if (!pair.what) return; - - pair.what.forEach((action, actionIndex) => { - if (action.action === 'scrapeList' && action.args && action.args.length > 0) { - // Check if first argument has a limit property - const arg = action.args[0]; - if (arg && typeof arg === 'object' && 'limit' in arg) { - limits.push({ - pairIndex, - actionIndex, - argIndex: 0, - currentLimit: arg.limit - }); - } - } - }); - }); - - setScrapeListLimits(limits); - }; - - function extractInitialCredentials(workflow: any[]): Credentials { - const credentials: Credentials = {}; - - const isPrintableCharacter = (char: string): boolean => { - return char.length === 1 && !!char.match(/^[\x20-\x7E]$/); - }; - - workflow.forEach(step => { - if (!step.what) return; - - let currentSelector = ''; - let currentValue = ''; - let currentType = ''; - let i = 0; - - while (i < step.what.length) { - const action = step.what[i]; - - if (!action.action || !action.args?.[0]) { - i++; - continue; - } - - const selector = action.args[0]; - - // Handle full word type actions first - if (action.action === 'type' && - action.args?.length >= 2 && - typeof action.args[1] === 'string' && - action.args[1].length > 1) { - - if (!credentials[selector]) { - credentials[selector] = { - value: action.args[1], - type: action.args[2] || 'text' - }; - } - i++; - continue; - } - - // Handle character-by-character sequences (both type and press) - if ((action.action === 'type' || action.action === 'press') && - action.args?.length >= 2 && - typeof action.args[1] === 'string') { - - if (selector !== currentSelector) { - if (currentSelector && currentValue) { - credentials[currentSelector] = { - value: currentValue, - type: currentType || 'text' - }; - } - currentSelector = selector; - currentValue = credentials[selector]?.value || ''; - currentType = action.args[2] || credentials[selector]?.type || 'text'; - } - - const character = action.args[1]; - - if (isPrintableCharacter(character)) { - currentValue += character; - } else if (character === 'Backspace') { - currentValue = currentValue.slice(0, -1); - } - - if (!currentType && action.args[2]?.toLowerCase() === 'password') { - currentType = 'password'; - } - - let j = i + 1; - while (j < step.what.length) { - const nextAction = step.what[j]; - if (!nextAction.action || !nextAction.args?.[0] || - nextAction.args[0] !== selector || - (nextAction.action !== 'type' && nextAction.action !== 'press')) { - break; - } - if (nextAction.args[1] === 'Backspace') { - currentValue = currentValue.slice(0, -1); - } else if (isPrintableCharacter(nextAction.args[1])) { - currentValue += nextAction.args[1]; - } - j++; - } - - credentials[currentSelector] = { - value: currentValue, - type: currentType - }; - - i = j; - } else { - i++; - } - } - - if (currentSelector && currentValue) { - credentials[currentSelector] = { - value: currentValue, - type: currentType || 'text' - }; - } - }); - - return credentials; - } - - const groupCredentialsByType = (credentials: Credentials): GroupedCredentials => { - return Object.entries(credentials).reduce((acc: GroupedCredentials, [selector, info]) => { - const credentialType = determineCredentialType(selector, info); - - switch (credentialType) { - case 'password': - acc.passwords.push(selector); - break; - case 'email': - acc.emails.push(selector); - break; - case 'username': - acc.usernames.push(selector); - break; - default: - acc.others.push(selector); - } - - return acc; - }, { passwords: [], emails: [], usernames: [], others: [] }); - }; - - const getRobot = async () => { - if (recordingId) { - const robot = await getStoredRecording(recordingId); - setRobot(robot); - } else { - notify('error', t('robot_edit.notifications.update_failed')); - } - }; - - const handleClickShowPassword = (selector: string) => { - setShowPasswords(prev => ({ - ...prev, - [selector]: !prev[selector] - })); - }; - - const handleRobotNameChange = (newName: string) => { - setRobot((prev) => - prev ? { ...prev, recording_meta: { ...prev.recording_meta, name: newName } } : prev - ); - }; - - const handleCredentialChange = (selector: string, value: string) => { - setCredentials(prev => ({ - ...prev, - [selector]: { - ...prev[selector], - value - } - })); - }; - - const handleLimitChange = (pairIndex: number, actionIndex: number, argIndex: number, newLimit: number) => { - setRobot((prev) => { - if (!prev) return prev; - - const updatedWorkflow = [...prev.recording.workflow]; - if ( - updatedWorkflow.length > pairIndex && - updatedWorkflow[pairIndex]?.what && - updatedWorkflow[pairIndex].what.length > actionIndex && - updatedWorkflow[pairIndex].what[actionIndex].args && - updatedWorkflow[pairIndex].what[actionIndex].args.length > argIndex - ) { - updatedWorkflow[pairIndex].what[actionIndex].args[argIndex].limit = newLimit; - - setScrapeListLimits(prev => { - return prev.map(item => { - if (item.pairIndex === pairIndex && - item.actionIndex === actionIndex && - item.argIndex === argIndex) { - return { ...item, currentLimit: newLimit }; - } - return item; - }); - }); - } - - return { ...prev, recording: { ...prev.recording, workflow: updatedWorkflow } }; - }); - }; - - const handleTargetUrlChange = (newUrl: string) => { - setRobot((prev) => { - if (!prev) return prev; - - const updatedWorkflow = [...prev.recording.workflow]; - const lastPairIndex = updatedWorkflow.length - 1; - - if (lastPairIndex >= 0) { - const gotoAction = updatedWorkflow[lastPairIndex]?.what?.find(action => action.action === "goto"); - if (gotoAction && gotoAction.args && gotoAction.args.length > 0) { - gotoAction.args[0] = newUrl; - } - } - - return { ...prev, recording: { ...prev.recording, workflow: updatedWorkflow } }; - }); - }; - - const renderAllCredentialFields = () => { - return ( - <> - {renderCredentialFields( - credentialGroups.usernames, - t('Username'), - 'text' - )} - - {renderCredentialFields( - credentialGroups.emails, - t('Email'), - 'text' - )} - - {renderCredentialFields( - credentialGroups.passwords, - t('Password'), - 'password' - )} - - {renderCredentialFields( - credentialGroups.others, - t('Other'), - 'text' - )} - - ); - }; - - const renderCredentialFields = (selectors: string[], headerText: string, defaultType: 'text' | 'password' = 'text') => { - if (selectors.length === 0) return null; - - return ( - <> - {selectors.map((selector, index) => { - const isVisible = showPasswords[selector]; - - return ( - handleCredentialChange(selector, e.target.value)} - style={{ marginBottom: '20px' }} - InputProps={{ - endAdornment: ( - - handleClickShowPassword(selector)} - edge="end" - disabled={!credentials[selector]?.value} - > - {isVisible ? : } - - - ), - }} - /> - ); - })} - - ); - }; - - const renderScrapeListLimitFields = () => { - if (scrapeListLimits.length === 0) return null; - - return ( - <> - - {t('List Limits')} - - - {scrapeListLimits.map((limitInfo, index) => ( - { - const value = parseInt(e.target.value, 10); - if (value >= 1) { - handleLimitChange( - limitInfo.pairIndex, - limitInfo.actionIndex, - limitInfo.argIndex, - value - ); - } - }} - inputProps={{ min: 1 }} - style={{ marginBottom: '20px' }} - /> - ))} - - ); - }; - - const handleSave = async () => { - if (!robot) return; - - try { - const credentialsForPayload = Object.entries(credentials).reduce((acc, [selector, info]) => { - const enforceType = info.type === 'password' ? 'password' : 'text'; - - acc[selector] = { - value: info.value, - type: enforceType - }; - return acc; - }, {} as Record); - - const lastPair = robot.recording.workflow[robot.recording.workflow.length - 1]; - const targetUrl = lastPair?.what.find(action => action.action === "goto")?.args?.[0]; - - const payload = { - name: robot.recording_meta.name, - limits: scrapeListLimits.map(limit => ({ - pairIndex: limit.pairIndex, - actionIndex: limit.actionIndex, - argIndex: limit.argIndex, - limit: limit.currentLimit - })), - credentials: credentialsForPayload, - targetUrl: targetUrl, - }; - - const success = await updateRecording(robot.recording_meta.id, payload); - - if (success) { - setRerenderRobots(true); - - notify('success', t('robot_edit.notifications.update_success')); - handleStart(robot); - handleClose(); - } else { - notify('error', t('robot_edit.notifications.update_failed')); - } - } catch (error) { - notify('error', t('robot_edit.notifications.update_error')); - console.error('Error updating robot:', error); - } - }; - - const lastPair = robot?.recording.workflow[robot?.recording.workflow.length - 1]; - const targetUrl = lastPair?.what.find(action => action.action === "goto")?.args?.[0]; - - return ( - - <> - - {t('robot_edit.title')} - - - {robot && ( - <> - handleRobotNameChange(e.target.value)} - style={{ marginBottom: '20px' }} - /> - - handleTargetUrlChange(e.target.value)} - style={{ marginBottom: '20px' }} - /> - - {renderScrapeListLimitFields()} - - {(Object.keys(credentials).length > 0) && ( - <> - - {t('Input Texts')} - - {renderAllCredentialFields()} - - )} - - - - - - - )} - - - - ); -}; \ No newline at end of file diff --git a/src/components/robot/RobotSettings.tsx b/src/components/robot/RobotSettings.tsx deleted file mode 100644 index c91b4f110..000000000 --- a/src/components/robot/RobotSettings.tsx +++ /dev/null @@ -1,173 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import { useTranslation } from 'react-i18next'; -import { GenericModal } from "../ui/GenericModal"; -import { TextField, Typography, Box } from "@mui/material"; -import { useGlobalInfoStore } from '../../context/globalInfo'; -import { getStoredRecording } from '../../api/storage'; -import { WhereWhatPair } from 'maxun-core'; -import { getUserById } from "../../api/auth"; - -interface RobotMeta { - name: string; - id: string; - createdAt: string; - pairs: number; - updatedAt: string; - params: any[]; -} - -interface RobotWorkflow { - workflow: WhereWhatPair[]; -} - -interface ScheduleConfig { - runEvery: number; - runEveryUnit: 'MINUTES' | 'HOURS' | 'DAYS' | 'WEEKS' | 'MONTHS'; - startFrom: 'SUNDAY' | 'MONDAY' | 'TUESDAY' | 'WEDNESDAY' | 'THURSDAY' | 'FRIDAY' | 'SATURDAY'; - atTimeStart?: string; - atTimeEnd?: string; - timezone: string; - lastRunAt?: Date; - nextRunAt?: Date; - cronExpression?: string; -} - -export interface RobotSettings { - id: string; - userId?: number; - recording_meta: RobotMeta; - recording: RobotWorkflow; - google_sheet_email?: string | null; - google_sheet_name?: string | null; - google_sheet_id?: string | null; - google_access_token?: string | null; - google_refresh_token?: string | null; - schedule?: ScheduleConfig | null; -} - -interface RobotSettingsProps { - isOpen: boolean; - handleStart: (settings: RobotSettings) => void; - handleClose: () => void; - initialSettings?: RobotSettings | null; -} - -export const RobotSettingsModal = ({ isOpen, handleStart, handleClose, initialSettings }: RobotSettingsProps) => { - const { t } = useTranslation(); - const [userEmail, setUserEmail] = useState(null); - const [robot, setRobot] = useState(null); - const { recordingId, notify } = useGlobalInfoStore(); - - useEffect(() => { - if (isOpen) { - getRobot(); - } - }, [isOpen]); - - const getRobot = async () => { - if (recordingId) { - const robot = await getStoredRecording(recordingId); - setRobot(robot); - } else { - notify('error', t('robot_settings.errors.robot_not_found')); - } - } - - const lastPair = robot?.recording.workflow[robot?.recording.workflow.length - 1]; - - // Find the `goto` action in `what` and retrieve its arguments - const targetUrl = lastPair?.what.find(action => action.action === "goto")?.args?.[0]; - - useEffect(() => { - const fetchUserEmail = async () => { - if (robot && robot.userId) { - const userData = await getUserById(robot.userId.toString()); - if (userData && userData.user) { - setUserEmail(userData.user.email); - } - } - }; - fetchUserEmail(); - }, [robot?.userId]); - - return ( - - <> - - {t('robot_settings.title')} - - - { - robot && ( - <> - - - {robot.recording.workflow?.[0]?.what?.[0]?.args?.[0]?.limit !== undefined && ( - - )} - - - - ) - } - - - - ); -}; - -export const modalStyle = { -top: "50%", -left: "50%", -transform: "translate(-50%, -50%)", -width: "30%", -backgroundColor: "background.paper", -p: 4, -height: "fit-content", -display: "block", -padding: "20px", -}; diff --git a/src/components/robot/ScheduleSettings.tsx b/src/components/robot/ScheduleSettings.tsx deleted file mode 100644 index 7a28d2dce..000000000 --- a/src/components/robot/ScheduleSettings.tsx +++ /dev/null @@ -1,314 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import { useTranslation } from 'react-i18next'; -import { GenericModal } from "../ui/GenericModal"; -import { MenuItem, TextField, Typography, Box } from "@mui/material"; -import { Dropdown } from "../ui/DropdownMui"; -import Button from "@mui/material/Button"; -import { validMomentTimezones } from '../../constants/const'; -import { useGlobalInfoStore } from '../../context/globalInfo'; -import { getSchedule, deleteSchedule } from '../../api/storage'; - -interface ScheduleSettingsProps { - isOpen: boolean; - handleStart: (settings: ScheduleSettings) => Promise; - handleClose: () => void; - initialSettings?: ScheduleSettings | null; -} - -export interface ScheduleSettings { - runEvery: number; - runEveryUnit: string; - startFrom: string; - dayOfMonth?: string; - atTimeStart?: string; - atTimeEnd?: string; - timezone: string; -} - -export const ScheduleSettingsModal = ({ isOpen, handleStart, handleClose, initialSettings }: ScheduleSettingsProps) => { - const { t } = useTranslation(); - const [schedule, setSchedule] = useState(null); - const [settings, setSettings] = useState({ - runEvery: 1, - runEveryUnit: 'HOURS', - startFrom: 'MONDAY', - dayOfMonth: '1', - atTimeStart: '00:00', - atTimeEnd: '01:00', - timezone: 'UTC' - }); - - useEffect(() => { - if (initialSettings) { - setSettings(initialSettings); - } - }, [initialSettings]); - - const handleChange = (field: keyof ScheduleSettings, value: string | number | boolean) => { - setSettings(prev => ({ ...prev, [field]: value })); - }; - - const textStyle = { - width: '150px', - height: '52px', - marginRight: '10px', - }; - - const dropDownStyle = { - marginTop: '2px', - width: '150px', - height: '59px', - marginRight: '10px', - }; - - const units = [ - 'MINUTES', - 'HOURS', - 'DAYS', - 'WEEKS', - 'MONTHS' - ]; - - const days = [ - 'MONDAY', - 'TUESDAY', - 'WEDNESDAY', - 'THURSDAY', - 'FRIDAY', - 'SATURDAY', - 'SUNDAY' - ]; - - const { recordingId, notify } = useGlobalInfoStore(); - - const deleteRobotSchedule = () => { - if (recordingId) { - deleteSchedule(recordingId); - setSchedule(null); - notify('success', t('Schedule deleted successfully')); - } else { - console.error('No recording id provided'); - } - - setSettings({ - runEvery: 1, - runEveryUnit: 'HOURS', - startFrom: 'MONDAY', - dayOfMonth: '', - atTimeStart: '00:00', - atTimeEnd: '01:00', - timezone: 'UTC' - }); - }; - - const getRobotSchedule = async () => { - if (recordingId) { - const scheduleData = await getSchedule(recordingId); - setSchedule(scheduleData); - } else { - console.error('No recording id provided'); - } - } - - useEffect(() => { - if (isOpen) { - const fetchSchedule = async () => { - await getRobotSchedule(); - }; - fetchSchedule(); - } - }, [isOpen]); - - const getDayOrdinal = (day: string | undefined) => { - if (!day) return ''; - const lastDigit = day.slice(-1); - const lastTwoDigits = day.slice(-2); - - // Special cases for 11, 12, 13 - if (['11', '12', '13'].includes(lastTwoDigits)) { - return t('schedule_settings.labels.on_day.th'); - } - - // Other cases - switch (lastDigit) { - case '1': return t('schedule_settings.labels.on_day.st'); - case '2': return t('schedule_settings.labels.on_day.nd'); - case '3': return t('schedule_settings.labels.on_day.rd'); - default: return t('schedule_settings.labels.on_day.th'); - } - }; - - return ( - - *': { marginBottom: '20px' }, - }}> - {t('schedule_settings.title')} - <> - {schedule !== null ? ( - <> - {t('schedule_settings.run_every')}: {schedule.runEvery} {schedule.runEveryUnit.toLowerCase()} - {['MONTHS', 'WEEKS'].includes(settings.runEveryUnit) ? t('schedule_settings.start_from') : t('schedule_settings.start_from')}: {schedule.startFrom.charAt(0).toUpperCase() + schedule.startFrom.slice(1).toLowerCase()} - {schedule.runEveryUnit === 'MONTHS' && ( - {t('schedule_settings.on_day')}: {schedule.dayOfMonth}{getDayOrdinal(schedule.dayOfMonth)} of the month - )} - {t('schedule_settings.at_around')}: {schedule.atTimeStart}, {schedule.timezone} {t('schedule_settings.timezone')} - - - - - ) : ( - <> - - {t('schedule_settings.labels.run_once_every')} - handleChange('runEvery', parseInt(e.target.value))} - sx={textStyle} - inputProps={{ min: 1 }} - /> - handleChange('runEveryUnit', e.target.value)} - sx={dropDownStyle} - > - {units.map((unit) => ( - {unit.charAt(0).toUpperCase() + unit.slice(1).toLowerCase()} - ))} - - - - - - {['MONTHS', 'WEEKS'].includes(settings.runEveryUnit) ? t('schedule_settings.labels.start_from_label') : t('schedule_settings.labels.start_from_label')} - - handleChange('startFrom', e.target.value)} - sx={dropDownStyle} - > - {days.map((day) => ( - - {day.charAt(0).toUpperCase() + day.slice(1).toLowerCase()} - - ))} - - - - {settings.runEveryUnit === 'MONTHS' && ( - - {t('schedule_settings.labels.on_day_of_month')} - handleChange('dayOfMonth', e.target.value)} - sx={textStyle} - inputProps={{ min: 1, max: 31 }} - /> - - )} - - {['MINUTES', 'HOURS'].includes(settings.runEveryUnit) ? ( - - - {t('schedule_settings.labels.in_between')} - handleChange('atTimeStart', e.target.value)} - sx={textStyle} - /> - handleChange('atTimeEnd', e.target.value)} - sx={textStyle} - /> - - - ) : ( - - {t('schedule_settings.at_around')} - handleChange('atTimeStart', e.target.value)} - sx={textStyle} - /> - - )} - - - {t('schedule_settings.timezone')} - handleChange('timezone', e.target.value)} - sx={dropDownStyle} - > - {validMomentTimezones.map((tz) => ( - {tz.charAt(0).toUpperCase() + tz.slice(1).toLowerCase()} - ))} - - - - - - - - )} - - - - ); -}; - -const modalStyle = { - top: '50%', - left: '50%', - transform: 'translate(-50%, -50%)', - width: '40%', - backgroundColor: 'background.paper', - p: 4, - height: 'fit-content', - display: 'block', - padding: '20px', -}; \ No newline at end of file From 4b28db25d14325ae00dde83a965e3541f3070be9 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 17:15:53 +0530 Subject: [PATCH 04/37] fix: match border bottom --- src/components/dashboard/NavBar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/dashboard/NavBar.tsx b/src/components/dashboard/NavBar.tsx index 7526de70c..7073b071f 100644 --- a/src/components/dashboard/NavBar.tsx +++ b/src/components/dashboard/NavBar.tsx @@ -605,7 +605,7 @@ const NavBarWrapper = styled.div<{ mode: 'light' | 'dark' }>` padding: 5px; display: flex; justify-content: space-between; - border-bottom: 1px solid ${({ mode }) => (mode === 'dark' ? '#333' : '#e0e0e0')}; + border-bottom: 1px solid ${({ mode }) => (mode === 'dark' ? '#080808ff' : '#e0e0e0')}; `; const ProjectName = styled.b<{ mode: 'light' | 'dark' }>` From c955ae339a0faacbe7c14ad8cc9c869625c52b14 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 17:16:41 +0530 Subject: [PATCH 05/37] feat: sync dark mode divider bg --- src/context/theme-provider.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/context/theme-provider.tsx b/src/context/theme-provider.tsx index 748d36d1a..26e772988 100644 --- a/src/context/theme-provider.tsx +++ b/src/context/theme-provider.tsx @@ -230,7 +230,7 @@ const darkTheme = createTheme({ MuiDivider: { styleOverrides: { root: { - borderColor: 'rgba(255, 255, 255, 0.12)', + borderColor: '#080808ff', }, }, }, From 87ddfbd56df781728b25203a710e8487f518af5c Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 17:17:13 +0530 Subject: [PATCH 06/37] feat: sync dark mode table cell border bottom --- src/context/theme-provider.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/context/theme-provider.tsx b/src/context/theme-provider.tsx index 26e772988..4d9f8bb6c 100644 --- a/src/context/theme-provider.tsx +++ b/src/context/theme-provider.tsx @@ -223,7 +223,7 @@ const darkTheme = createTheme({ MuiTableCell: { styleOverrides: { root: { - borderBottom: '1px solid rgba(255, 255, 255, 0.12)', + borderBottom: '1px solid #080808ff', }, }, }, From d5668e5da73de024dedfeb0621e36e0069732cb6 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 17:18:16 +0530 Subject: [PATCH 07/37] feat: inherit bg btn dark mode --- src/context/theme-provider.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/context/theme-provider.tsx b/src/context/theme-provider.tsx index 4d9f8bb6c..21b795041 100644 --- a/src/context/theme-provider.tsx +++ b/src/context/theme-provider.tsx @@ -112,7 +112,7 @@ const darkTheme = createTheme({ color: '#ffffff', "&:hover": { borderColor: '#ffffff', - backgroundColor: 'rgba(255, 255, 255, 0.08)', + backgroundColor: 'inherit', }, }, }, From 44d713fd5d6ed3cced4f22946f783291f04e480d Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 17:18:48 +0530 Subject: [PATCH 08/37] feat: change dark theme border color paper --- src/context/theme-provider.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/context/theme-provider.tsx b/src/context/theme-provider.tsx index 21b795041..ccc4fda1c 100644 --- a/src/context/theme-provider.tsx +++ b/src/context/theme-provider.tsx @@ -203,6 +203,7 @@ const darkTheme = createTheme({ styleOverrides: { root: { backgroundColor: '#080808ff', + border: '1px solid #121111ff', }, }, }, From f0d808c29b02d36a807ba0a0ac5676c74afb2921 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 17:25:48 +0530 Subject: [PATCH 09/37] fix: match border bottom clr --- src/components/dashboard/NavBar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/dashboard/NavBar.tsx b/src/components/dashboard/NavBar.tsx index 7073b071f..5910e9b53 100644 --- a/src/components/dashboard/NavBar.tsx +++ b/src/components/dashboard/NavBar.tsx @@ -605,7 +605,7 @@ const NavBarWrapper = styled.div<{ mode: 'light' | 'dark' }>` padding: 5px; display: flex; justify-content: space-between; - border-bottom: 1px solid ${({ mode }) => (mode === 'dark' ? '#080808ff' : '#e0e0e0')}; + border-bottom: 1px solid ${({ mode }) => (mode === 'dark' ? '#121111ff' : '#e0e0e0')}; `; const ProjectName = styled.b<{ mode: 'light' | 'dark' }>` From 341602a91570f1e9e99e4501a6cccfbe9503cdad Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 17:26:52 +0530 Subject: [PATCH 10/37] feat: inherit bg --- src/pages/Login.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Login.tsx b/src/pages/Login.tsx index 2d34bd810..da036a17a 100644 --- a/src/pages/Login.tsx +++ b/src/pages/Login.tsx @@ -80,7 +80,7 @@ const Login = () => { maxHeight: "100vh", mt: 6, padding: 4, - backgroundColor: darkMode ? "#121212" : "#ffffff", + backgroundColor: "inherit", }} > Date: Mon, 13 Oct 2025 17:27:41 +0530 Subject: [PATCH 11/37] feat: -rm mt --- src/pages/Register.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/Register.tsx b/src/pages/Register.tsx index bc4faf27d..ca0493918 100644 --- a/src/pages/Register.tsx +++ b/src/pages/Register.tsx @@ -71,7 +71,6 @@ const Register = () => { justifyContent: "center", alignItems: "center", maxHeight: "100vh", - mt: 6, padding: 4, backgroundColor: darkMode ? "#121212" : "#ffffff", }} From f0542a4a7640ba459c3ba2b43a652d9480ffbf83 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 17:28:32 +0530 Subject: [PATCH 12/37] feat: change card color --- src/pages/Register.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Register.tsx b/src/pages/Register.tsx index ca0493918..e4b78e646 100644 --- a/src/pages/Register.tsx +++ b/src/pages/Register.tsx @@ -80,7 +80,7 @@ const Register = () => { onSubmit={submitForm} sx={{ textAlign: "center", - backgroundColor: darkMode ? "#1e1e1e" : "#ffffff", + backgroundColor: darkMode ? "#121111ff" : "#ffffff", color: darkMode ? "#ffffff" : "#333333", padding: 6, borderRadius: 5, From ba8a5a12294cb340f694c9e83a54d0e0d9772f82 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 17:28:49 +0530 Subject: [PATCH 13/37] feat: inherit bg --- src/pages/Register.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Register.tsx b/src/pages/Register.tsx index e4b78e646..850559e99 100644 --- a/src/pages/Register.tsx +++ b/src/pages/Register.tsx @@ -72,7 +72,7 @@ const Register = () => { alignItems: "center", maxHeight: "100vh", padding: 4, - backgroundColor: darkMode ? "#121212" : "#ffffff", + backgroundColor: "inherit", }} > Date: Mon, 13 Oct 2025 17:29:21 +0530 Subject: [PATCH 14/37] feat: inherit bg --- src/pages/Login.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Login.tsx b/src/pages/Login.tsx index da036a17a..ed84c211a 100644 --- a/src/pages/Login.tsx +++ b/src/pages/Login.tsx @@ -88,7 +88,7 @@ const Login = () => { onSubmit={submitForm} sx={{ textAlign: "center", - backgroundColor: darkMode ? "#1e1e1e" : "#ffffff", + backgroundColor: darkMode ? "#121111ff" : "#ffffff", color: darkMode ? "#ffffff" : "#333333", padding: 6, borderRadius: 5, From 552dc4b4169379c52efcb20fa8723bbc7bac654d Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 17:33:29 +0530 Subject: [PATCH 15/37] feat: larger logo --- src/pages/Register.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pages/Register.tsx b/src/pages/Register.tsx index 850559e99..41ac133e3 100644 --- a/src/pages/Register.tsx +++ b/src/pages/Register.tsx @@ -71,6 +71,7 @@ const Register = () => { justifyContent: "center", alignItems: "center", maxHeight: "100vh", + mt: 6, padding: 4, backgroundColor: "inherit", }} @@ -96,8 +97,8 @@ const Register = () => { logo Date: Mon, 13 Oct 2025 17:33:45 +0530 Subject: [PATCH 16/37] feat: larger logo --- src/pages/Login.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/Login.tsx b/src/pages/Login.tsx index ed84c211a..dd0d0b03c 100644 --- a/src/pages/Login.tsx +++ b/src/pages/Login.tsx @@ -100,7 +100,8 @@ const Login = () => { width: "100%", }} > - logo + logo {t('login.title')} From 180e5718e9dd5af1a858f0cf16cb3f2fb01c72ae Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 17:41:12 +0530 Subject: [PATCH 17/37] feat: change background of recorder in dm --- src/pages/RecordingPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/RecordingPage.tsx b/src/pages/RecordingPage.tsx index 7dbed8b2c..6e3624713 100644 --- a/src/pages/RecordingPage.tsx +++ b/src/pages/RecordingPage.tsx @@ -61,7 +61,7 @@ export const RecordingPage = ({ recordingName }: RecordingPageProps) => { useEffect(() => { if (darkMode) { - document.body.style.background = 'rgba(18,18,18,1)'; + document.body.style.background = '#080808ff'; } else { document.body.style.background = 'radial-gradient(circle, rgba(255, 255, 255, 1) 0%, rgba(232, 191, 222, 1) 100%, rgba(255, 255, 255, 1) 100%)'; From db6e7d62cf23773d1ba499e8ded01e6f886fa770 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 17:46:18 +0530 Subject: [PATCH 18/37] feat: change bg browser tabs dm --- src/components/browser/BrowserTabs.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/browser/BrowserTabs.tsx b/src/components/browser/BrowserTabs.tsx index f34fda370..3a721f4bd 100644 --- a/src/components/browser/BrowserTabs.tsx +++ b/src/components/browser/BrowserTabs.tsx @@ -49,7 +49,7 @@ export const BrowserTabs = ( background: 'white', borderRadius: '5px 5px 0px 0px', '&.Mui-selected': { - backgroundColor: ` ${isDarkMode ? "#2a2a2a" : "#f5f5f5"}`, + backgroundColor: ` ${isDarkMode ? "121111ff" : "#f5f5f5"}`, color: '#ff00c3', // Slightly lighter text when selected }, }} From b78a21ec1748b9d11e345244e2385013df401e95 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 17:46:52 +0530 Subject: [PATCH 19/37] feat: sync bg browser nav dm --- src/components/browser/BrowserNavBar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/browser/BrowserNavBar.tsx b/src/components/browser/BrowserNavBar.tsx index a06b7b4ec..8df8df108 100644 --- a/src/components/browser/BrowserNavBar.tsx +++ b/src/components/browser/BrowserNavBar.tsx @@ -14,7 +14,7 @@ import { useThemeMode } from '../../context/theme-provider'; const StyledNavBar = styled.div<{ browserWidth: number; isDarkMode: boolean }>` display: flex; padding: 12px 0px; - background-color: ${({ isDarkMode }) => (isDarkMode ? '#2C2F33' : '#f6f6f6')}; + background-color: ${({ isDarkMode }) => (isDarkMode ? '#1d1c1cff' : '#f6f6f6')}; width: ${({ browserWidth }) => browserWidth}px; border-radius: 0px 5px 0px 0px; `; From 1b68ec84bd3a0a363786259b5450d91216a9d0e1 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 17:47:03 +0530 Subject: [PATCH 20/37] feat: sync bg browser nav dm --- src/components/browser/BrowserNavBar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/browser/BrowserNavBar.tsx b/src/components/browser/BrowserNavBar.tsx index 8df8df108..f5ee382d9 100644 --- a/src/components/browser/BrowserNavBar.tsx +++ b/src/components/browser/BrowserNavBar.tsx @@ -20,7 +20,7 @@ const StyledNavBar = styled.div<{ browserWidth: number; isDarkMode: boolean }>` `; const IconButton = styled(NavBarButton) <{ mode: string }>` - background-color: ${({ mode }) => (mode === 'dark' ? '#2C2F33' : '#f6f6f6')}; + background-color: ${({ mode }) => (mode === 'dark' ? '1d1c1cff' : '#f6f6f6')}; transition: background-color 0.3s ease, transform 0.1s ease; color: ${({ mode }) => (mode === 'dark' ? '#FFFFFF' : '#333')}; cursor: pointer; From c8582c6426c5254723bf963b7363e810c7915c16 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 17:47:26 +0530 Subject: [PATCH 21/37] feat: sync bg browser nav dm --- src/components/browser/BrowserNavBar.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/browser/BrowserNavBar.tsx b/src/components/browser/BrowserNavBar.tsx index f5ee382d9..e651ed265 100644 --- a/src/components/browser/BrowserNavBar.tsx +++ b/src/components/browser/BrowserNavBar.tsx @@ -20,12 +20,12 @@ const StyledNavBar = styled.div<{ browserWidth: number; isDarkMode: boolean }>` `; const IconButton = styled(NavBarButton) <{ mode: string }>` - background-color: ${({ mode }) => (mode === 'dark' ? '1d1c1cff' : '#f6f6f6')}; + background-color: ${({ mode }) => (mode === 'dark' ? '#1d1c1cff' : '#f6f6f6')}; transition: background-color 0.3s ease, transform 0.1s ease; color: ${({ mode }) => (mode === 'dark' ? '#FFFFFF' : '#333')}; cursor: pointer; &:hover { - background-color: ${({ mode }) => (mode === 'dark' ? '#586069' : '#D0D0D0')}; + background-color: ${({ mode }) => (mode === 'dark' ? '#1d1c1cff' : '#D0D0D0')}; } `; From bdf726dcc5c892ba6fdbceb7e6a70d1176145377 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 17:49:14 +0530 Subject: [PATCH 22/37] feat: sync action description box dark mode bg --- src/components/action/ActionDescriptionBox.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/action/ActionDescriptionBox.tsx b/src/components/action/ActionDescriptionBox.tsx index d36db4079..e8c11cd5e 100644 --- a/src/components/action/ActionDescriptionBox.tsx +++ b/src/components/action/ActionDescriptionBox.tsx @@ -16,7 +16,7 @@ const CustomBoxContainer = styled.div` min-height: 100px; height: auto; border-radius: 5px; - background-color: ${({ isDarkMode }) => (isDarkMode ? '#313438' : 'white')}; + background-color: ${({ isDarkMode }) => (isDarkMode ? '#1d1c1cff' : 'white')}; color: ${({ isDarkMode }) => (isDarkMode ? 'white' : 'black')}; margin: 80px 13px 25px 13px; box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1); From 242c73f46eafb2d794a7bf1f4c6b1c3672a0ddee Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 17:49:29 +0530 Subject: [PATCH 23/37] feat: sync action description box dark mode bg --- src/components/action/ActionDescriptionBox.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/action/ActionDescriptionBox.tsx b/src/components/action/ActionDescriptionBox.tsx index e8c11cd5e..ac730b064 100644 --- a/src/components/action/ActionDescriptionBox.tsx +++ b/src/components/action/ActionDescriptionBox.tsx @@ -31,7 +31,7 @@ const Triangle = styled.div` height: 0; border-left: 20px solid transparent; border-right: 20px solid transparent; - border-bottom: 20px solid ${({ isDarkMode }) => (isDarkMode ? '#313438' : 'white')}; + border-bottom: 20px solid ${({ isDarkMode }) => (isDarkMode ? '#1d1c1cff' : 'white')}; `; const Logo = styled.img` From f61daeec3dfd07e431eb40a69fb0d1d1aea982e2 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 17:50:38 +0530 Subject: [PATCH 24/37] feat: remove unwanted textfield capture text sx styles --- src/components/recorder/RightSidePanel.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/recorder/RightSidePanel.tsx b/src/components/recorder/RightSidePanel.tsx index bf0a10c4d..1938a2eec 100644 --- a/src/components/recorder/RightSidePanel.tsx +++ b/src/components/recorder/RightSidePanel.tsx @@ -1080,7 +1080,6 @@ export const RightSidePanel: React.FC = ({ onFinishCapture ) }} - sx={{ background: isDarkMode ? "#1E2124" : 'white', color: isDarkMode ? "white" : 'black' }} /> Date: Mon, 13 Oct 2025 17:52:09 +0530 Subject: [PATCH 25/37] feat: capture actions box dark mode bg --- src/components/recorder/RightSidePanel.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/recorder/RightSidePanel.tsx b/src/components/recorder/RightSidePanel.tsx index 1938a2eec..037e32c48 100644 --- a/src/components/recorder/RightSidePanel.tsx +++ b/src/components/recorder/RightSidePanel.tsx @@ -1059,7 +1059,7 @@ export const RightSidePanel: React.FC = ({ onFinishCapture {browserSteps.map(step => ( - handleMouseEnter(step.id)} onMouseLeave={() => handleMouseLeave(step.id)} sx={{ padding: '10px', margin: '11px', borderRadius: '5px', position: 'relative', background: isDarkMode ? "#1E2124" : 'white', color: isDarkMode ? "white" : 'black' }}> + handleMouseEnter(step.id)} onMouseLeave={() => handleMouseLeave(step.id)} sx={{ padding: '10px', margin: '11px', borderRadius: '5px', position: 'relative', background: isDarkMode ? "#1d1c1cff" : 'white', color: isDarkMode ? "white" : 'black' }}> { step.type === 'text' && ( <> From 270782917fbe35ea1049cd899dac02fa6a08a765 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 17:56:02 +0530 Subject: [PATCH 26/37] feat: sync dark mode bg output preview --- src/components/run/InterpretationLog.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/run/InterpretationLog.tsx b/src/components/run/InterpretationLog.tsx index faf965e91..d03821202 100644 --- a/src/components/run/InterpretationLog.tsx +++ b/src/components/run/InterpretationLog.tsx @@ -193,7 +193,7 @@ export const InterpretationLog: React.FC = ({ isOpen, se onOpen={toggleDrawer(true)} PaperProps={{ sx: { - background: `${darkMode ? '#1e2124' : 'white'}`, + background: `${darkMode ? '#1d1c1cff' : 'white'}`, color: `${darkMode ? 'white' : 'black'}`, padding: '10px', height: outputPreviewHeight, From 6108629ff9615a82acbf92bfc2870bba24941bd7 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 17:56:54 +0530 Subject: [PATCH 27/37] feat: remove unwated styled --- src/components/run/InterpretationLog.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/run/InterpretationLog.tsx b/src/components/run/InterpretationLog.tsx index d03821202..ec6a9d9b4 100644 --- a/src/components/run/InterpretationLog.tsx +++ b/src/components/run/InterpretationLog.tsx @@ -216,8 +216,6 @@ export const InterpretationLog: React.FC = ({ isOpen, se sx={{ display: 'flex', borderBottom: '1px solid', - borderColor: darkMode ? '#3a4453' : '#dee2e6', - backgroundColor: darkMode ? '#2a3441' : '#f8f9fa' }} > {availableTabs.map((tab, index) => ( From da50be7d8c3dfc51b649e331d47b700c8d7f6b39 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 17:59:48 +0530 Subject: [PATCH 28/37] feat: output preview revamp --- src/components/run/InterpretationLog.tsx | 60 +++++++++++++++--------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/src/components/run/InterpretationLog.tsx b/src/components/run/InterpretationLog.tsx index ec6a9d9b4..c0c9d8fd0 100644 --- a/src/components/run/InterpretationLog.tsx +++ b/src/components/run/InterpretationLog.tsx @@ -22,9 +22,10 @@ import { useBrowserSteps } from '../../context/browserSteps'; interface InterpretationLogProps { isOpen: boolean; setIsOpen: (isOpen: boolean) => void; + tutorialMode?: boolean; } -export const InterpretationLog: React.FC = ({ isOpen, setIsOpen }) => { +export const InterpretationLog: React.FC = ({ isOpen, setIsOpen, tutorialMode = false }) => { const { t } = useTranslation(); const [captureListData, setCaptureListData] = useState([]); @@ -68,6 +69,7 @@ export const InterpretationLog: React.FC = ({ isOpen, se } }, [captureListData.length, captureTextData.length, screenshotData.length]); + useEffect(() => { const textSteps = browserSteps.filter(step => step.type === 'text'); if (textSteps.length > 0) { @@ -144,6 +146,16 @@ export const InterpretationLog: React.FC = ({ isOpen, se } }, [hasScrapeListAction, hasScrapeSchemaAction, hasScreenshotAction, setIsOpen]); + useEffect(() => { + if ( + tutorialMode && + (hasScrapeListAction || hasScrapeSchemaAction || hasScreenshotAction) + ) { + setShowPreviewData(true); + setIsOpen(true); // auto-open drawer + } + }, [tutorialMode, hasScrapeListAction, hasScrapeSchemaAction, hasScreenshotAction, setIsOpen]); + const { darkMode } = useThemeMode(); const getCaptureTextColumns = captureTextData.length > 0 ? Object.keys(captureTextData[0]) : []; @@ -216,6 +228,8 @@ export const InterpretationLog: React.FC = ({ isOpen, se sx={{ display: 'flex', borderBottom: '1px solid', + borderColor: darkMode ? '#080808ff' : '#dee2e6', + backgroundColor: darkMode ? '#080808ff' : '#f8f9fa' }} > {availableTabs.map((tab, index) => ( @@ -226,15 +240,15 @@ export const InterpretationLog: React.FC = ({ isOpen, se px: 4, py: 2, cursor: 'pointer', - borderBottom: activeTab === index ? '2px solid' : 'none', + // borderBottom: activeTab === index ? '2px solid' : 'none', borderColor: activeTab === index ? (darkMode ? '#ff00c3' : '#ff00c3') : 'transparent', - backgroundColor: activeTab === index ? (darkMode ? '#34404d' : '#e9ecef') : 'transparent', + backgroundColor: activeTab === index ? (darkMode ? '#121111ff' : '#e9ecef') : 'transparent', color: darkMode ? 'white' : 'black', fontWeight: activeTab === index ? 500 : 400, textAlign: 'center', position: 'relative', '&:hover': { - backgroundColor: activeTab !== index ? (darkMode ? '#303b49' : '#e2e6ea') : undefined + backgroundColor: activeTab !== index ? (darkMode ? '#121111ff' : '#e2e6ea') : undefined } }} > @@ -286,8 +300,8 @@ export const InterpretationLog: React.FC = ({ isOpen, se key={index} sx={{ borderBottom: '1px solid', - borderColor: darkMode ? '#3a4453' : '#dee2e6', - backgroundColor: darkMode ? '#2a3441' : '#f8f9fa' + borderColor: darkMode ? '#080808ff' : '#dee2e6', + backgroundColor: darkMode ? '#080808ff' : '#f8f9fa' }} > {field.label} @@ -297,16 +311,16 @@ export const InterpretationLog: React.FC = ({ isOpen, se {(captureListData[captureListPage]?.data || []) - .slice(0, Math.min(captureListData[captureListPage]?.limit || 10, 5)) + .slice(0, tutorialMode ? (captureListData[captureListPage]?.data?.length || 0) : Math.min(captureListData[captureListPage]?.limit || 10, 5)) .map((row: any, rowIndex: any) => ( - {Object.values(captureListData[captureListPage]?.fields || {}).map((field: any, colIndex) => ( @@ -317,7 +331,7 @@ export const InterpretationLog: React.FC = ({ isOpen, se py: 2 }} > - {row[field.label]} + {typeof row[field.label] === 'object' ? JSON.stringify(row[field.label]) : String(row[field.label] || '')} ))} @@ -377,7 +391,7 @@ export const InterpretationLog: React.FC = ({ isOpen, se )} {(activeTab === availableTabs.findIndex(tab => tab.id === 'captureText') || singleContentType === 'captureText') && captureTextData.length > 0 && ( - + @@ -385,8 +399,8 @@ export const InterpretationLog: React.FC = ({ isOpen, se Label @@ -394,8 +408,8 @@ export const InterpretationLog: React.FC = ({ isOpen, se Value @@ -408,7 +422,7 @@ export const InterpretationLog: React.FC = ({ isOpen, se key={column} sx={{ borderBottom: index < getCaptureTextColumns.length - 1 ? '1px solid' : 'none', - borderColor: darkMode ? '#3a4453' : '#dee2e6' + borderColor: darkMode ? '#080808ff' : '#dee2e6' }} > = ({ isOpen, se py: 2 }} > - {captureTextData[0][column]} + {typeof captureTextData[0][column] === 'object' ? JSON.stringify(captureTextData[0][column]) : String(captureTextData[0][column] || '')} ))} @@ -445,7 +459,9 @@ export const InterpretationLog: React.FC = ({ isOpen, se {t('interpretation_log.messages.successful_training')} - setShowPreviewData(true)} /> + {!tutorialMode && ( + setShowPreviewData(true)} /> + )} ) : ( From 60b96596cd201545c6f6d7e11901168bf494cfb8 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 18:00:59 +0530 Subject: [PATCH 29/37] feat: sync dark mode w cloud --- src/context/theme-provider.tsx | 36 +++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/context/theme-provider.tsx b/src/context/theme-provider.tsx index ccc4fda1c..1bff81f75 100644 --- a/src/context/theme-provider.tsx +++ b/src/context/theme-provider.tsx @@ -94,7 +94,7 @@ const darkTheme = createTheme({ }, background: { default: '#000000ff', - paper: '#080808ff', + paper: '#000000ff', }, text: { primary: '#ffffff', @@ -127,14 +127,14 @@ const darkTheme = createTheme({ borderColor: '#ff00c3', color: '#ff00c3', "&:hover": { - backgroundColor: 'rgba(255, 0, 195, 0.08)', + // backgroundColor: 'rgba(255, 0, 195, 0.08)', borderColor: '#ff66d9', }, '&.MuiButton-outlinedError': { borderColor: '#f44336', color: '#f44336', "&:hover": { - backgroundColor: 'rgba(244, 67, 54, 0.08)', + // backgroundColor: 'rgba(244, 67, 54, 0.08)', borderColor: '#d32f2f', }, }, @@ -155,14 +155,14 @@ const darkTheme = createTheme({ styleOverrides: { root: { color: '#ffffff', - "&:hover": { - backgroundColor: 'rgba(255, 0, 195, 0.08)', - }, + // "&:hover": { + // backgroundColor: 'rgba(255, 0, 195, 0.08)', + // }, '&.MuiIconButton-colorError': { color: '#f44336', - "&:hover": { - backgroundColor: 'rgba(244, 67, 54, 0.08)', - }, + // "&:hover": { + // backgroundColor: 'rgba(244, 67, 54, 0.08)', + // }, }, }, }, @@ -181,7 +181,7 @@ const darkTheme = createTheme({ MuiAlert: { styleOverrides: { standardInfo: { - backgroundColor: "rgba(255, 0, 195, 0.15)", + // backgroundColor: "rgba(255, 0, 195, 0.15)", color: "#ff66d9", "& .MuiAlert-icon": { color: "#ff66d9", @@ -202,8 +202,8 @@ const darkTheme = createTheme({ MuiPaper: { styleOverrides: { root: { - backgroundColor: '#080808ff', - border: '1px solid #121111ff', + backgroundColor: '#000000ff', + border: '1px solid #080808ff', }, }, }, @@ -231,10 +231,18 @@ const darkTheme = createTheme({ MuiDivider: { styleOverrides: { root: { - borderColor: '#080808ff', + borderColor: '#494949ff', }, }, }, + // MuiTextField:{ + // styleOverrides: { + // root: { + // '& .MuiInputBase-root': { + // backgroundColor: '#1d1c1cff', + // }, + // } + // }} }, }); @@ -274,4 +282,4 @@ const ThemeModeProvider = ({ children }: { children: React.ReactNode }) => { ); }; -export default ThemeModeProvider; +export default ThemeModeProvider; \ No newline at end of file From fcf1f68177c93e144aed4c96363c1401aca46271 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 18:02:11 +0530 Subject: [PATCH 30/37] feat: use divider instead of hr --- src/components/dashboard/MainMenu.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/dashboard/MainMenu.tsx b/src/components/dashboard/MainMenu.tsx index 05846b758..2cfaab03e 100644 --- a/src/components/dashboard/MainMenu.tsx +++ b/src/components/dashboard/MainMenu.tsx @@ -3,7 +3,7 @@ import Tabs from '@mui/material/Tabs'; import Tab from '@mui/material/Tab'; import Box from '@mui/material/Box'; import { useNavigate, useLocation } from 'react-router-dom'; -import { Paper, Button, useTheme, Modal, Typography, Stack, TextField, InputAdornment, IconButton } from "@mui/material"; +import { Paper, Button, useTheme, Modal, Typography, Stack, TextField, InputAdornment, IconButton, Divider } from "@mui/material"; import { AutoAwesome, FormatListBulleted, VpnKey, Usb, CloudQueue, Description, Favorite, ContentCopy, SlowMotionVideo } from "@mui/icons-material"; import { useTranslation } from 'react-i18next'; import { useGlobalInfoStore } from "../../context/globalInfo"; @@ -94,7 +94,7 @@ export const MainMenu = ({ value = 'robots', handleChangeContent }: MainMenuProp } iconPosition="start" sx={{ justifyContent: 'flex-start', textAlign: 'left', fontSize: 'medium' }} /> } iconPosition="start" sx={{ justifyContent: 'flex-start', textAlign: 'left', fontSize: 'medium' }} /> -
+
- + {/* */} {columns.map((column) => ( ))} - + {/* */} {visibleRows.map((row) => ( Date: Mon, 13 Oct 2025 18:05:53 +0530 Subject: [PATCH 34/37] fix: background color override for mui alert dark theme --- src/context/theme-provider.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/context/theme-provider.tsx b/src/context/theme-provider.tsx index 1bff81f75..ef16069f0 100644 --- a/src/context/theme-provider.tsx +++ b/src/context/theme-provider.tsx @@ -181,7 +181,7 @@ const darkTheme = createTheme({ MuiAlert: { styleOverrides: { standardInfo: { - // backgroundColor: "rgba(255, 0, 195, 0.15)", + backgroundColor: "rgba(255, 0, 195, 0.15)", color: "#ff66d9", "& .MuiAlert-icon": { color: "#ff66d9", From 820444218dc72555d288ef8cfbd70c03a0f2af86 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 20:04:06 +0530 Subject: [PATCH 35/37] fix: missing # --- src/components/browser/BrowserTabs.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/browser/BrowserTabs.tsx b/src/components/browser/BrowserTabs.tsx index 3a721f4bd..e375fb932 100644 --- a/src/components/browser/BrowserTabs.tsx +++ b/src/components/browser/BrowserTabs.tsx @@ -49,7 +49,7 @@ export const BrowserTabs = ( background: 'white', borderRadius: '5px 5px 0px 0px', '&.Mui-selected': { - backgroundColor: ` ${isDarkMode ? "121111ff" : "#f5f5f5"}`, + backgroundColor: ` ${isDarkMode ? "#121111ff" : "#f5f5f5"}`, color: '#ff00c3', // Slightly lighter text when selected }, }} From 0f771bba258805c0eb6f4ae27817b5e8e3721a02 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 20:07:15 +0530 Subject: [PATCH 36/37] fix: -rm tutorial mode --- src/components/run/InterpretationLog.tsx | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/src/components/run/InterpretationLog.tsx b/src/components/run/InterpretationLog.tsx index c0c9d8fd0..7180014b8 100644 --- a/src/components/run/InterpretationLog.tsx +++ b/src/components/run/InterpretationLog.tsx @@ -22,10 +22,9 @@ import { useBrowserSteps } from '../../context/browserSteps'; interface InterpretationLogProps { isOpen: boolean; setIsOpen: (isOpen: boolean) => void; - tutorialMode?: boolean; } -export const InterpretationLog: React.FC = ({ isOpen, setIsOpen, tutorialMode = false }) => { +export const InterpretationLog: React.FC = ({ isOpen, setIsOpen }) => { const { t } = useTranslation(); const [captureListData, setCaptureListData] = useState([]); @@ -146,15 +145,6 @@ export const InterpretationLog: React.FC = ({ isOpen, se } }, [hasScrapeListAction, hasScrapeSchemaAction, hasScreenshotAction, setIsOpen]); - useEffect(() => { - if ( - tutorialMode && - (hasScrapeListAction || hasScrapeSchemaAction || hasScreenshotAction) - ) { - setShowPreviewData(true); - setIsOpen(true); // auto-open drawer - } - }, [tutorialMode, hasScrapeListAction, hasScrapeSchemaAction, hasScreenshotAction, setIsOpen]); const { darkMode } = useThemeMode(); @@ -311,14 +301,13 @@ export const InterpretationLog: React.FC = ({ isOpen, se {(captureListData[captureListPage]?.data || []) - .slice(0, tutorialMode ? (captureListData[captureListPage]?.data?.length || 0) : Math.min(captureListData[captureListPage]?.limit || 10, 5)) + .slice(0, Math.min(captureListData[captureListPage]?.limit || 10, 5)) .map((row: any, rowIndex: any) => ( = ({ isOpen, se {t('interpretation_log.messages.successful_training')} - {!tutorialMode && ( - setShowPreviewData(true)} /> - )} ) : ( From 3f0e252638f911b7b89ede0f8ed5c93e4a833e75 Mon Sep 17 00:00:00 2001 From: amhsirak Date: Mon, 13 Oct 2025 20:23:28 +0530 Subject: [PATCH 37/37] fix: output preview button --- src/components/run/InterpretationLog.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/run/InterpretationLog.tsx b/src/components/run/InterpretationLog.tsx index 7180014b8..49e4a7041 100644 --- a/src/components/run/InterpretationLog.tsx +++ b/src/components/run/InterpretationLog.tsx @@ -448,6 +448,7 @@ export const InterpretationLog: React.FC = ({ isOpen, se {t('interpretation_log.messages.successful_training')} + setShowPreviewData(true)} /> ) : (