Skip to content

Commit

Permalink
feat: setup base structure
Browse files Browse the repository at this point in the history
  • Loading branch information
DamonSalvatoreDeveloper committed Jul 21, 2024
1 parent c8205d9 commit f9acbfd
Show file tree
Hide file tree
Showing 36 changed files with 870 additions and 210 deletions.
25 changes: 14 additions & 11 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>

<head>
<meta charset="UTF-8" />
<!-- <link rel="icon" type="image/svg+xml" href="/vite.svg" /> -->
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Hiddify - Quick Setup</title>
</head>

<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>

</html>
99 changes: 59 additions & 40 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,53 +1,72 @@
import { ThemeProvider } from '@mui/material/styles';
import React, { lazy, Suspense, useEffect, useState } from 'react';
import { Experimental_CssVarsProvider as CssVarsProvider } from '@mui/material/styles';
import React, { lazy, Suspense } from 'react';
import { Route, BrowserRouter as Router, Routes } from 'react-router-dom';
import Loading from './components/Loading';
import Layout from './layout/Layout';
import darkTheme from './themes/dark.theme.config';
import lightTheme from './themes/light.theme.config';
import StepsLayout from './layout/StepsLayout';
import { ActiveStepProvider } from './providers/activeStepProvider';
import { InstallTypeProvider } from './providers/installTypeProvider';
import { urls } from './routes/urls';
import theme from './themes/theme.config';

// Lazy load the pages
const Step1 = lazy(() => import('./pages/Step1'));
const Step2 = lazy(() => import('./pages/Step2'));
const Step3 = lazy(() => import('./pages/Step3'));
const Step4 = lazy(() => import('./pages/Step4'));
const Step5 = lazy(() => import('./pages/Step5'));
const Step6 = lazy(() => import('./pages/Step6'));
const Home = lazy(() => import('./pages/home/Home'));

const App: React.FC = () => {
const [isDarkMode, setIsDarkMode] = useState(() => {
const savedTheme = localStorage.getItem('theme');
return savedTheme === 'dark';
});
const SharedStep1 = lazy(() => import('./pages/sharedSteps/Step1'));
const SharedStep2 = lazy(() => import('./pages/sharedSteps/Step2'));

const NewInstallStep3 = lazy(() => import('./pages/newInstallSteps/Step3'));
const NewInstallStep4 = lazy(() => import('./pages/newInstallSteps/Step4'));
const NewInstallStep5 = lazy(() => import('./pages/newInstallSteps/Step5'));
const NewInstallStep6 = lazy(() => import('./pages/newInstallSteps/Step6'));
const NewInstallStep7 = lazy(() => import('./pages/newInstallSteps/Step7'));

useEffect(() => {
localStorage.setItem('theme', isDarkMode ? 'dark' : 'light');
}, [isDarkMode]);
const MainServerStep3 = lazy(() => import('./pages/mainServerInstallSteps/Step3'));
const MainServerStep4 = lazy(() => import('./pages/mainServerInstallSteps/Step4'));
const MainServerStep5 = lazy(() => import('./pages/mainServerInstallSteps/Step5'));

const handleThemeToggle = () => {
setIsDarkMode(!isDarkMode);
};
const BackupStep3 = lazy(() => import('./pages/backupInstallSteps/Step3'));
const BackupStep4 = lazy(() => import('./pages/backupInstallSteps/Step4'));
const BackupStep5 = lazy(() => import('./pages/backupInstallSteps/Step5'));

const App: React.FC = () => {
return (
<ThemeProvider theme={isDarkMode ? darkTheme : lightTheme}>
<Router>
<Suspense fallback={<Loading />}>
<Routes>
<Route
path='/'
element={<Layout handleThemeToggle={handleThemeToggle} isDarkMode={isDarkMode} />}
>
<Route index element={<Step1 />} />
<Route path='step2' element={<Step2 />} />
<Route path='step3' element={<Step3 />} />
<Route path='step4' element={<Step4 />} />
<Route path='step5' element={<Step5 />} />
<Route path='step6' element={<Step6 />} />
</Route>
</Routes>
</Suspense>
</Router>
</ThemeProvider>
<InstallTypeProvider>
<ActiveStepProvider>
<CssVarsProvider theme={theme}>
<Router>
<Suspense fallback={<Loading />}>
<Routes>
<Route path='/' element={<Layout />}>
<Route index element={<Home />} />
<Route path='/' element={<StepsLayout />}>
<Route path={urls.sharedSteps.step1} element={<SharedStep1 />} />
<Route path={urls.sharedSteps.step2} element={<SharedStep2 />} />

{/* new install steps */}
<Route path={urls.newInstallSteps.step3} element={<NewInstallStep3 />} />
<Route path={urls.newInstallSteps.step4} element={<NewInstallStep4 />} />
<Route path={urls.newInstallSteps.step5} element={<NewInstallStep5 />} />
<Route path={urls.newInstallSteps.step6} element={<NewInstallStep6 />} />
<Route path={urls.newInstallSteps.step7} element={<NewInstallStep7 />} />

{/* backup install steps */}
<Route path={urls.backupInstallSteps.step3} element={<BackupStep3 />} />
<Route path={urls.backupInstallSteps.step4} element={<BackupStep4 />} />
<Route path={urls.backupInstallSteps.step5} element={<BackupStep5 />} />

{/* main server install steps */}
<Route path={urls.mainServerInstallSteps.step3} element={<MainServerStep3 />} />
<Route path={urls.mainServerInstallSteps.step4} element={<MainServerStep4 />} />
<Route path={urls.mainServerInstallSteps.step5} element={<MainServerStep5 />} />
</Route>
</Route>
</Routes>
</Suspense>
</Router>
</CssVarsProvider>
</ActiveStepProvider>
</InstallTypeProvider>
);
};

Expand Down
23 changes: 22 additions & 1 deletion src/components/Loading.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
import { Box } from '@mui/material';
import Typography from './Typography';

const Loading = () => {
return <div></div>;
return (
<Box
component='div'
sx={{
width: '100%',
height: '100vh',
overflow: 'hidden',
background: theme => theme.palette.bodyBg,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: theme => theme.palette.btnBg,
}}
>
<Typography size={30} weight={500}>
Loading...
</Typography>
</Box>
);
};

export default Loading;
29 changes: 29 additions & 0 deletions src/components/MainButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Button, ButtonProps, SxProps, Theme } from '@mui/material';
import { FC, ReactNode } from 'react';

interface IProps extends ButtonProps {
sx?: SxProps<Theme> | undefined;
children: ReactNode;
}

const MainButton: FC<IProps> = ({ sx, children, ...props }) => {
return (
<Button
variant='contained'
sx={{
border: 'none',
borderRadius: '100px',
padding: '15px 40px',
background: theme => theme.palette.btnBg,
position: 'relative',
color: theme => theme.palette.btnText,
...sx,
}}
{...props}
>
{children}
</Button>
);
};

export default MainButton;
119 changes: 70 additions & 49 deletions src/components/Stepper.tsx
Original file line number Diff line number Diff line change
@@ -1,58 +1,79 @@
import { Box, Button, Stepper as MuiStepper, Step, StepLabel, Typography } from '@mui/material';
import {
Box,
Stepper as MuiStepper,
Step,
stepClasses,
stepIconClasses,
StepLabel,
stepLabelClasses,
SxProps,
Theme,
useMediaQuery,
} from '@mui/material';
import React from 'react';
import { TStep } from '../providers/installTypeProvider';

const steps = ['Step 1', 'Step 2', 'Step 3'];

const Stepper: React.FC = () => {
const [activeStep, setActiveStep] = React.useState(0);

const handleNext = () => {
setActiveStep(prevActiveStep => prevActiveStep + 1);
};

const handleBack = () => {
setActiveStep(prevActiveStep => prevActiveStep - 1);
};
type TProps = {
sx?: SxProps<Theme> | undefined;
steps: TStep[];
activeStep: number;
};

const handleReset = () => {
setActiveStep(0);
};
const Stepper: React.FC<TProps> = ({ sx, steps, activeStep = 1 }) => {
const isMobile = useMediaQuery('(max-width:768px)');

return (
<Box sx={{ width: '100%' }}>
<MuiStepper activeStep={activeStep} orientation='vertical'>
{steps.map((label, index) => (
<Step key={label}>
<StepLabel>{label}</StepLabel>
<Box sx={{ mb: 2 }}>
<div>
<Typography>Step {index + 1} content goes here.</Typography>
<Box sx={{ mt: 2 }}>
<Button
variant='contained'
onClick={handleNext}
sx={{ mr: 1 }}
disabled={index === steps.length - 1}
>
{index === steps.length - 1 ? 'Finish' : 'Next'}
</Button>
<Button variant='contained' onClick={handleBack} disabled={index === 0}>
Back
</Button>
</Box>
</div>
</Box>
</Step>
))}
<Box sx={{ width: 'fit-content', ...sx }}>
<MuiStepper
activeStep={activeStep - 1}
orientation='vertical'
sx={{
[`& .${stepIconClasses.active}`]: {
fill: theme => theme.palette.white,
[`& .${stepIconClasses.text}`]: { fill: theme => theme.palette.royal },
},
}}
>
{steps.map((step, index) => {
let labelStyle: SxProps<Theme> | undefined = {};
if (activeStep - 1 === index) {
labelStyle = {
[`& .${stepLabelClasses.labelContainer}`]: {
display: 'block',
},
backgroundColor: theme => theme.palette.stepBg,
borderRadius: '100px',
padding: '15px',
paddingRight: '40px',
[`& .${stepLabelClasses.iconContainer}`]: { paddingRight: '20px' },
};
} else {
labelStyle = {
[`& .${stepLabelClasses.labelContainer}`]: {
display: 'none',
},
padding: '0',
[`& .${stepLabelClasses.iconContainer}`]: { padding: 0 },
};
}

const content = (
<Step
key={step.label}
sx={{
[`&.${stepClasses.root}`]: {
width: 'fit-content',
},
}}
>
<StepLabel sx={{ width: 'fit-content', ...labelStyle }}>
{activeStep - 1 === index && step.label}
</StepLabel>
</Step>
);
return content;
})}
</MuiStepper>
{activeStep === steps.length && (
<Box sx={{ mt: 2 }}>
<Typography>All steps completed</Typography>
<Button onClick={handleReset} variant='contained'>
Reset
</Button>
</Box>
)}
</Box>
);
};
Expand Down
35 changes: 35 additions & 0 deletions src/components/Typography.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Typography as MuiTypography, SxProps, Theme } from '@mui/material';
import { TypographyOwnProps, TypographyTypeMap } from '@mui/material/Typography';
import { FC, ReactNode } from 'react';

interface TProps extends TypographyOwnProps {
weight: 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900;
size: number;
variant?: TypographyTypeMap['props']['variant'];
sx?: SxProps<Theme> | undefined;
children: ReactNode;
}

const Typography: FC<TProps> = ({ sx, variant, children, size, weight, ...props }) => {
return (
<MuiTypography
variant={variant}
sx={{
fontSize: {
xs: size / 2 + 'px',
sm: size / 1.8 + 'px',
md: size / 1.6 + 'px',
lg: size / 1.4 + 'px',
xl: size,
},
fontWeight: weight,
...sx,
}}
{...props}
>
{children}
</MuiTypography>
);
};

export default Typography;
4 changes: 3 additions & 1 deletion src/index.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
* {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
}
padding: 0;
margin: 0;
}
Loading

0 comments on commit f9acbfd

Please sign in to comment.