Started on shifts page

dependabot/npm_and_yarn/typescript-eslint/parser-4.33.0
Guusvanmeerveld 3 years ago
parent 0c8f33c486
commit 1890d022ff

@ -11,6 +11,8 @@
"export": "next build && next export"
},
"dependencies": {
"@types/luxon": "^1.27.1",
"luxon": "^2.0.1",
"milligram": "^1.4.1",
"next": "^10.2.3",
"next-themes": "^0.0.14",
@ -18,7 +20,8 @@
"react-dom": "^17.0.2",
"react-google-recaptcha": "^2.1.0",
"react-icons": "^4.2.0",
"sass": "^1.34.0"
"sass": "^1.34.0",
"swr": "^0.5.6"
},
"devDependencies": {
"@types/node": "^15.6.1",
@ -34,4 +37,4 @@
"prettier": "^2.3.0",
"typescript": "^4.2.4"
}
}
}

@ -0,0 +1,29 @@
{
"updated": "2021-07-15T22:29:19.164Z",
"parsed": [
{
"start": "2021-07-07T17:00:00.000Z",
"end": "2021-07-07T19:00:00.000Z"
},
{
"start": "2021-07-08T17:00:00.000Z",
"end": "2021-07-08T20:00:00.000Z"
},
{
"start": "2021-07-10T17:00:00.000Z",
"end": "2021-07-10T20:30:00.000Z"
},
{
"start": "2021-07-14T17:30:00.000Z",
"end": "2021-07-14T19:30:00.000Z"
},
{
"start": "2021-07-17T17:00:00.000Z",
"end": "2021-07-17T20:30:00.000Z"
},
{
"start": "2021-07-18T10:00:00.000Z",
"end": "2021-07-18T13:30:00.000Z"
}
]
}

@ -11,6 +11,6 @@
"background_color": "#FFFFFF",
"display": "standalone",
"scope": "/",
"theme_color": "#9b4dca",
"theme_color": "#388e3c",
"description": "A simple portfolio website to display my projects."
}

@ -0,0 +1,40 @@
.lds {
display: inline-block;
position: relative;
width: 80px;
height: 80px;
div {
box-sizing: border-box;
display: block;
position: absolute;
width: 64px;
height: 64px;
margin: 8px;
border: 8px solid var(--foreground);
border-radius: 50%;
animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
border-color: var(--foreground) transparent transparent transparent;
&:nth-child(1) {
animation-delay: -0.45s;
}
&:nth-child(2) {
animation-delay: -0.3s;
}
&:nth-child(3) {
animation-delay: -0.15s;
}
}
}
@keyframes lds-ring {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}

@ -0,0 +1,14 @@
import { FC } from 'react';
import styles from './Spinner.module.scss';
const Spinner: FC = () => (
<div className={styles.lds}>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
);
export default Spinner;

@ -0,0 +1,4 @@
export default interface Shift {
start: string;
end: string;
}

@ -0,0 +1,40 @@
.body {
padding-top: 6rem;
}
.content {
height: calc(100vh - 6rem);
padding-top: 5rem;
text-align: center;
display: flex;
justify-content: center;
}
.table {
background-color: var(--secondary);
padding: 3rem;
font-family: 'Roboto';
border-radius: 7.5px;
border: var(--borders) 1px solid;
margin: 0;
}
.tableHeader {
font-family: 'Raleway';
text-align: left;
}
.weekDays {
text-align: center;
}
.error {
button {
margin-right: 2rem;
}
}

@ -4,6 +4,7 @@ import type { AppProps } from 'next/app';
import 'milligram';
import '@styles/raleway.css';
import '@styles/roboto.css';
import '@styles/globals.scss';

@ -0,0 +1,110 @@
import { NextPage } from 'next';
import { Info, DateTime } from 'luxon';
import useSWR from 'swr';
import { FC } from 'react';
import { stringToTime } from '@utils/date';
import Spinner from '@components/Spinner';
import Layout from '@components/Layout';
import Page from '@components/Page';
import Shift from '@models/shifts';
import styles from './Shifts.module.scss';
interface APIResponse {
updated: Date;
parsed: Shift[];
}
const Error: FC = () => (
<>
<div className={styles.error}>
<h1>Error retrieving shift information</h1>
<button className="button">Retry</button>
<a href="/">
<button className="button">Go back</button>
</a>
</div>
</>
);
const Table: FC = () => {
const { data, error } = useSWR<APIResponse>('https://api.g-vm.nl/appie');
if (error) {
return <Error />;
}
if (!data) {
return (
<>
<Spinner />
<h1>Retrieving shift information...</h1>
</>
);
}
if (data) {
const weeks = new Map<number, Record<string, Shift>>();
data.parsed.forEach((shift) => {
const weekNumber = DateTime.fromISO(shift.start).weekNumber;
const dayName = DateTime.fromISO(shift.start).weekdayLong;
const current = weeks.get(weekNumber);
weeks.set(weekNumber, { ...current, [dayName]: shift });
});
return (
<table className={styles.table}>
<caption>
<h1 className={styles.tableHeader}>Work timesheet</h1>
</caption>
<thead>
<tr className={styles.weekDays}>
<th></th>
{Info.weekdays().map((day) => (
<th key={day}>{day}</th>
))}
</tr>
</thead>
<tbody>
{Array.from(weeks).map(([weekNumber, week], i) => (
<tr key={i}>
<th>{weekNumber}</th>
{Info.weekdays().map((weekDay) => {
week[weekDay] ? (
<td key={week[weekDay].start}>
{stringToTime(week[weekDay].start)} - {stringToTime(week[weekDay].end)}
</td>
) : (
<td></td>
);
})}
</tr>
))}
</tbody>
</table>
);
}
};
const Shifts: NextPage = () => (
<Page description="Check mijn AH rooster" title="Shifts">
<Layout>
<div className={styles.body}>
<div className={styles.content}>
<div>
<Table />
</div>
</div>
</div>
</Layout>
</Page>
);
export default Shifts;

Binary file not shown.

Binary file not shown.

@ -16,6 +16,11 @@
--secondary: #1c1c1c;
--borders: #3c3838;
--foreground: rgb(236, 235, 235);
td,
th {
border-color: var(--borders);
}
}
body {
@ -35,4 +40,11 @@ a {
border-color: var(--primary);
}
input:focus,
textarea:focus,
select:focus,
input[type='email']:focus {
border-color: var(--primary);
}
@import 'page.scss';

@ -1,57 +1,9 @@
/* cyrillic-ext */
@font-face {
font-family: 'Raleway';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/raleway/v19/1Ptxg8zYS_SKggPN4iEgvnHyvveLxVvaorCFPrEVJz9d-c8.woff2)
format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Raleway';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/raleway/v19/1Ptxg8zYS_SKggPN4iEgvnHyvveLxVvaorCMPrEVJz9d-c8.woff2)
format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
font-family: 'Raleway';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/raleway/v19/1Ptxg8zYS_SKggPN4iEgvnHyvveLxVvaorCHPrEVJz9d-c8.woff2)
format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0,
U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Raleway';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/raleway/v19/1Ptxg8zYS_SKggPN4iEgvnHyvveLxVvaorCGPrEVJz9d-c8.woff2)
format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113,
U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Raleway';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/raleway/v19/1Ptxg8zYS_SKggPN4iEgvnHyvveLxVvaorCIPrEVJz9d.woff2)
format('woff2');
src: url(./fonts/raleway.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F,
U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@ -0,0 +1,8 @@
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: url(./fonts/roboto.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F,
U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@ -0,0 +1,3 @@
import { DateTime } from 'luxon';
export const stringToTime = (date: string): string => DateTime.fromISO(date).toFormat('T');

@ -6,7 +6,8 @@
"@public/*": ["src/public/*"],
"@styles/*": ["src/styles/*"],
"@models/*": ["src/models/*"],
"@config/*": ["src/config/*"]
"@config/*": ["src/config/*"],
"@utils/*": ["src/utils/*"]
},
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],

@ -159,6 +159,11 @@
resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz"
integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==
"@types/luxon@^1.27.1":
version "1.27.1"
resolved "https://registry.yarnpkg.com/@types/luxon/-/luxon-1.27.1.tgz#aceeb2d5be8fccf541237e184e37ecff5faa9096"
integrity sha512-cPiXpOvPFDr2edMnOXlz3UBDApwUfR+cpizvxCy0n3vp9bz/qe8BWzHPIEFcy+ogUOyjKuCISgyq77ELZPmkkg==
"@types/node@*", "@types/node@^15.6.1":
version "15.6.1"
resolved "https://registry.npmjs.org/@types/node/-/node-15.6.1.tgz"
@ -857,6 +862,11 @@ depd@~1.1.2:
resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz"
integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
dequal@2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.2.tgz#85ca22025e3a87e65ef75a7a437b35284a7e319d"
integrity sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug==
des.js@^1.0.0:
version "1.0.1"
resolved "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz"
@ -1798,6 +1808,11 @@ lru-cache@^6.0.0:
dependencies:
yallist "^4.0.0"
luxon@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/luxon/-/luxon-2.0.1.tgz#b41ca2f1f5ad8099c18603ae6c36a7794039daf0"
integrity sha512-8Eawf81c9ZlQj62W3eq4mp+C7SAIAnmaS7ZuEAiX503YMcn+0C1JnMQRtfaQj6B5qTZLgHv0F4H5WabBCvi1fw==
make-dir@^3.0.2:
version "3.1.0"
resolved "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz"
@ -2772,6 +2787,13 @@ supports-color@^8.0.0:
dependencies:
has-flag "^4.0.0"
swr@^0.5.6:
version "0.5.6"
resolved "https://registry.yarnpkg.com/swr/-/swr-0.5.6.tgz#70bfe9bc9d7ac49a064be4a0f4acf57982e55a31"
integrity sha512-Bmx3L4geMZjYT5S2Z6EE6/5Cx6v1Ka0LhqZKq8d6WL2eu9y6gHWz3dUzfIK/ymZVHVfwT/EweFXiYGgfifei3w==
dependencies:
dequal "2.0.2"
table@^6.0.9:
version "6.7.1"
resolved "https://registry.npmjs.org/table/-/table-6.7.1.tgz"

Loading…
Cancel
Save