Skip to content

Commit

Permalink
feat: update ui
Browse files Browse the repository at this point in the history
  • Loading branch information
walidelnozahy committed Sep 10, 2024
1 parent 4b64266 commit 9c15ec1
Show file tree
Hide file tree
Showing 11 changed files with 425 additions and 246 deletions.
14 changes: 8 additions & 6 deletions website/app/eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import js from '@eslint/js'
import globals from 'globals'
import react from 'eslint-plugin-react'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import js from '@eslint/js';
import globals from 'globals';
import react from 'eslint-plugin-react';
import reactHooks from 'eslint-plugin-react-hooks';
import reactRefresh from 'eslint-plugin-react-refresh';

export default [
{ ignores: ['dist'] },
Expand All @@ -28,11 +28,13 @@ export default [
...react.configs.recommended.rules,
...react.configs['jsx-runtime'].rules,
...reactHooks.configs.recommended.rules,
'react/prop-types': 'off',
'no-unused-vars': 'off',
'react/jsx-no-target-blank': 'off',
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
},
]
];
29 changes: 16 additions & 13 deletions website/app/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
import { BrowserRouter, Navigate, Route, Routes } from "react-router-dom";
import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom';

import ChatPage from "./chat/ChatPage";
import LoginPage from "./auth/LoginPage";
import RegistrationPage from "./auth/RegistrationPage";
import Layout from "./app/Layout";
import { AuthProvider } from "./auth/AuthProvider";
import { ProtectedRoute } from "./auth/ProtectedRoute";
import ChatPage from './chat/ChatPage';
import LoginPage from './auth/LoginPage';
import RegistrationPage from './auth/RegistrationPage';
import Layout from './app/Layout';
import { AuthProvider } from './auth/AuthProvider';
import { ProtectedRoute } from './auth/ProtectedRoute';
import AuthLayout from './app/AuthLayout';

const AppRoutes = () => {
return (
<Routes>
<Route path="" element={<Layout />}>
<Route path="/login" element={<LoginPage />} />
<Route path="/register" element={<RegistrationPage />} />
<Route element={<ProtectedRoute loginPath="/login" />}>
<Route path="" element={<Navigate to="/chat" />} />
<Route path="/chat" element={<ChatPage />} />
<Route element={<AuthLayout />}>
<Route path='/login' element={<LoginPage />} />
<Route path='/register' element={<RegistrationPage />} />
</Route>
<Route path='' element={<Layout />}>
<Route element={<ProtectedRoute loginPath='/login' />}>
<Route path='' element={<Navigate to='/chat' />} />
<Route path='/chat' element={<ChatPage />} />
</Route>
</Route>
</Routes>
Expand Down
45 changes: 45 additions & 0 deletions website/app/src/app/AuthLayout.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Outlet, Link, useLocation } from 'react-router-dom';
import { Logo } from '../components/Logo';

const AuthLayout = () => {
const location = useLocation();
const isLoginPage = location.pathname === '/login';

return (
<div className='min-h-screen flex flex-col justify-center items-center space-y-6'>
<Logo />
<div className='w-full max-w-md px-8 py-10 bg-white rounded-lg border flex flex-col space-y-6 items-center animate-fadeIn'>
<div className='w-full max-w-sm mx-auto'>
<Outlet />
</div>
<div className='text-center'>
{isLoginPage ? (
<div>
<span className='text-gray-500'>Don&apos;t have an account?</span>{' '}
<Link to='/register' className=' font-bold'>
Register here.
</Link>
</div>
) : (
<div>
<span className='text-gray-500'>Already have an account?</span>{' '}
<Link to='/login' className=' font-bold'>
Login here.
</Link>
</div>
)}
</div>
</div>
<div className='animate-fadeIn flex flex-col items-center gap-2 text-center '>
<span className='text-xs text-gray-800'>Powered By</span>
<img
src='https://s3.us-east-2.amazonaws.com/assets.public.serverless/general/framework-text-lighting-icon-center-black.svg'
alt='Serverless Framework'
className='h-8 p-0 m-0'
/>
</div>
</div>
);
};

export default AuthLayout;
63 changes: 43 additions & 20 deletions website/app/src/app/Layout.jsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,57 @@
import { Outlet, useNavigate } from "react-router-dom";
import { useAuth } from "../auth/AuthProvider";
import { Outlet, useNavigate } from 'react-router-dom';
import { useAuth } from '../auth/AuthProvider';

const Layout = () => {
const navigate = useNavigate();
const { logout, isLoggedIn } = useAuth();

const handleLogout = () => {
logout();
navigate("/login");
navigate('/login');
};

return (
<div className="bg-gray-100 min-h-screen pt-20">
<div className="flex flex-row justify-between fixed top-0 left-0 w-full p-2 bg-white shadow-md">
<img
src="https://assets.serverless-extras.com/general/logo-aws-ai-stack-black.png"
alt="AWS AI Stack"
className="h-10 p-0 m-0"
/>
<div className="m-2">
{isLoggedIn() && (
<div className="cursor-pointer" onClick={handleLogout}>
Logout
</div>
)}
<div className='min-h-screen flex flex-col'>
{isLoggedIn() && (
<div className='flex bg-white items-center sticky top-0 left-0 w-full p-4 z-10 shadow-md gap-2'>
<img
src='https://assets.serverless-extras.com/general/logo-aws-ai-stack-black.png'
alt='AWS AI Stack'
className='h-10'
/>
<div className='flex items-center gap-2 text-center ml-auto mr-0 justify-center'>
<span className='text-xs text-gray-800 mt-1.5'>By</span>
<img
src='https://s3.us-east-2.amazonaws.com/assets.public.serverless/general/framework-text-lighting-icon-center-black.svg'
alt='Serverless Framework'
className='h-8'
/>
</div>
<button
onClick={handleLogout}
className='text-gray-400 bg-transparent px-2 py-2 rounded-md hover:bg-primary hover:text-white focus:outline-none focus:ring-2 focus:ring-primary transition-colors'
>
<svg
xmlns='http://www.w3.org/2000/svg'
width='18'
height='18'
viewBox='0 0 24 24'
fill='none'
stroke='currentColor'
strokeWidth='2'
strokeLinecap='round'
strokeLinejoin='round'
className='lucide lucide-log-out'
>
<path d='M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4' />
<polyline points='16 17 21 12 16 7' />
<line x1='21' x2='9' y1='12' y2='12' />
</svg>
</button>
</div>
</div>
<div>
<Outlet />
</div>
)}

<Outlet />
</div>
);
};
Expand Down
22 changes: 11 additions & 11 deletions website/app/src/auth/AuthProvider.jsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,49 @@
import { createContext, useContext } from "react";
import { createContext, useContext } from 'react';

const authApiUrl = import.meta.env.VITE_AUTH_API_URL;
const AuthContext = createContext();

export const AuthProvider = ({ children }) => {
const getToken = () => localStorage.getItem("token");
const getToken = () => localStorage.getItem('token');

const login = async ({ email, password }) => {
const response = await fetch(`${authApiUrl}/login`, {
method: "POST",
method: 'POST',
headers: {
"Content-Type": "application/json",
'Content-Type': 'application/json',
},
body: JSON.stringify({ email, password }),
});
const data = await response.json();
if (data.token) {
localStorage.setItem("token", data.token);
localStorage.setItem('token', data.token);
} else if (data.error) {
throw new Error(data.error);
} else {
throw new Error("Unknown error");
throw new Error('Unknown error');
}
};

const register = async ({ email, password }) => {
const response = await fetch(`${authApiUrl}/register`, {
method: "POST",
method: 'POST',
headers: {
"Content-Type": "application/json",
'Content-Type': 'application/json',
},
body: JSON.stringify({ email, password }),
});
const data = await response.json();
if (data.token) {
localStorage.setItem("token", data.token);
localStorage.setItem('token', data.token);
} else if (data.error) {
throw new Error(data.error);
} else {
throw new Error("Unknown error");
throw new Error('Unknown error');
}
};

const logout = () => {
localStorage.removeItem("token");
localStorage.removeItem('token');
};

const isLoggedIn = () => {
Expand Down
Loading

0 comments on commit 9c15ec1

Please sign in to comment.