Started on shifts page
parent
0c8f33c486
commit
1890d022ff
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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.
@ -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');
|
Loading…
Reference in new issue