Skip to content

Commit

Permalink
Merge pull request #111 from ASM-Studios/mra/feat-dashboard
Browse files Browse the repository at this point in the history
Mra/feat dashboard
  • Loading branch information
Mael-RABOT authored Dec 3, 2024
2 parents 5e41e43 + 462f891 commit 4963872
Show file tree
Hide file tree
Showing 28 changed files with 1,802 additions and 196 deletions.
579 changes: 578 additions & 1 deletion client_web/package-lock.json

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion client_web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,20 @@
"dependencies": {
"@azure/msal-browser": "^3.27.0",
"@react-oauth/google": "^0.12.1",
"@tsparticles/engine": "^3.7.1",
"@tsparticles/react": "^3.0.0",
"@tsparticles/slim": "^3.7.1",
"@types/js-cookie": "^3.0.6",
"antd": "^5.22.1",
"axios": "^1.7.7",
"dotenv": "^16.4.5",
"framer-motion": "^11.11.17",
"js-cookie": "^3.0.5",
"react": "^18.3.1",
"react-color": "^2.19.3",
"react-dom": "^18.3.1",
"react-router-dom": "^6.28.0"
"react-router-dom": "^6.28.0",
"react-toastify": "^10.0.6"
},
"devDependencies": {
"@eslint/js": "^9.13.0",
Expand Down
Binary file added client_web/public/google-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
170 changes: 151 additions & 19 deletions client_web/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import { ContextManager } from "./Context/ContextManager";
import { uri } from './Config/uri';
// @ts-ignore
import { uri } from '@Config/uri';

import { useEffect, useMemo, useState } from "react";
import Particles, { initParticlesEngine } from "@tsparticles/react";
import {
type Container,
type ISourceOptions,
MoveDirection,
OutMode,
} from "@tsparticles/engine";
import { loadSlim } from "@tsparticles/slim";

import Home from './Pages/Home';
import NotFound from './Pages/NotFound';
import Layout from './components/Layout/Layout';
// @ts-ignore
import Layout from '@/Components/Layout/Layout';
import Login from './Pages/Auth/Forms/Login';
import Register from './Pages/Auth/Forms/Register';

Expand All @@ -13,27 +25,147 @@ import SpotifyCallback from './Pages/Auth/Callback/SpotifyCallback';
import MicrosoftCallback from './Pages/Auth/Callback/MicrosoftCallback';
import DiscordCallback from './Pages/Auth/Callback/DiscordCallback';

import CreateWorkflow from "./Pages/Workflows/CreateWorkflow";
import WorkflowsTable from "./Pages/Workflows/WorkflowsTable";

import Dashboard from './Pages/Dashboard/Dashboard';

import { ToastContainer } from 'react-toastify';
// @ts-ignore
import 'react-toastify/dist/ReactToastify.css';

const App = () => {
const [init, setInit] = useState(false);
const [backgroundColor, setBackgroundColor] = useState("#FFA500");

useEffect(() => {
initParticlesEngine(async (engine) => {
await loadSlim(engine);
}).then(() => {
setInit(true);
});
setBackgroundColor(sessionStorage.getItem("backgroundColor") || "#FFA500");
}, []);

const particlesLoaded = async (container?: Container): Promise<void> => {
console.log(container);
};

const options: ISourceOptions = useMemo(
() => ({
background: {
color: {
value: backgroundColor,
},
},
fpsLimit: 60,
interactivity: {
events: {
onClick: {
enable: true,
mode: "push",
},
onHover: {
enable: true,
mode: "repulse",
},
},
modes: {
push: {
quantity: 1,
},
repulse: {
distance: 200,
duration: 0.4,
},
},
},
particles: {
color: {
value: "#ffffff",
},
links: {
color: "#ffffff",
distance: 150,
enable: true,
opacity: 0.5,
width: 1,
},
move: {
direction: MoveDirection.none,
enable: true,
outModes: {
default: OutMode.out,
},
random: false,
speed: 6,
straight: false,
},
number: {
density: {
enable: true,
},
value: 80,
},
opacity: {
value: 0.5,
},
shape: {
type: "circle",
},
size: {
value: { min: 1, max: 5 },
},
},
detectRetina: true,
}),
[backgroundColor],
);

return (
<ContextManager>
<Router>
<Layout>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/login" element={<Login />} />
<Route path="/register" element={<Register />} />
<Route path="/dashboard" element={<Dashboard />} />
<Route path={uri.spotify.auth.redirectUri.replace(window.location.origin, "")} element={<SpotifyCallback />} />
<Route path={uri.microsoft.auth.redirectUri.replace(window.location.origin, "")} element={<MicrosoftCallback />} />
<Route path={uri.linkedin.auth.redirectUri.replace(window.location.origin, "")} element={<LinkedinCallback />} />
<Route path={uri.discord.auth.redirectUri.replace(window.location.origin, "")} element={<DiscordCallback />} />
<Route path="*" element={<NotFound />} />
</Routes>
</Layout>
</Router>
</ContextManager>
<>
<ToastContainer
position="top-right"
autoClose={5000}
hideProgressBar={false}
newestOnTop
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
theme="light"
/>
{init && (
<Particles
id="tsparticles"
particlesLoaded={particlesLoaded}
options={options}
/>
)}
<ContextManager>
<Router>
<Layout>
<Routes>
<Route path="/" element={<Home backgroundColor={backgroundColor} setBackgroundColor={setBackgroundColor} />} />
<Route path="/login" element={<Login />} />
<Route path="/register" element={<Register />} />
<Route path="/dashboard" element={<Dashboard />} />

<Route path={uri.spotify.auth.redirectUri.replace(window.location.origin, "")} element={<SpotifyCallback />} />
<Route path={uri.microsoft.auth.redirectUri.replace(window.location.origin, "")} element={<MicrosoftCallback />} />
<Route path={uri.linkedin.auth.redirectUri.replace(window.location.origin, "")} element={<LinkedinCallback />} />
<Route path={uri.discord.auth.redirectUri.replace(window.location.origin, "")} element={<DiscordCallback />} />

<Route path="/workflow/create" element={<CreateWorkflow />} />
<Route path="/workflows" element={<WorkflowsTable />} />
<Route path="/workflow/:id" element={<NotFound />} />
<Route path="*" element={<NotFound />} />
</Routes>
</Layout>
</Router>
</ContextManager>
</>
);
};

Expand Down
54 changes: 54 additions & 0 deletions client_web/src/Components/Auth/Buttons/GoogleAuth.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Form, Button } from 'antd';
import { GoogleOAuthProvider } from '@react-oauth/google';
// @ts-ignore
import { uri } from '@Config/uri';

interface GoogleAuthProps {
onSuccess: (response: unknown) => void;
onError: () => void;
buttonText: string;
}

const GoogleAuth = ({ onSuccess, onError, buttonText }: GoogleAuthProps) => {
if (!uri.google.auth.clientId || uri.google.auth.clientId === '') {
return null;
}

const handleGoogleLogin = () => {
// Initialize the Google Sign-In client
let google: any;
const client = google.accounts.oauth2.initCodeClient({
client_id: uri.google.auth.clientId,
scope: 'email profile', // TODO: Add other scopes as needed
callback: (response: unknown) => {
// @ts-ignore
if (response?.code) {
onSuccess(response);
} else {
onError();
}
},
});
client.requestCode();
};

return (
<GoogleOAuthProvider clientId={uri.google.auth.clientId}>
<Form.Item style={{ textAlign: 'center' }}>
<Button
onClick={handleGoogleLogin}
className="w-full flex items-center justify-center gap-2 bg-white text-gray-700 py-2 px-4 rounded-md hover:bg-gray-100 transition-colors border border-gray-300"
>
<img
src="/google-icon.png"
alt="Google Logo"
style={{ width: '24px', height: '24px' }}
/>
{buttonText}
</Button>
</Form.Item>
</GoogleOAuthProvider>
);
};

export default GoogleAuth;
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const OAuthButtons = ({
<GoogleAuth
onSuccess={onGoogleSuccess}
onError={onGoogleError}
buttonText={`${mode}_with`}
buttonText={`Sign ${mode === 'signin' ? 'in' : 'up'} with Google`}
/>

<MicrosoftAuth
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
33 changes: 33 additions & 0 deletions client_web/src/Components/LinkButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from "react";
import { Button } from 'antd';
import { useNavigate } from 'react-router-dom';

interface LinkButtonProps {
text: string;
url?: string;
style?: React.CSSProperties;
type?: "primary" | "default" | "dashed" | "link" | "text" | "danger" | undefined;
goBack?: boolean;
}

const LinkButton: React.FC<LinkButtonProps> = ({ text, url, type = "primary", style = {}, goBack = false }) => {
const navigate = useNavigate();

const handleClick = () => {
if (goBack) {
navigate(-1);
} else if (url) {
navigate(url);
}
};

const buttonStyle = type === "danger" ? { ...style, backgroundColor: 'red', borderColor: 'red', color: 'white' } : style;

return (
<Button type={type === "danger" ? "default" : type} style={buttonStyle} onClick={handleClick}>
{text}
</Button>
);
};

export default LinkButton;
File renamed without changes.
7 changes: 2 additions & 5 deletions client_web/src/Pages/Auth/Forms/Login.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Form, Input, Button, Card } from 'antd';
import { Link } from 'react-router-dom';
import OAuthButtons from '../../../components/auth/OAuthButtons';
import OAuthButtons from '../../../Components/Auth/OAuthButtons';

const Login = () => {
const onFinish = (values: { email: string, password: string }) => {
Expand Down Expand Up @@ -41,9 +41,6 @@ const Login = () => {

return (
<div style={{
backgroundImage: 'url("/background.png")',
backgroundSize: 'cover',
backgroundPosition: 'center',
minHeight: '100vh',
display: 'flex',
alignItems: 'center',
Expand All @@ -52,7 +49,7 @@ const Login = () => {
width: '100%',
top: 0,
left: 0
}}>
}} role="main">
<Card title="Login" style={{ width: 400 }}>
<Form
name="login"
Expand Down
8 changes: 3 additions & 5 deletions client_web/src/Pages/Auth/Forms/Register.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Form, Input, Button, Card } from 'antd';
import { Link } from 'react-router-dom';
import OAuthButtons from '../../../components/auth/OAuthButtons';
// @ts-ignore
import OAuthButtons from '@/Components/Auth/OAuthButtons';

const Register = () => {
const onFinish = (values: unknown) => {
Expand Down Expand Up @@ -41,9 +42,6 @@ const Register = () => {

return (
<div style={{
backgroundImage: 'url("/background.png")',
backgroundSize: 'cover',
backgroundPosition: 'center',
minHeight: '100vh',
display: 'flex',
alignItems: 'center',
Expand All @@ -52,7 +50,7 @@ const Register = () => {
width: '100%',
top: 0,
left: 0
}}>
}} role="main">
<Card title="Register" style={{ width: 400 }}>
<Form
name="register"
Expand Down
Loading

0 comments on commit 4963872

Please sign in to comment.