do some work

This commit is contained in:
DIVISIONSolar 2024-09-23 18:45:35 -04:00
parent ab2492a6a4
commit cbb250abc0
Signed by: JoshS
GPG key ID: A37D037686151E97
14 changed files with 380 additions and 60 deletions

82
package-lock.json generated
View file

@ -11,10 +11,16 @@
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.7.7",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-scripts": "5.0.1",
"react-router": "^6.26.2",
"react-router-dom": "^6.26.2",
"react-scripts": "^5.0.1",
"web-vitals": "^2.1.4"
},
"devDependencies": {
"tailwindcss": "^3.4.13"
}
},
"node_modules/@adobe/css-tools": {
@ -3540,6 +3546,14 @@
}
}
},
"node_modules/@remix-run/router": {
"version": "1.19.2",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.2.tgz",
"integrity": "sha512-baiMx18+IMuD1yyvOGaHM9QrVUPGGG0jC+z+IPHnRJWUAUvaKuWKyE8gjDj2rzv3sz9zOGoRSPgeBVHRhZnBlA==",
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/@rollup/plugin-babel": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
@ -5811,6 +5825,29 @@
"node": ">=4"
}
},
"node_modules/axios": {
"version": "1.7.7",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz",
"integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/axios/node_modules/form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/axobject-query": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
@ -15829,6 +15866,11 @@
"node": ">= 0.10"
}
},
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"node_modules/psl": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
@ -16215,11 +16257,40 @@
"node": ">=0.10.0"
}
},
"node_modules/react-router": {
"version": "6.26.2",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.26.2.tgz",
"integrity": "sha512-tvN1iuT03kHgOFnLPfLJ8V95eijteveqdOSk+srqfePtQvqCExB8eHOYnlilbOcyJyKnYkr1vJvf7YqotAJu1A==",
"dependencies": {
"@remix-run/router": "1.19.2"
},
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
"react": ">=16.8"
}
},
"node_modules/react-router-dom": {
"version": "6.26.2",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.26.2.tgz",
"integrity": "sha512-z7YkaEW0Dy35T3/QKPYB1LjMK2R1fxnHO8kWpUMTBdfVzZrWOiY9a7CtN8HqdWtDUWd5FY6Dl8HFsqVwH4uOtQ==",
"dependencies": {
"@remix-run/router": "1.19.2",
"react-router": "6.26.2"
},
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
"react": ">=16.8",
"react-dom": ">=16.8"
}
},
"node_modules/react-scripts": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
"integrity": "sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ==",
"license": "MIT",
"dependencies": {
"@babel/core": "^7.16.0",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.3",
@ -18020,10 +18091,9 @@
"license": "MIT"
},
"node_modules/tailwindcss": {
"version": "3.4.12",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.12.tgz",
"integrity": "sha512-Htf/gHj2+soPb9UayUNci/Ja3d8pTmu9ONTfh4QY8r3MATTZOzmv6UYWF7ZwikEIC8okpfqmGqrmDehua8mF8w==",
"license": "MIT",
"version": "3.4.13",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.13.tgz",
"integrity": "sha512-KqjHOJKogOUt5Bs752ykCeiwvi0fKVkr5oqsFNt/8px/tA8scFPIlkygsf6jXrfCqGHz7VflA6+yytWuM+XhFw==",
"dependencies": {
"@alloc/quick-lru": "^5.2.0",
"arg": "^5.0.2",

View file

@ -6,9 +6,12 @@
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.7.7",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-scripts": "5.0.1",
"react-router": "^6.26.2",
"react-router-dom": "^6.26.2",
"react-scripts": "^5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
@ -34,5 +37,8 @@
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"tailwindcss": "^3.4.13"
}
}

View file

@ -1,43 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MCDonalds</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
<div id="app"></div>
</body>
</html>

View file

@ -1,21 +1,11 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"short_name": "",
"name": "",
"icons": [
{
"src": "favicon.ico",
"src": "",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",

5
src/Assets/CSS/Navbar.min.css vendored Normal file
View file

@ -0,0 +1,5 @@
@import url(https://fonts.bunny.net/css?family=abril-fatface:400|rubik:600,800i,900i);
body {
background-color: #101725;
}

3
src/Assets/CSS/input.css Normal file
View file

@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

14
src/Components/Layout.jsx Normal file
View file

@ -0,0 +1,14 @@
import React from "react";
import { Outlet } from "react-router-dom";
import Navbar from "./Navbar";
const Layout = () => {
return (
<>
<Navbar />
<Outlet />
</>
);
};
export default Layout;

66
src/Components/Navbar.jsx Normal file
View file

@ -0,0 +1,66 @@
import React, { useState, useEffect, useRef } from "react";
import { Link } from "react-router-dom";
import "../Assets/CSS/Navbar.min.css";
function Navbar() {
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
const dropdownRef = useRef(null);
const handleDropdownToggle = (event) => {
event.stopPropagation();
setIsDropdownOpen(!isDropdownOpen);
};
const handleOptionClick = () => {
setIsDropdownOpen(false);
};
const handleClickOutsideDropdown = (event) => {
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
setIsDropdownOpen(false);
}
};
useEffect(() => {
window.addEventListener("click", handleClickOutsideDropdown);
return () => {
window.removeEventListener("click", handleClickOutsideDropdown);
};
}, []);
return (
<nav className="bg-nav-black p-[17px] text-center font-bold text-white font-abril-fatface font-rubik">
<Link className="text-lg p-[6px]" to="/">
Home
</Link>
<div className="relative inline-block text-left">
<button
className="text-lg p-[6px] focus:outline-none"
onClick={handleDropdownToggle}
>
Pages
</button>
{isDropdownOpen && (
<div
ref={dropdownRef}
className="absolute left-0 mt-2 w-40 bg-white shadow-lg rounded-md z-10"
>
<Link
to="/Info/Schedule"
className="block px-4 py-2 text-gray-800 hover:bg-gray-200"
onClick={handleOptionClick}
>
Schedule
</Link>
</div>
)}
<Link className="text-lg p-[6px]" to="/Login">
Login
</Link>
</div>
</nav>
);
}
export default Navbar;

View file

@ -0,0 +1,11 @@
import React from "react";
const Preloader = () => {
return (
<div className="flex justify-center items-center h-screen">
<div className="border-t-4 border-blue-500 rounded-full animate-spin h-12 w-12"></div>
</div>
);
};
export default Preloader;

12
src/Pages/Home.jsx Normal file
View file

@ -0,0 +1,12 @@
import React from "react";
import "../Assets/CSS/input.css";
function Home() {
return (
<div>
<h1>Hi</h1>
</div>
);
}
export default Home;

62
src/Pages/Login.jsx Normal file
View file

@ -0,0 +1,62 @@
import React, { useState } from 'react';
const Login = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleLogin = (e) => {
e.preventDefault();
// Login logic here
console.log('Email:', email);
console.log('Password:', password);
};
return (
<div className="flex items-center justify-center h-screen bg-nav-black">
<div className="w-full max-w-md p-8 space-y-8 shadow-lg rounded-xl">
<h2 className="text-2xl font-bold text-center text-white">McDonald's Work Schedule</h2>
<form className="mt-8 space-y-6" onSubmit={handleLogin}>
<div className="rounded-md shadow-sm space-y-4">
<div>
<label htmlFor="email" className="sr-only">Email address</label>
<input
id="email"
name="email"
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-highlightRed focus:border-highlightRed"
placeholder="Email address"
/>
</div>
<div>
<label htmlFor="password" className="sr-only">Password</label>
<input
id="password"
name="password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-highlightRed focus:border-highlightRed"
placeholder="Password"
/>
</div>
</div>
<div>
<button
type="submit"
className="w-full px-4 py-2 text-white bg-highlightRed rounded-md hover:bg-red-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-highlightRed"
>
Log In
</button>
</div>
</form>
</div>
</div>
);
};
export default Login;

View file

@ -0,0 +1,68 @@
import React, { useEffect, useState } from 'react';
import axios from 'axios';
const WorkSchedule = () => {
const [schedule, setSchedule] = useState([]);
const [error, setError] = useState(false); // State to track if there's an error
useEffect(() => {
const fetchSchedule = async () => {
try {
const response = await axios.get('http://localhost:5000/api/schedules');
setSchedule(response.data);
setError(false); // Reset error state if the fetch succeeds
} catch (error) {
console.error('Error fetching the schedule data:', error);
setError(true); // Set error to true if the fetch fails
}
};
fetchSchedule();
}, []);
return (
<div className="flex items-center justify-center min-h-screen bg-nav-black">
<div className="w-full max-w-6xl p-8 bg-darkGray shadow-lg rounded-2xl">
<h2 className="text-3xl font-bold text-center text-highlightRed mb-6">Employee Work Schedule</h2>
<table className="min-w-full table-auto text-left border-collapse">
<thead>
<tr className="bg-gray-800 text-gray-100">
<th className="px-6 py-4 border-b-2 border-gray-300">First Name</th>
<th className="px-6 py-4 border-b-2 border-gray-300">Last Name</th>
<th className="px-6 py-4 border-b-2 border-gray-300">Email</th>
<th className="px-6 py-4 border-b-2 border-gray-300">Phone</th>
<th className="px-6 py-4 border-b-2 border-gray-300">Hours Today</th>
<th className="px-6 py-4 border-b-2 border-gray-300">Hours This Week</th>
<th className="px-6 py-4 border-b-2 border-gray-300">Hourly Rate</th>
<th className="px-6 py-4 border-b-2 border-gray-300">Estimated Weekly Earnings</th>
</tr>
</thead>
<tbody>
{error ? (
// Display this row if fetching data fails
<tr>
<td colSpan="8" className="text-center px-6 py-4 text-red-600">Failed to fetch data.</td>
</tr>
) : (
// Display table rows if data fetching is successful
schedule.map((person, index) => (
<tr key={person.id} className={`hover:bg-gray-100 ${index % 2 === 0 ? 'bg-gray-50' : 'bg-white'}`}>
<td className="px-6 py-4 border-b">{person.first_name}</td>
<td className="px-6 py-4 border-b">{person.last_name}</td>
<td className="px-6 py-4 border-b">{person.email}</td>
<td className="px-6 py-4 border-b">{person.phone}</td>
<td className="px-6 py-4 border-b">{person.hours_worked_today}</td>
<td className="px-6 py-4 border-b">{person.hours_worked_week}</td>
<td className="px-6 py-4 border-b">${person.hourly_rate.toFixed(2)}</td>
<td className="px-6 py-4 border-b">${person.estimated_weekly_earnings.toFixed(2)}</td>
</tr>
))
)}
</tbody>
</table>
</div>
</div>
);
};
export default WorkSchedule;

24
src/index.js Normal file
View file

@ -0,0 +1,24 @@
import { BrowserRouter, Routes, Route } from "react-router-dom";
import { createRoot } from "react-dom/client";
import Layout from "./Components/Layout";
import Home from "./Pages/Home";
import Login from "./Pages/Login";
import Schedule from "./Pages/Scheduleinfo";
export default function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="/Login" element={<Login />} />
<Route path="/Info/Schedule" element={<Schedule />} />
</Route>
</Routes>
</BrowserRouter>
);
}
const container = document.getElementById("app");
const root = createRoot(container); // createRoot(container!) if you use TypeScript
root.render(<App tab="home" />);

20
tailwind.config.js Normal file
View file

@ -0,0 +1,20 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./src/**/*.{js,jsx,ts,tsx}', './public/index.html'],
theme: {
extend: {
colors: {
'nav-black': '#0b0f19',
'background-black': '#101725',
'darkGray': '#1A1A1A',
'lightGray': '#B0B0B0',
'highlightRed': '#FF3D5A',
},
fontFamily: {
'abril-fatface': ['Abril Fatface', 'display'], // Imported from https://fonts.bunny.net/css?family=abril-fatface:400|rubik:600,800i,900i
'rubik': ['Rubik', 'sans-serif'], // Imported from https://fonts.bunny.net/css?family=abril-fatface:400|rubik:600,800i,900i
}
},
},
plugins: [],
}