integrated theme in app
This commit is contained in:
parent
328a760eb8
commit
a1072bff05
BIN
public/backgroundCurvyLines.png
Normal file
BIN
public/backgroundCurvyLines.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 36 KiB |
@ -5,6 +5,7 @@ import { useNavigate } from "react-router-dom";
|
|||||||
import { yupResolver } from "@hookform/resolvers/yup";
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
import * as yup from "yup";
|
import * as yup from "yup";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
|
import Typography from "@theme/modules/components/Typography";
|
||||||
|
|
||||||
type Inputs = {
|
type Inputs = {
|
||||||
email: string;
|
email: string;
|
||||||
@ -48,7 +49,7 @@ export default function ForgotPassword() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onSubmit(data: Inputs) {
|
function onSubmit(data: Inputs) {
|
||||||
console.log("There will be an API call now with the following data");
|
console.warn("There will be an API call now with the following data");
|
||||||
console.table(data);
|
console.table(data);
|
||||||
console.log(
|
console.log(
|
||||||
"You can now go to http://localhost:8080/reset to acces the reset form"
|
"You can now go to http://localhost:8080/reset to acces the reset form"
|
||||||
@ -59,11 +60,11 @@ export default function ForgotPassword() {
|
|||||||
<main className="cardContainer">
|
<main className="cardContainer">
|
||||||
<form onSubmit={handleSubmit(onSubmit)}>
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
<Card className="card">
|
<Card className="card">
|
||||||
<h3>Forgot Passowrd</h3>
|
<Typography className="title" variant="h5">Forgot Password</Typography>
|
||||||
<p>
|
<Typography>
|
||||||
If you have forgot your password, we can send you an
|
If you have forgot your password, we can send you an
|
||||||
email with a link to reset it.
|
email with a link to reset it.
|
||||||
</p>
|
</Typography>
|
||||||
<TextField {...emailProps} />
|
<TextField {...emailProps} />
|
||||||
<div className="buttons">
|
<div className="buttons">
|
||||||
<Button
|
<Button
|
||||||
|
@ -6,6 +6,7 @@ import { yupResolver } from "@hookform/resolvers/yup";
|
|||||||
import * as yup from "yup";
|
import * as yup from "yup";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import userContext from "@ts/userContext"
|
import userContext from "@ts/userContext"
|
||||||
|
import Typography from "@theme/modules/components/Typography";
|
||||||
|
|
||||||
type Inputs = {
|
type Inputs = {
|
||||||
email: string;
|
email: string;
|
||||||
@ -65,7 +66,7 @@ export default function Login() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function onSubmit(data: Inputs) {
|
function onSubmit(data: Inputs) {
|
||||||
console.log("There will be an API call now with the following data");
|
console.warn("There will be an API call now with the following data");
|
||||||
data = { ...data, password: hash(data.password) };
|
data = { ...data, password: hash(data.password) };
|
||||||
user.setName(data.email);
|
user.setName(data.email);
|
||||||
console.table(data);
|
console.table(data);
|
||||||
@ -76,15 +77,15 @@ export default function Login() {
|
|||||||
<main className="cardContainer">
|
<main className="cardContainer">
|
||||||
<form onSubmit={handleSubmit(onSubmit)}>
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
<Card className="card">
|
<Card className="card">
|
||||||
<h3>Login</h3>
|
<Typography className="title" variant="h4">Login</Typography>
|
||||||
<TextField {...emailProps} />
|
<TextField {...emailProps} />
|
||||||
<TextField {...passProps} />
|
<TextField {...passProps} />
|
||||||
<Button type="submit" id="submit" variant="contained">
|
<Button type="submit" id="submit" variant="contained">
|
||||||
Login
|
Login
|
||||||
</Button>
|
</Button>
|
||||||
<p>
|
<Typography>
|
||||||
Forgot your <Link to="/forgot">password</Link>?
|
Forgot your <Link to="/forgot">password</Link>?
|
||||||
</p>
|
</Typography>
|
||||||
</Card>
|
</Card>
|
||||||
</form>
|
</form>
|
||||||
</main>
|
</main>
|
||||||
|
@ -5,6 +5,7 @@ import { useNavigate } from "react-router-dom";
|
|||||||
import { yupResolver } from "@hookform/resolvers/yup";
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
import * as yup from "yup";
|
import * as yup from "yup";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
|
import Typography from "@theme/modules/components/Typography";
|
||||||
|
|
||||||
type Inputs = {
|
type Inputs = {
|
||||||
password: string;
|
password: string;
|
||||||
@ -43,6 +44,7 @@ export default function Reset() {
|
|||||||
inputRef: passRef,
|
inputRef: passRef,
|
||||||
className: "textField",
|
className: "textField",
|
||||||
name: "password",
|
name: "password",
|
||||||
|
type: "password",
|
||||||
id: "password",
|
id: "password",
|
||||||
label: "Password",
|
label: "Password",
|
||||||
error: !!errors.password,
|
error: !!errors.password,
|
||||||
@ -58,13 +60,14 @@ export default function Reset() {
|
|||||||
className: "textField",
|
className: "textField",
|
||||||
name: "confirm_password",
|
name: "confirm_password",
|
||||||
id: "confirm_password",
|
id: "confirm_password",
|
||||||
|
type: "password",
|
||||||
label: "Confirm Password",
|
label: "Confirm Password",
|
||||||
error: !!errors.confirm_password,
|
error: !!errors.confirm_password,
|
||||||
helperText: errors?.confirm_password?.message,
|
helperText: errors?.confirm_password?.message,
|
||||||
};
|
};
|
||||||
|
|
||||||
function onSubmit(data: Inputs) {
|
function onSubmit(data: Inputs) {
|
||||||
console.log("There will be an API call now with the following data");
|
console.warn("There will be an API call now with the following data");
|
||||||
data = {
|
data = {
|
||||||
password: hash(data.password),
|
password: hash(data.password),
|
||||||
confirm_password: hash(data.confirm_password),
|
confirm_password: hash(data.confirm_password),
|
||||||
@ -76,7 +79,7 @@ export default function Reset() {
|
|||||||
<main className="cardContainer">
|
<main className="cardContainer">
|
||||||
<form onSubmit={handleSubmit(onSubmit)}>
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
<Card className="card">
|
<Card className="card">
|
||||||
<h3>Reset Password</h3>
|
<Typography className="title" variant="h5">Reset Password</Typography>
|
||||||
<TextField {...passProps} />
|
<TextField {...passProps} />
|
||||||
<TextField {...confirmPassProps} />
|
<TextField {...confirmPassProps} />
|
||||||
<Button type="submit" id="submit" variant="contained">
|
<Button type="submit" id="submit" variant="contained">
|
||||||
|
@ -2,18 +2,144 @@ import React, { useContext, useEffect } from "react";
|
|||||||
import "@scss/transactions.scss";
|
import "@scss/transactions.scss";
|
||||||
import Table from "@components/Transactions/Table"
|
import Table from "@components/Transactions/Table"
|
||||||
import userContext from "@ts/userContext"
|
import userContext from "@ts/userContext"
|
||||||
|
import AppBar from "@theme/modules/components/AppBar";
|
||||||
|
import Toolbar from "@theme/modules/components/Toolbar";
|
||||||
|
import Typography from "@theme/modules/components/Typography";
|
||||||
|
import { Box, Link, TextFieldProps, TextField } from "@mui/material";
|
||||||
|
import AccountCircleIcon from '@mui/icons-material/AccountCircle';
|
||||||
|
import { DesktopDatePicker } from '@mui/x-date-pickers/DesktopDatePicker';
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import * as yup from "yup";
|
||||||
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
|
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider/LocalizationProvider";
|
||||||
|
import dayjs, { Dayjs } from 'dayjs';
|
||||||
|
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
|
||||||
|
import { getValue } from "@mui/system";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
type Inputs = {
|
||||||
|
startDate?: Date;
|
||||||
|
endDate?: Date;
|
||||||
|
minAmount?: number;
|
||||||
|
maxAmount?: number;
|
||||||
|
amountType?: "incoming" | "outgoing" | "both";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const schema = yup
|
||||||
|
.object()
|
||||||
|
.shape({
|
||||||
|
startDate: yup.date().nullable().default(() => {return null}).typeError("Invalid date"),
|
||||||
|
endDate: yup.date().nullable().typeError("Invalid date"),
|
||||||
|
minAmount: yup.number().positive(),
|
||||||
|
maxAmount: yup.number().positive(),
|
||||||
|
amountType: yup.string().oneOf(["incoming", "outgoing", "both"]),
|
||||||
|
})
|
||||||
|
.required();
|
||||||
|
|
||||||
|
|
||||||
export default function Transactions() {
|
export default function Transactions() {
|
||||||
const user = useContext(userContext)
|
const user = useContext(userContext)
|
||||||
|
|
||||||
|
const {
|
||||||
|
register,
|
||||||
|
formState: { errors },
|
||||||
|
handleSubmit,
|
||||||
|
getValues
|
||||||
|
} = useForm<Inputs>({
|
||||||
|
resolver: yupResolver(schema),
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const { ref: startDateRef, ...startDateRegisterProps } = register("startDate");
|
||||||
|
console.log(startDateRegisterProps)
|
||||||
|
|
||||||
|
const startDatePickerProps = {
|
||||||
|
...startDateRegisterProps,
|
||||||
|
inputRef: startDateRef,
|
||||||
|
value: getValues("startDate"),
|
||||||
|
className: "input datePicker start",
|
||||||
|
label: "Starting Date",
|
||||||
|
name: "endDate",
|
||||||
|
emptyLabel: "hello world",
|
||||||
|
inputFormat: "DD/MM/YYYY",
|
||||||
|
renderInput: (params: TextFieldProps) => <TextField {...params} />
|
||||||
|
}
|
||||||
|
|
||||||
|
const { ref: endDateRef, ...endDateRegisterProps } = register("endDate");
|
||||||
|
|
||||||
|
const endDatePickerProps = {
|
||||||
|
...endDateRegisterProps,
|
||||||
|
inputRef: endDateRef,
|
||||||
|
value: getValues("endDate"),
|
||||||
|
className: "input datePicker end",
|
||||||
|
label: "Ending Date",
|
||||||
|
name: "endDate",
|
||||||
|
inputFormat: "DD/MM/YYYY",
|
||||||
|
error: !!errors.minAmount,
|
||||||
|
helperText: errors?.minAmount?.message,
|
||||||
|
renderInput: (params: TextFieldProps) => <TextField {...params} />
|
||||||
|
}
|
||||||
|
|
||||||
|
const { ref: minAmountRef, ...minAmountRegisterProps } = register("minAmount");
|
||||||
|
|
||||||
|
const minAmountProps = {
|
||||||
|
...minAmountRegisterProps,
|
||||||
|
inputRef: minAmountRef,
|
||||||
|
className: "input min",
|
||||||
|
label: "Minimum Amount",
|
||||||
|
name: "minAmount",
|
||||||
|
error: !!errors.minAmount,
|
||||||
|
helperText: errors?.minAmount?.message,
|
||||||
|
}
|
||||||
|
|
||||||
|
const { ref: maxAmountRef, ...maxAmountRegisterProps } = register("maxAmount");
|
||||||
|
|
||||||
|
const maxAmountProps = {
|
||||||
|
...maxAmountRegisterProps,
|
||||||
|
inputRef: maxAmountRef,
|
||||||
|
className: "input max",
|
||||||
|
label: "Maximum Amount",
|
||||||
|
name: "maxAmount",
|
||||||
|
error: !!errors.maxAmount,
|
||||||
|
helperText: errors?.maxAmount?.message,
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id="tablePage">
|
<div id="tablePage">
|
||||||
<header>
|
<AppBar position="fixed" sx={{ background: "#28282a" }}>
|
||||||
Hello {user.name}
|
<Toolbar className="toolbar" sx={{ justifyContent: 'space-between' }}>
|
||||||
</header>
|
<Box className="box left" />
|
||||||
|
<Typography variant="h3" >
|
||||||
|
Transactions
|
||||||
|
</Typography>
|
||||||
|
<Box className="box right">
|
||||||
|
<Link variant="h6" className="link" href="/">
|
||||||
|
{user.name}
|
||||||
|
</Link>
|
||||||
|
<AccountCircleIcon className="icon" />
|
||||||
|
</Box>
|
||||||
|
</Toolbar>
|
||||||
|
</AppBar>
|
||||||
<aside>
|
<aside>
|
||||||
|
<form>
|
||||||
|
<Typography variant="h5">
|
||||||
|
Filters
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="h6">
|
||||||
|
Dates
|
||||||
|
</Typography>
|
||||||
|
<LocalizationProvider dateAdapter={AdapterDayjs}>
|
||||||
|
<DesktopDatePicker {...startDatePickerProps} />
|
||||||
|
<DesktopDatePicker {...endDatePickerProps} />
|
||||||
|
</LocalizationProvider>
|
||||||
|
<Typography variant="h6">
|
||||||
|
Transactions
|
||||||
|
</Typography>
|
||||||
|
<TextField {...minAmountProps}></TextField>
|
||||||
|
<TextField {...maxAmountProps}></TextField>
|
||||||
|
</form>
|
||||||
</aside>
|
</aside>
|
||||||
<main>
|
<main>
|
||||||
<Table />
|
<Table />
|
||||||
|
@ -3,7 +3,7 @@ import React, { useEffect } from "react";
|
|||||||
import { useNavigate, useSearchParams } from "react-router-dom";
|
import { useNavigate, useSearchParams } from "react-router-dom";
|
||||||
|
|
||||||
type AuthProps = {
|
type AuthProps = {
|
||||||
children: JSX.Element | JSX.Element[],
|
children: React.ReactNode,
|
||||||
}
|
}
|
||||||
export default function AuthComponent({ children }: AuthProps) {
|
export default function AuthComponent({ children }: AuthProps) {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
@ -8,5 +8,6 @@
|
|||||||
|
|
||||||
body {
|
body {
|
||||||
background: $bg1;
|
background: $bg1;
|
||||||
|
background-image: $bg-image;
|
||||||
color: $fg1;
|
color: $fg1;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
@import "variables.module.scss";
|
@import "variables.module.scss";
|
||||||
|
|
||||||
body.transactions {
|
body.transactions {
|
||||||
|
background-image: url("/public/backgroundCurvyLines.png");
|
||||||
|
|
||||||
div#tablePage {
|
div#tablePage {
|
||||||
color: black;
|
color: black;
|
||||||
display: grid;
|
display: grid;
|
||||||
@ -18,18 +20,49 @@ body.transactions {
|
|||||||
|
|
||||||
header {
|
header {
|
||||||
grid-row: 1;
|
grid-row: 1;
|
||||||
background: lightcyan;
|
position: fixed;
|
||||||
|
background-color: $bg-header;
|
||||||
|
|
||||||
|
.toolbar {
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
.box {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box.right {
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.link {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
margin-right: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
width: 1.75em;
|
||||||
|
height: 1.75em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
grid-row: 3;
|
grid-row: 3;
|
||||||
background: lightcoral;
|
// background: lightcoral;
|
||||||
}
|
}
|
||||||
|
|
||||||
main {
|
main {
|
||||||
grid-row: 2;
|
grid-row: 2;
|
||||||
grid-column: 2;
|
grid-column: 2;
|
||||||
|
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
// justify-content: center;
|
// justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -46,7 +79,20 @@ body.transactions {
|
|||||||
aside {
|
aside {
|
||||||
grid-column: 1;
|
grid-column: 1;
|
||||||
grid-row: 2;
|
grid-row: 2;
|
||||||
background: lightgreen;
|
|
||||||
|
form {
|
||||||
|
display: flex;
|
||||||
|
padding: 7px;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
flex-direction: column;
|
||||||
|
padding-top:1em;
|
||||||
|
|
||||||
|
.input {
|
||||||
|
margin: .4em 0;
|
||||||
|
background: $bg1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,5 +1,7 @@
|
|||||||
$bg1: #333;
|
$bg1: white;
|
||||||
$fg1: #c5c8c6;
|
$bg-image: url("/public/backgroundCurvyLines.png");
|
||||||
|
$bg-header: #28282a;
|
||||||
|
$fg1: black;
|
||||||
|
|
||||||
$fg-green: green;
|
$fg-green: green;
|
||||||
$fg-red: red;
|
$fg-red: red;
|
||||||
|
Loading…
Reference in New Issue
Block a user