add a sample AuthorizationServer to the repo and put traffic-police app in a separate folder

This commit is contained in:
Muhammad Azeez
2021-01-16 21:20:05 +03:00
parent 91810950db
commit 85cd111f5f
201 changed files with 10992 additions and 16 deletions

View File

@@ -0,0 +1,15 @@
import React from "react";
import VehicleRegisterForm from "./components/VehicleRegisterForm";
import Navbar from "./components/Navbar";
import Main from "./components/Main";
const RegisterVehicle = () => {
return (
<div>
<Navbar />
<Main Component={VehicleRegisterForm} />
</div>
);
};
export default RegisterVehicle;

View File

@@ -0,0 +1,15 @@
import React from "react";
import Navbar from "./components/Navbar";
import Main from "./components/Main";
import VehiclesMain from "./components/VehiclesMain";
const YourVehicles = () => {
return (
<div>
<Navbar />
<Main Component={VehiclesMain} />
</div>
);
};
export default YourVehicles;

View File

@@ -0,0 +1,12 @@
import React from "react";
const Button = ({ onClickEvent, text, classes = "" }) => (
<button
onClick={onClickEvent}
className={`bg-blue-custom border-0 font-inter font-semibold rounded text-xl m-0 ${classes}`}
>
{text}
</button>
);
export default Button;

View File

@@ -0,0 +1,14 @@
import React from "react";
const Card = ({ children, classes = "", styles = {} }) => {
return (
<div
style={{ ...styles }}
className={`xl:w-1/3 lg:w-5/12 md:w-2/4 sm:w-9/12 w-11/12 flex flex-col justify-center shadow md:px-32 sm:px-28 md:py-36 sm:py-36 px-20 py-16 my-20 ${classes}`}
>
{children}
</div>
);
};
export default Card;

View File

@@ -0,0 +1,12 @@
import React from "react";
const Heading1 = ({ text, classes = "", styles = {} }) => (
<h1
className={`font-playfair text-black-custom text-6xl mb-12 ${classes}`}
style={{ ...styles }}
>
{text}
</h1>
);
export default Heading1;

View File

@@ -0,0 +1,14 @@
import React from "react";
const Heading3 = ({ children, styles = {} }) => {
return (
<h3
style={{ ...styles }}
className="font-light font-inter text-black-custom my-20 self-start"
>
{children}
</h3>
);
};
export default Heading3;

View File

@@ -0,0 +1,27 @@
import React from "react";
import Button from "./Button";
import { storeUser } from "../../actions/authActions";
import store from "../../store";
import Heading1 from "./Heading1";
import Card from "./Card";
const LoginWindow = () => {
const onUserLogin = () => {
const user = { profile: { given_name: "John Doe" } };
console.log(`User logged in!`);
store.dispatch(storeUser(user));
};
return (
<Card>
<Heading1 text={"Traffic Police Service"} />
<p className="text-black-custom font-light text-3xl mb-20">
Login to your account to view your dashboard and register a new vehicle.
</p>
<Button onClickEvent={onUserLogin} text={"Login"} />
</Card>
);
};
export default LoginWindow;

View File

@@ -0,0 +1,14 @@
import React from "react";
const Main = ({ Component, styles = {} }) => {
return (
<div
className="flex flex-col items-center justify-center h-4/5"
style={{ ...styles, marginTop: "80px" }}
>
<Component />
</div>
);
};
export default Main;

View File

@@ -0,0 +1,84 @@
import React, { useState } from "react";
import logo from "../../images/logo.svg";
import { Link } from "react-router-dom";
import { useSelector } from "react-redux";
import { IoMdMenu } from "react-icons/io";
import { useMediaQuery } from "react-responsive";
// Services
import { signoutRedirect } from "../../services/userService";
const Navbar = () => {
const [isMenuOpen, setIsMenuOpen] = useState(false);
const isMobile = useMediaQuery({ query: "(max-width: 950px)" });
const user = useSelector((state) => state.auth.user);
function signOut() {
signoutRedirect();
}
return (
<div
className="w-screen bg-blue-custom flex justify-center items-center fixed top-0 left-0"
style={{ height: "80px" }}
>
<nav className="flex items-center justify-between xl:w-4/5 w-10/12">
<Link to="/">
<img src={logo} alt="logo" className="h-24" />
</Link>
{user ? (
<>
<IoMdMenu
onClick={() =>
isMenuOpen ? setIsMenuOpen(false) : setIsMenuOpen(true)
}
className={`text-5xl text-white hidden hamburger-menu cursor-pointer ${
isMenuOpen ? "text-blue-custom" : ""
}`}
/>
<ul
className="list-none flex items-center justify-between m-0 navbar-list"
style={
isMobile
? isMenuOpen
? { display: "flex" }
: { display: "none" }
: { display: "flex" }
}
>
<li className="m-0">
<Link
to="/"
className="text-white font-inter font-semibold hover:text-white focus:text-white tracking-normal mr-20"
style={{ fontSize: "1.335rem" }}
>
Your Vehicles
</Link>
</li>
<li className="m-0">
<Link
to="/register"
className="text-white font-inter font-semibold hover:text-white focus:text-white tracking-normal mr-20"
style={{ fontSize: "1.335rem" }}
>
Register A Vehicles
</Link>
</li>
<li
onClick={signOut}
className="m-0 text-white font-inter font-semibold hover:text-white focus:text-white cursor-pointer tracking-normal"
style={{ fontSize: "1.335rem" }}
>
Sign Out
</li>
</ul>
</>
) : (
""
)}
</nav>
</div>
);
};
export default Navbar;

View File

@@ -0,0 +1,79 @@
import React, { useState } from "react";
import { useSelector } from "react-redux";
// Services
import * as apiService from "../../services/apiService";
// Components
import Card from "./Card";
import Heading3 from "./Heading3";
import Button from "./Button";
import InputText from "./inputs/InputText";
import InputSelect from "./inputs/InputSelect";
const VehicleRegisterForm = () => {
const [model, setModel] = useState("");
const [licensePlate, setlicensePlate] = useState("");
const [color, setColor] = useState("White");
const [type, setType] = useState(1);
const user = useSelector((state) => state.auth.user);
async function registerVehicle() {
await apiService.registerVehicle(
{ model, licensePlate, color, type },
user.access_token
);
// await getVehicles();
}
return (
<Card styles={{ padding: "60px" }} classes="xl:w-2/5">
<form onSubmit={(e) => e.preventDefault()} className="m-0 flex flex-col">
<Heading3 styles={{ marginTop: "0" }}>Register A Vehicle</Heading3>
<div className="flex flex-col">
<InputText
label="Model"
value={model}
name="model"
placeholder="Model"
onChangeEvent={(e) => setModel(e.target.value)}
/>
<InputText
label="License Plate"
value={licensePlate}
name="licensePlate"
placeholder="License Plate"
onChangeEvent={(e) => setlicensePlate(e.target.value)}
/>
<InputText
label="Color"
value={color}
name="color"
placeholder="Color"
onChangeEvent={(e) => setColor(e.target.value)}
/>
<InputSelect
label="Type"
value={type}
name="type"
onChangeEvent={(e) => setType(e.target.value)}
options={[
{ value: "1", text: "Sedan" },
{ value: "2", text: "SUV" },
{ value: "3", text: "Pickup" },
]}
/>
</div>
<Button
text="Register"
onClickEvent={registerVehicle}
classes="mt-10"
/>
</form>
</Card>
);
};
export default VehicleRegisterForm;

View File

@@ -0,0 +1,98 @@
import React, { useState, useEffect } from "react";
import { useSelector } from "react-redux";
import { useHistory } from "react-router-dom";
// Services
import * as apiService from "../../services/apiService";
// Components
import Heading1 from "./Heading1";
import Heading3 from "./Heading3";
import Button from "./Button";
import Table from "./table/Table";
const VehiclesMain = () => {
const user = useSelector((state) => state.auth.user);
const history = useHistory();
// Initial state must be null ** Temporary **
const [vehicleData, setVehicleData] = useState([
{
id: Math.floor(Math.random() * 200) + 1,
color: "White",
model: "Toyota Camry",
licensePlate: "14324235",
type: 2,
},
{
id: Math.floor(Math.random() * 200) + 1,
color: "Black",
model: "Honda Accord",
licensePlate: "8765658",
type: 1,
},
{
id: Math.floor(Math.random() * 200) + 1,
color: "Beige",
model: "Toyota Corolla",
licensePlate: "235464",
type: 2,
},
{
id: Math.floor(Math.random() * 200) + 1,
color: "Grey",
model: "Toyota Yaris",
licensePlate: "1878767",
type: 2,
},
{
id: Math.floor(Math.random() * 200) + 1,
color: "White",
model: "Toyota Camry",
licensePlate: "9956443",
type: 1,
},
]);
useEffect(() => {
getVehicles();
// eslint-disable-next-line
}, []);
async function getVehicles() {
console.log(user);
const vehicles = await apiService.getVehiclesFromApi(user.access_token);
setVehicleData(vehicles);
}
return (
<div className="flex flex-col xl:w-2/3 lg:w-4/5 w-11/12">
<Heading1
text={"Traffic Police Service"}
classes="mt-24"
styles={{
marginBottom: "0",
}}
/>
{/* <p>Hello, {user.profile.given_name}.</p> */}
{vehicleData ? (
<>
<Heading3>Your Vehicles:</Heading3>
<Table vehicleData={vehicleData} />
</>
) : (
<h3 className="font-light font-inter text-black-custom my-32 self-center">
No vehicles yet.
</h3>
)}
<Button
text="Register A Vehicle"
classes={vehicleData && "self-start my-24"}
onClickEvent={() => history.push("/register")}
/>
</div>
);
};
export default VehiclesMain;

View File

@@ -0,0 +1,39 @@
import React from "react";
const InputSelect = ({
label,
value,
name,
placeholder,
onChangeEvent,
options,
}) => {
return (
<div className="flex flex-col items-start">
<label className="font-inter font-semibold text-2xl text-black-custom mb-4">
{label}
</label>
<select
value={value}
name={name}
onChange={onChangeEvent}
className="font-normal font-inter text-2xl text-black-custom mb-10 cursor-pointer"
style={{
borderRadius: ".25rem",
border: "none",
boxShadow: `0 1px 1px rgba(0, 0, 0, 0.2), 0 0 4px rgba(0, 0, 0, 0.1)`,
background: "none",
appearance: "auto",
}}
>
{options.map((option, i) => (
<option key={i} value={option.value}>
{option.text}
</option>
))}
</select>
</div>
);
};
export default InputSelect;

View File

@@ -0,0 +1,27 @@
import React from "react";
const InputText = ({ label, value, name, onChangeEvent, placeholder }) => {
return (
<div className="flex flex-col items-start">
<label className="font-inter font-semibold text-2xl text-black-custom mb-4">
{label}
</label>
<input
value={value}
type="text"
name={name}
onChange={onChangeEvent}
className="font-normal font-inter text-2xl text-black-custom mb-10"
placeholder={placeholder}
autoComplete="off"
style={{
borderRadius: ".25rem",
border: "none",
boxShadow: `0 1px 1px rgba(0, 0, 0, 0.2), 0 0 4px rgba(0, 0, 0, 0.1)`,
}}
/>
</div>
);
};
export default InputText;

View File

@@ -0,0 +1,13 @@
import React from "react";
const ColumnName = ({ text }) => (
<th
scope="col"
className="whitespace-nowrap text-2xl font-inter text-black-custom font-semibold text-center"
style={{ padding: "10px 40px 10px 40px" }}
>
{text}
</th>
);
export default ColumnName;

View File

@@ -0,0 +1,15 @@
import React from "react";
import { FiSettings, FiTrash } from "react-icons/fi";
import { BsThreeDots } from "react-icons/bs";
const EditBtns = () => {
return (
<div className="flex">
<FiTrash className="mx-3 cursor-pointer" />
<FiSettings className="mx-3 cursor-pointer" />
<BsThreeDots className="mx-3 text-3xl cursor-pointer" />
</div>
);
};
export default EditBtns;

View File

@@ -0,0 +1,51 @@
import React from "react";
import ColumnName from "./ColumnName";
import EditBtns from "./EditBtns";
import TableData from "./TableData";
const Table = ({ vehicleData }) => {
function getType(type) {
// eslint-disable-next-line
switch (type) {
case 1:
return "Sedan";
case 2:
return "SUV";
case 3:
return "Pickup";
}
}
return (
<div className="shadow overflow-x-auto border-b border-gray-200 sm:rounded w-full">
<table className="min-w-full divide-y divide-gray-200 mb-0">
<thead className="bg-gray-50">
<tr>
<ColumnName text={"Model"} />
<ColumnName text={"License Plate"} />
<ColumnName text={"Color"} />
<ColumnName text={"Type"} />
<th scope="col" className="relative px-6 py-3">
<span className="sr-only">Actions</span>
</th>
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200">
{vehicleData.map((vehicle) => (
<tr key={vehicle.id}>
<TableData text={vehicle.model} />
<TableData text={vehicle.licensePlate} />
<TableData text={vehicle.color} />
<TableData text={getType(vehicle.type)} />
<TableData Component={EditBtns} />
</tr>
))}
{/* <!-- More items... --> */}
</tbody>
</table>
</div>
);
};
export default Table;

View File

@@ -0,0 +1,12 @@
import React from "react";
const TableData = ({ text, Component }) => (
<td
className="whitespace-nowrap text-2xl font-inter text-black-custom font-normal text-center"
style={{ padding: "10px 40px 10px 40px" }}
>
{text ? text : <Component />}
</td>
);
export default TableData;

View File

@@ -0,0 +1,21 @@
import React from "react";
import { Switch, Route, BrowserRouter as Router } from "react-router-dom";
import RegisterVehicle from "./RegisterVehicle";
import YourVehicles from "./YourVehicles";
function Home() {
return (
<Router>
<Switch>
<Route path="/register">
<RegisterVehicle />
</Route>
<Route path="/">
<YourVehicles />
</Route>
</Switch>
</Router>
);
}
export default Home;

View File

@@ -0,0 +1,26 @@
import React from "react";
import { signinRedirect } from "../services/userService";
import { Redirect } from "react-router-dom";
import { useSelector } from "react-redux";
import Navbar from "./components/Navbar";
import Main from "./components/Main";
import LoginWindow from "./components/LoginWindow";
function Login() {
const user = useSelector((state) => state.auth.user);
function login() {
signinRedirect();
}
return user ? (
<Redirect to={"/"} />
) : (
<div>
<Navbar />
<Main Component={LoginWindow} />
</div>
);
}
export default Login;

View File

@@ -0,0 +1,22 @@
import React, { useEffect } from 'react'
import { signinRedirectCallback } from '../services/userService'
import { useHistory } from 'react-router-dom'
function SigninOidc() {
const history = useHistory()
useEffect(() => {
async function signinAsync() {
await signinRedirectCallback()
history.push('/')
}
signinAsync()
}, [history])
return (
<div>
Redirecting...
</div>
)
}
export default SigninOidc

View File

@@ -0,0 +1,22 @@
import React, { useEffect } from 'react'
import { signoutRedirectCallback } from '../services/userService'
import { useHistory } from 'react-router-dom'
function SignoutOidc() {
const history = useHistory()
useEffect(() => {
async function signoutAsync() {
await signoutRedirectCallback()
history.push('/')
}
signoutAsync()
}, [history])
return (
<div>
Redirecting...
</div>
)
}
export default SignoutOidc