language support
This commit is contained in:
50
public/locales/de.json
Normal file
50
public/locales/de.json
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"login": {
|
||||||
|
"title": "Willkommen zurück!",
|
||||||
|
"email": "E-Mail",
|
||||||
|
"password": "Passwort",
|
||||||
|
"button": "Einloggen",
|
||||||
|
"loading": "Lädt",
|
||||||
|
"register_prompt": "Noch keinen Account?",
|
||||||
|
"register_link": "Registrieren",
|
||||||
|
"welcome_notification": "Willkommen bei Maxun!",
|
||||||
|
"error_notification": "Anmeldung fehlgeschlagen. Bitte versuchen Sie es erneut."
|
||||||
|
},
|
||||||
|
"register": {
|
||||||
|
"title": "Konto registrieren",
|
||||||
|
"email": "E-Mail",
|
||||||
|
"password": "Passwort",
|
||||||
|
"button": "Registrieren",
|
||||||
|
"loading": "Lädt",
|
||||||
|
"register_prompt": "Bereits ein Konto?",
|
||||||
|
"login_link": "Einloggen",
|
||||||
|
"welcome_notification": "Willkommen bei Maxun!",
|
||||||
|
"error_notification": "Registrierung fehlgeschlagen. Bitte versuchen Sie es erneut."
|
||||||
|
},
|
||||||
|
"recordingtable": {
|
||||||
|
"run": "Ausführen",
|
||||||
|
"name": "Name",
|
||||||
|
"schedule": "Zeitplan",
|
||||||
|
"integrate": "Integrieren",
|
||||||
|
"settings": "Einstellungen",
|
||||||
|
"options": "Optionen",
|
||||||
|
"heading": "Meine Roboter",
|
||||||
|
"new": "Roboter erstellen",
|
||||||
|
"modal": {
|
||||||
|
"title": "Geben Sie die URL ein",
|
||||||
|
"label": "URL",
|
||||||
|
"button": "Aufnahme starten"
|
||||||
|
},
|
||||||
|
"edit": "Bearbeiten",
|
||||||
|
"delete": "Löschen",
|
||||||
|
"duplicate": "Duplizieren"
|
||||||
|
},
|
||||||
|
"mainmenu": {
|
||||||
|
"recordings": "Roboter",
|
||||||
|
"runs": "Ausführungen",
|
||||||
|
"proxy": "Proxy",
|
||||||
|
"apikey": "API-Schlüssel",
|
||||||
|
"feedback": "Maxun Cloud beitreten",
|
||||||
|
"apidocs": "API-Dokumentation"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,5 +9,45 @@
|
|||||||
"register_link": "Register",
|
"register_link": "Register",
|
||||||
"welcome_notification": "Welcome to Maxun!",
|
"welcome_notification": "Welcome to Maxun!",
|
||||||
"error_notification": "Login Failed. Please try again."
|
"error_notification": "Login Failed. Please try again."
|
||||||
|
},
|
||||||
|
"register": {
|
||||||
|
"title": "Register Account",
|
||||||
|
"email": "Email",
|
||||||
|
"password": "Password",
|
||||||
|
"button": "Register",
|
||||||
|
"loading": "Loading",
|
||||||
|
"register_prompt": "Already have an account?",
|
||||||
|
"login_link": "Login",
|
||||||
|
"welcome_notification": "Welcome to Maxun!",
|
||||||
|
"error_notification": "Registeration Failed. Please try again."
|
||||||
|
},
|
||||||
|
"recordingtable":{
|
||||||
|
"run": "Run",
|
||||||
|
"name": "Name",
|
||||||
|
"schedule": "Schedule",
|
||||||
|
"integrate": "Integrate",
|
||||||
|
"settings": "Settings",
|
||||||
|
"options": "Options",
|
||||||
|
"heading":"My Robots",
|
||||||
|
"new":"Create Robot",
|
||||||
|
"modal":{
|
||||||
|
"title":"Enter the URL",
|
||||||
|
"label":"URL",
|
||||||
|
"button":"Start Recording"
|
||||||
|
},
|
||||||
|
"edit":"Edit",
|
||||||
|
"delete":"Delete",
|
||||||
|
"duplicate":"Duplicate",
|
||||||
|
"search":"Search Robots..."
|
||||||
|
|
||||||
|
},
|
||||||
|
"mainmenu":{
|
||||||
|
"recordings": "Robots",
|
||||||
|
"runs": "Runs",
|
||||||
|
"proxy": "Proxy",
|
||||||
|
"apikey": "API Key",
|
||||||
|
"feedback":"Join Maxun Cloud",
|
||||||
|
"apidocs":"API Docs"
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,50 @@
|
|||||||
{
|
{
|
||||||
"app": {
|
"login": {
|
||||||
"name": "Maxun",
|
"title": "お帰りなさい!",
|
||||||
"version": "beta"
|
|
||||||
},
|
|
||||||
"login": {
|
|
||||||
"title": "おかえりなさい!",
|
|
||||||
"email": "メールアドレス",
|
"email": "メールアドレス",
|
||||||
"password": "パスワード",
|
"password": "パスワード",
|
||||||
"button": "ログイン",
|
"button": "ログイン",
|
||||||
"register_prompt": "アカウントをお持ちでない方は、新規登録"
|
"loading": "読み込み中",
|
||||||
}
|
"register_prompt": "アカウントをお持ちでないですか?",
|
||||||
|
"register_link": "登録する",
|
||||||
|
"welcome_notification": "Maxunへようこそ!",
|
||||||
|
"error_notification": "ログインに失敗しました。もう一度お試しください。"
|
||||||
|
},
|
||||||
|
"register": {
|
||||||
|
"title": "アカウントを登録する",
|
||||||
|
"email": "メールアドレス",
|
||||||
|
"password": "パスワード",
|
||||||
|
"button": "登録する",
|
||||||
|
"loading": "読み込み中",
|
||||||
|
"register_prompt": "既にアカウントをお持ちですか?",
|
||||||
|
"login_link": "ログイン",
|
||||||
|
"welcome_notification": "Maxunへようこそ!",
|
||||||
|
"error_notification": "登録に失敗しました。もう一度お試しください。"
|
||||||
|
},
|
||||||
|
"recordingtable": {
|
||||||
|
"run": "実行",
|
||||||
|
"name": "名前",
|
||||||
|
"schedule": "スケジュール",
|
||||||
|
"integrate": "統合",
|
||||||
|
"settings": "設定",
|
||||||
|
"options": "オプション",
|
||||||
|
"heading": "私のロボット",
|
||||||
|
"new": "ロボットを作成",
|
||||||
|
"modal": {
|
||||||
|
"title": "URLを入力してください",
|
||||||
|
"label": "URL",
|
||||||
|
"button": "録画を開始"
|
||||||
|
},
|
||||||
|
"edit": "編集",
|
||||||
|
"delete": "削除",
|
||||||
|
"duplicate": "複製"
|
||||||
|
},
|
||||||
|
"mainmenu": {
|
||||||
|
"recordings": "ロボット",
|
||||||
|
"runs": "実行",
|
||||||
|
"proxy": "プロキシ",
|
||||||
|
"apikey": "APIキー",
|
||||||
|
"feedback": "Maxunクラウドに参加する",
|
||||||
|
"apidocs": "APIドキュメント"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -245,6 +245,15 @@ export const NavBar: React.FC<NavBarProps> = ({
|
|||||||
>
|
>
|
||||||
中文
|
中文
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
<MenuItem
|
||||||
|
onClick={() => {
|
||||||
|
changeLanguage("de");
|
||||||
|
handleMenuClose();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
German
|
||||||
|
|
||||||
|
</MenuItem>
|
||||||
</Menu>
|
</Menu>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
import Paper from '@mui/material/Paper';
|
import Paper from '@mui/material/Paper';
|
||||||
import Table from '@mui/material/Table';
|
import Table from '@mui/material/Table';
|
||||||
import TableBody from '@mui/material/TableBody';
|
import TableBody from '@mui/material/TableBody';
|
||||||
@@ -19,6 +20,7 @@ import { useNavigate } from 'react-router-dom';
|
|||||||
import { stopRecording } from "../../api/recording";
|
import { stopRecording } from "../../api/recording";
|
||||||
import { GenericModal } from '../atoms/GenericModal';
|
import { GenericModal } from '../atoms/GenericModal';
|
||||||
|
|
||||||
|
|
||||||
/** TODO:
|
/** TODO:
|
||||||
* 1. allow editing existing robot after persisting browser steps
|
* 1. allow editing existing robot after persisting browser steps
|
||||||
*/
|
*/
|
||||||
@@ -31,30 +33,9 @@ interface Column {
|
|||||||
format?: (value: string) => string;
|
format?: (value: string) => string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const columns: readonly Column[] = [
|
|
||||||
{ id: 'interpret', label: 'Run', minWidth: 80 },
|
|
||||||
{ id: 'name', label: 'Name', minWidth: 80 },
|
|
||||||
{
|
|
||||||
id: 'schedule',
|
|
||||||
label: 'Schedule',
|
|
||||||
minWidth: 80,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'integrate',
|
|
||||||
label: 'Integrate',
|
|
||||||
minWidth: 80,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'settings',
|
|
||||||
label: 'Settings',
|
|
||||||
minWidth: 80,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'options',
|
|
||||||
label: 'Options',
|
|
||||||
minWidth: 80,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
interface Data {
|
interface Data {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -76,12 +57,38 @@ interface RecordingsTableProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const RecordingsTable = ({ handleEditRecording, handleRunRecording, handleScheduleRecording, handleIntegrateRecording, handleSettingsRecording, handleEditRobot, handleDuplicateRobot }: RecordingsTableProps) => {
|
export const RecordingsTable = ({ handleEditRecording, handleRunRecording, handleScheduleRecording, handleIntegrateRecording, handleSettingsRecording, handleEditRobot, handleDuplicateRobot }: RecordingsTableProps) => {
|
||||||
|
const {t} = useTranslation();
|
||||||
const [page, setPage] = React.useState(0);
|
const [page, setPage] = React.useState(0);
|
||||||
const [rowsPerPage, setRowsPerPage] = React.useState(10);
|
const [rowsPerPage, setRowsPerPage] = React.useState(10);
|
||||||
const [rows, setRows] = React.useState<Data[]>([]);
|
const [rows, setRows] = React.useState<Data[]>([]);
|
||||||
const [isModalOpen, setModalOpen] = React.useState(false);
|
const [isModalOpen, setModalOpen] = React.useState(false);
|
||||||
const [searchTerm, setSearchTerm] = React.useState('');
|
const [searchTerm, setSearchTerm] = React.useState('');
|
||||||
|
|
||||||
|
const columns: readonly Column[] = [
|
||||||
|
{ id: 'interpret', label: t('recordingtable.run'), minWidth: 80 },
|
||||||
|
{ id: 'name', label: t('recordingtable.name'), minWidth: 80 },
|
||||||
|
{
|
||||||
|
id: 'schedule',
|
||||||
|
label: t('recordingtable.schedule'),
|
||||||
|
minWidth: 80,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'integrate',
|
||||||
|
label: t('recordingtable.integrate'),
|
||||||
|
minWidth: 80,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'settings',
|
||||||
|
label: t('recordingtable.settings'),
|
||||||
|
minWidth: 80,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'options',
|
||||||
|
label: t('recordingtable.options'),
|
||||||
|
minWidth: 80,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const { notify, setRecordings, browserId, setBrowserId, recordingUrl, setRecordingUrl, recordingName, setRecordingName, recordingId, setRecordingId } = useGlobalInfoStore();
|
const { notify, setRecordings, browserId, setBrowserId, recordingUrl, setRecordingUrl, recordingName, setRecordingName, recordingId, setRecordingId } = useGlobalInfoStore();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
@@ -154,16 +161,17 @@ export const RecordingsTable = ({ handleEditRecording, handleRunRecording, handl
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Box display="flex" justifyContent="space-between" alignItems="center">
|
<Box display="flex" justifyContent="space-between" alignItems="center">
|
||||||
<Typography variant="h6" gutterBottom>
|
<Typography variant="h6" gutterBottom>
|
||||||
My Robots
|
{t('recordingtable.heading')}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box display="flex" alignItems="center" gap={2}>
|
<Box display="flex" alignItems="center" gap={2}>
|
||||||
<TextField
|
<TextField
|
||||||
size="small"
|
size="small"
|
||||||
placeholder="Search robots..."
|
placeholder={t('recordingtable.search')}
|
||||||
value={searchTerm}
|
value={searchTerm}
|
||||||
onChange={handleSearchChange}
|
onChange={handleSearchChange}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
@@ -190,7 +198,7 @@ export const RecordingsTable = ({ handleEditRecording, handleRunRecording, handl
|
|||||||
'&:hover': { color: 'white', backgroundColor: '#ff00c3' }
|
'&:hover': { color: 'white', backgroundColor: '#ff00c3' }
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Add sx={{ marginRight: '5px' }} /> Create Robot
|
<Add sx={{ marginRight: '5px' }} /> {t('recordingtable.new')}
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -300,9 +308,9 @@ export const RecordingsTable = ({ handleEditRecording, handleRunRecording, handl
|
|||||||
/>
|
/>
|
||||||
<GenericModal isOpen={isModalOpen} onClose={() => setModalOpen(false)} modalStyle={modalStyle}>
|
<GenericModal isOpen={isModalOpen} onClose={() => setModalOpen(false)} modalStyle={modalStyle}>
|
||||||
<div style={{ padding: '20px' }}>
|
<div style={{ padding: '20px' }}>
|
||||||
<Typography variant="h6" gutterBottom>Enter URL To Extract Data</Typography>
|
<Typography variant="h6" gutterBottom>{t('recordingtable.modal.title')}</Typography>
|
||||||
<TextField
|
<TextField
|
||||||
label="URL"
|
label={t('recordingtable.modal.label')}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
fullWidth
|
fullWidth
|
||||||
value={recordingUrl}
|
value={recordingUrl}
|
||||||
@@ -315,7 +323,7 @@ export const RecordingsTable = ({ handleEditRecording, handleRunRecording, handl
|
|||||||
onClick={startRecording}
|
onClick={startRecording}
|
||||||
disabled={!recordingUrl}
|
disabled={!recordingUrl}
|
||||||
>
|
>
|
||||||
Start Training Robot
|
{t('recordingtable.modal.button')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</GenericModal>
|
</GenericModal>
|
||||||
@@ -400,6 +408,8 @@ const OptionsButton = ({ handleEdit, handleDelete, handleDuplicate }: OptionsBut
|
|||||||
setAnchorEl(null);
|
setAnchorEl(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const {t} = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<IconButton
|
<IconButton
|
||||||
@@ -418,19 +428,19 @@ const OptionsButton = ({ handleEdit, handleDelete, handleDuplicate }: OptionsBut
|
|||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<Edit fontSize="small" />
|
<Edit fontSize="small" />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText>Edit</ListItemText>
|
<ListItemText>{t('recordingtable.edit')}</ListItemText>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem onClick={() => { handleDelete(); handleClose(); }}>
|
<MenuItem onClick={() => { handleDelete(); handleClose(); }}>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<DeleteForever fontSize="small" />
|
<DeleteForever fontSize="small" />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText>Delete</ListItemText>
|
<ListItemText>{t('recordingtable.delete')}</ListItemText>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem onClick={() => { handleDuplicate(); handleClose(); }}>
|
<MenuItem onClick={() => { handleDuplicate(); handleClose(); }}>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<ContentCopy fontSize="small" />
|
<ContentCopy fontSize="small" />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText>Duplicate</ListItemText>
|
<ListItemText>{t('recordingtable.duplicate')}</ListItemText>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</Menu>
|
</Menu>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ import Box from '@mui/material/Box';
|
|||||||
import { Paper, Button } from "@mui/material";
|
import { Paper, Button } from "@mui/material";
|
||||||
import { AutoAwesome, FormatListBulleted, VpnKey, Usb, CloudQueue, Code } from "@mui/icons-material";
|
import { AutoAwesome, FormatListBulleted, VpnKey, Usb, CloudQueue, Code } from "@mui/icons-material";
|
||||||
import { apiUrl } from "../../apiConfig";
|
import { apiUrl } from "../../apiConfig";
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import i18n from '../../i18n';
|
||||||
|
|
||||||
|
|
||||||
interface MainMenuProps {
|
interface MainMenuProps {
|
||||||
value: string;
|
value: string;
|
||||||
@@ -12,6 +15,7 @@ interface MainMenuProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const MainMenu = ({ value = 'recordings', handleChangeContent }: MainMenuProps) => {
|
export const MainMenu = ({ value = 'recordings', handleChangeContent }: MainMenuProps) => {
|
||||||
|
const {t} = useTranslation();
|
||||||
|
|
||||||
const handleChange = (event: React.SyntheticEvent, newValue: string) => {
|
const handleChange = (event: React.SyntheticEvent, newValue: string) => {
|
||||||
handleChangeContent(newValue);
|
handleChangeContent(newValue);
|
||||||
@@ -47,7 +51,7 @@ export const MainMenu = ({ value = 'recordings', handleChangeContent }: MainMenu
|
|||||||
fontSize: 'medium',
|
fontSize: 'medium',
|
||||||
}}
|
}}
|
||||||
value="recordings"
|
value="recordings"
|
||||||
label="Robots"
|
label={t('mainmenu.recordings')}
|
||||||
icon={<AutoAwesome />}
|
icon={<AutoAwesome />}
|
||||||
iconPosition="start"
|
iconPosition="start"
|
||||||
/>
|
/>
|
||||||
@@ -58,7 +62,7 @@ export const MainMenu = ({ value = 'recordings', handleChangeContent }: MainMenu
|
|||||||
fontSize: 'medium',
|
fontSize: 'medium',
|
||||||
}}
|
}}
|
||||||
value="runs"
|
value="runs"
|
||||||
label="Runs"
|
label={t('mainmenu.runs')}
|
||||||
icon={<FormatListBulleted />}
|
icon={<FormatListBulleted />}
|
||||||
iconPosition="start"
|
iconPosition="start"
|
||||||
/>
|
/>
|
||||||
@@ -69,7 +73,7 @@ export const MainMenu = ({ value = 'recordings', handleChangeContent }: MainMenu
|
|||||||
fontSize: 'medium',
|
fontSize: 'medium',
|
||||||
}}
|
}}
|
||||||
value="proxy"
|
value="proxy"
|
||||||
label="Proxy"
|
label={t('mainmenu.proxy')}
|
||||||
icon={<Usb />}
|
icon={<Usb />}
|
||||||
iconPosition="start"
|
iconPosition="start"
|
||||||
/>
|
/>
|
||||||
@@ -80,7 +84,7 @@ export const MainMenu = ({ value = 'recordings', handleChangeContent }: MainMenu
|
|||||||
fontSize: 'medium',
|
fontSize: 'medium',
|
||||||
}}
|
}}
|
||||||
value="apikey"
|
value="apikey"
|
||||||
label="API Key"
|
label={t('mainmenu.apikey')}
|
||||||
icon={<VpnKey />}
|
icon={<VpnKey />}
|
||||||
iconPosition="start"
|
iconPosition="start"
|
||||||
/>
|
/>
|
||||||
@@ -88,10 +92,10 @@ export const MainMenu = ({ value = 'recordings', handleChangeContent }: MainMenu
|
|||||||
<hr />
|
<hr />
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: '1rem', textAlign: 'left' }}>
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: '1rem', textAlign: 'left' }}>
|
||||||
<Button href={`${apiUrl}/api-docs/`} target="_blank" rel="noopener noreferrer" sx={buttonStyles} startIcon={<Code />}>
|
<Button href={`${apiUrl}/api-docs/`} target="_blank" rel="noopener noreferrer" sx={buttonStyles} startIcon={<Code />}>
|
||||||
Website To API
|
{t('mainmenu.apidocs')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button href="https://forms.gle/hXjgqDvkEhPcaBW76" target="_blank" rel="noopener noreferrer" sx={buttonStyles} startIcon={<CloudQueue />}>
|
<Button href="https://forms.gle/hXjgqDvkEhPcaBW76" target="_blank" rel="noopener noreferrer" sx={buttonStyles} startIcon={<CloudQueue />}>
|
||||||
Join Maxun Cloud
|
{t('mainmenu.feedback')}
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ i18n
|
|||||||
.init({
|
.init({
|
||||||
fallbackLng: 'en',
|
fallbackLng: 'en',
|
||||||
debug: import.meta.env.DEV,
|
debug: import.meta.env.DEV,
|
||||||
supportedLngs: ['en', 'es', 'ja', 'zh', 'ar'],
|
supportedLngs: ['en', 'es', 'ja', 'zh','de'],
|
||||||
interpolation: {
|
interpolation: {
|
||||||
escapeValue: false, // React already escapes
|
escapeValue: false, // React already escapes
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ import { Box, Typography, TextField, Button, CircularProgress, Grid } from "@mui
|
|||||||
import { useGlobalInfoStore } from "../context/globalInfo";
|
import { useGlobalInfoStore } from "../context/globalInfo";
|
||||||
import { apiUrl } from "../apiConfig";
|
import { apiUrl } from "../apiConfig";
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import i18n from '../i18n'; // Add this import
|
import i18n from '../i18n';
|
||||||
|
|
||||||
const Login = () => {
|
const Login = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
console.log(i18n) // Add translation hook
|
console.log(i18n)
|
||||||
console.log(t)
|
console.log(t)
|
||||||
const [form, setForm] = useState({
|
const [form, setForm] = useState({
|
||||||
email: "",
|
email: "",
|
||||||
@@ -55,9 +55,7 @@ const Login = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Language switcher function
|
// Language switcher function
|
||||||
const changeLanguage = (lng: string) => {
|
|
||||||
i18n.changeLanguage(lng);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
|
|||||||
@@ -5,8 +5,13 @@ import { AuthContext } from "../context/auth";
|
|||||||
import { Box, Typography, TextField, Button, CircularProgress } from "@mui/material";
|
import { Box, Typography, TextField, Button, CircularProgress } from "@mui/material";
|
||||||
import { useGlobalInfoStore } from "../context/globalInfo";
|
import { useGlobalInfoStore } from "../context/globalInfo";
|
||||||
import { apiUrl } from "../apiConfig";
|
import { apiUrl } from "../apiConfig";
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import i18n from '../i18n';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const Register = () => {
|
const Register = () => {
|
||||||
|
const {t} = useTranslation();
|
||||||
const [form, setForm] = useState({
|
const [form, setForm] = useState({
|
||||||
email: "",
|
email: "",
|
||||||
password: "",
|
password: "",
|
||||||
@@ -40,11 +45,11 @@ const Register = () => {
|
|||||||
password,
|
password,
|
||||||
});
|
});
|
||||||
dispatch({ type: "LOGIN", payload: data });
|
dispatch({ type: "LOGIN", payload: data });
|
||||||
notify("success", "Registration Successful!");
|
notify("success", t('register.welcome_notification'));
|
||||||
window.localStorage.setItem("user", JSON.stringify(data));
|
window.localStorage.setItem("user", JSON.stringify(data));
|
||||||
navigate("/");
|
navigate("/");
|
||||||
} catch (error:any) {
|
} catch (error:any) {
|
||||||
notify("error", error.response.data || "Registration Failed. Please try again.");
|
notify("error", error.response.data || t('register.error_notification'));
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -82,7 +87,7 @@ const Register = () => {
|
|||||||
</Typography>
|
</Typography>
|
||||||
<TextField
|
<TextField
|
||||||
fullWidth
|
fullWidth
|
||||||
label="Email"
|
label={t('register.email')}
|
||||||
name="email"
|
name="email"
|
||||||
value={email}
|
value={email}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
@@ -92,7 +97,7 @@ const Register = () => {
|
|||||||
/>
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
fullWidth
|
fullWidth
|
||||||
label="Password"
|
label={t('register.password')}
|
||||||
name="password"
|
name="password"
|
||||||
type="password"
|
type="password"
|
||||||
value={password}
|
value={password}
|
||||||
@@ -115,13 +120,14 @@ const Register = () => {
|
|||||||
Loading
|
Loading
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
"Register"
|
t('register.button')
|
||||||
)}
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
<Typography variant="body2" align="center">
|
<Typography variant="body2" align="center">
|
||||||
Already have an account?{" "}
|
{t('register.register_prompt')}{" "}
|
||||||
<Link to="/login" style={{ textDecoration: "none", color: "#ff33cc" }}>
|
<Link to="/login" style={{ textDecoration: "none", color: "#ff33cc" }}>
|
||||||
Login
|
|
||||||
|
{t('register.login_link')}
|
||||||
</Link>
|
</Link>
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
Reference in New Issue
Block a user