diff --git a/app/lib/components/doodle.tsx b/app/lib/components/doodle.tsx index bc48443..714b098 100644 --- a/app/lib/components/doodle.tsx +++ b/app/lib/components/doodle.tsx @@ -10,7 +10,7 @@ export const Doodle = ({ currentUser: string }) => { return ( -
+
{doodle ? ( ) : ( diff --git a/app/routes/new-start.tsx b/app/routes/new-start.tsx deleted file mode 100644 index 42cf1dc..0000000 --- a/app/routes/new-start.tsx +++ /dev/null @@ -1,442 +0,0 @@ -import {type LoaderFunctionArgs, json, type HeadersArgs} from '@remix-run/node' -import {useLoaderData} from '@remix-run/react' -import {pick, diffArray} from '@arcath/utils' - -import {createTimings} from '~/utils/timings.server' -import {getUPNFromHeaders, getUserFromUPN} from '~/lib/user.server' -import {getConfigValues} from '~/lib/config.server' -import {getPrisma, getShortcutsForUser} from '~/lib/prisma' -import {getSupplyLevels} from '~/lib/printers.server' - -import {MDXComponent} from '~/lib/mdx' -import {Doodle} from '~/lib/components/doodle' -import {TabedBox, Tab} from '~/lib/components/tabed-box' -import {COMPONENT_STATUS} from '~/utils/constants' - -export const loader = async ({request}: LoaderFunctionArgs) => { - const {time, getHeader} = createTimings() - - const url = new URL(request.url) - const doodleIdString = url.searchParams.get('doodle') - let doodleId = 0 - - if (doodleIdString) { - doodleId = parseInt(doodleIdString) - } - - const user = await time('getUser', 'Get User from header', () => - getUserFromUPN(getUPNFromHeaders(request)) - ) - - const prisma = getPrisma() - - const [title, dateFormat, logo, headerStrip, snowScript] = await time( - 'getConfig', - 'Get config from database', - () => - getConfigValues([ - 'title', - 'dateFormat', - 'logo', - 'headerStripCache', - 'snowScript' - ]) - ) - - const doodle = await time('getDoodle', 'Get doodle', async () => { - if (doodleId !== 0) { - return prisma.doodle.findFirstOrThrow({where: {id: doodleId}}) - } - - const today = new Date() - const doodleDate = new Date( - `${today.getFullYear()}-${(today.getMonth() + 1) - .toString() - .padStart(2, '0')}-${today - .getDate() - .toString() - .padStart(2, '0')} 00:00:00+0000` - ) - - return prisma.doodle.findFirst({ - where: { - startDate: {lte: doodleDate}, - endDate: {gte: doodleDate} - }, - orderBy: {endDate: 'asc'} - }) - }) - - const {shortcuts, hasOverflow, scopes} = await time( - 'getShortcutsForUser', - 'Get shortcuts for the given user', - () => getShortcutsForUser(user, request) - ) - - const levels = await time( - 'getSupplyLevels', - 'Get printer supply levels', - async () => { - return (await getSupplyLevels()).filter(({staffOnly}) => { - if (user.type !== 'STAFF') { - return !staffOnly - } - - return true - }) - } - ) - - const advert = await time('getAds', 'Get adverts', async () => { - const allAdverts = await prisma.advert.findMany({ - where: {startDate: {lte: new Date()}, endDate: {gte: new Date()}} - }) - - const adverts = allAdverts.filter(({targets}) => { - const {common} = diffArray(targets, scopes) - - return common.length > 0 - }) - - return adverts.length > 0 - ? adverts[Math.floor(Math.random() * adverts.length)] - : null - }) - - const message = await time( - 'getMessagesForUser', - 'Get messages for the current user', - async () => { - const today = new Date() - - const messageDate = new Date( - `${today.getFullYear()}-${(today.getMonth() + 1) - .toString() - .padStart(2, '0')}-${today - .getDate() - .toString() - .padStart(2, '0')} 00:00:00+0000` - ) - - const activeMessages = await prisma.infoMessage.findMany({ - where: { - startDate: {lte: messageDate}, - endDate: {gte: messageDate} - }, - orderBy: {endDate: 'asc'} - }) - - const messages = activeMessages.filter(({scopes: messageScopes}) => { - const {common} = diffArray(scopes, messageScopes) - - if (common.length > 0) { - return true - } - - let matched = false - - messageScopes.forEach(scope => { - if (scope[0] === '/') { - scopes.forEach(s => { - if (s === user?.username) { - return - } - - const regex = new RegExp(scope.slice(1, -1)) - - const matches = regex.exec(s) - - if (matches) { - matched = true - } - }) - } - }) - - return matched - }) - - if (messages[0]) { - return messages[0] - } - - return undefined - } - ) - - const components = await time('getComponents', 'Get Components', async () => { - if (user.type !== 'STAFF') { - return [] - } - - return prisma.componentGroup.findMany({ - orderBy: {order: 'asc'}, - include: { - components: { - select: {id: true, name: true, state: true}, - orderBy: {name: 'asc'} - } - } - }) - }) - - return json( - { - title, - user, - headerStrip, - logo, - dateFormat, - doodle: doodle === null ? null : pick(doodle, ['bodyCache']), - shortcuts, - hasOverflow, - scopes, - levels, - advert, - snowScript, - message, - components - }, - { - headers: {'Server-Timing': getHeader()} - } - ) -} - -export const headers = ({loaderHeaders}: HeadersArgs) => { - return loaderHeaders -} - -const StartPage = () => { - const { - headerStrip, - user, - doodle, - logo, - title, - shortcuts, - levels, - advert, - message, - components - } = useLoaderData() - - let messageColors = '' - - if (message) { - switch (message.type) { - case 'Danger': - messageColors = 'bg-red-500 border-red-600' - break - case 'Warning': - messageColors = 'bg-yellow-500 border-yellow-600' - break - default: - messageColors = 'bg-blue-500 border-blue-600' - } - } - - return ( -
-
- {headerStrip !== '' ? ( - - ) : ( - '' - )} -
- {message ? ( - - {message.title} -

- - ) : ( - '' - )} -

- - -
- Logo -
-

- {user.name ? ( -

- {user.name} -

- ) : ( - '' - )} -
-
- Google Logo - - -
-
-
- -
- {levels.map(({name, black, cyan, yellow, magenta}, i) => { - return ( -
-
- {name} -
-
- {black}% -
-
- {cyan}% -
-
- {yellow}% -
-
- {magenta}% -
-
- ) - })} -
-
- {components.length > 0 ? ( - -
-

System Status

-
- {components.map(({name, id, components}) => { - return ( -
-

{name}

-
    - {components.map(({id, name, state}) => { - return ( -
  • - {COMPONENT_STATUS[state].icon} {name} -
  • - ) - })} -
-
- ) - })} -
- More Details -
-
- ) : undefined} -
-
- -
-
-
- {shortcuts.map(({id, title, icon, target}) => { - return ( - - {title} - {title} - - ) - })} - {user && user.type === 'STAFF' ? ( - - Manage Shortcuts - Manage Shortcuts - - ) : ( - '' - )} - {user && user.admin ? ( - - Admin - Admin - - ) : ( - '' - )} -
-
- {advert === null ? ( - '' - ) : ( - - {advert.name} - - )} -
-
- ) -} - -export default StartPage diff --git a/app/routes/start.tsx b/app/routes/start.tsx index 09c8e2d..238113f 100644 --- a/app/routes/start.tsx +++ b/app/routes/start.tsx @@ -1,41 +1,71 @@ -import { - type LoaderFunctionArgs, - type HeadersArgs, - redirect, - json -} from '@remix-run/node' -import {useEffect} from 'react' -import {diffArray, pick, increment} from '@arcath/utils' -import {useLoaderData, useSearchParams} from '@remix-run/react' -import {format} from 'date-fns' - -import {Button} from '~/lib/components/boxes/button' -import {Doodle} from '~/lib/components/doodle' +import {type LoaderFunctionArgs, json, type HeadersArgs} from '@remix-run/node' +import {useLoaderData} from '@remix-run/react' +import {pick, diffArray} from '@arcath/utils' -import {getConfigValue, getConfigValues} from '~/lib/config.server' -import {getUPNFromHeaders, getUserFromUPN} from '~/lib/user.server' import {createTimings} from '~/utils/timings.server' - +import {getUPNFromHeaders, getUserFromUPN} from '~/lib/user.server' +import {getConfigValues} from '~/lib/config.server' import {getPrisma, getShortcutsForUser} from '~/lib/prisma' -import {MDXComponent} from '~/lib/mdx' - import {getSupplyLevels} from '~/lib/printers.server' +import {MDXComponent} from '~/lib/mdx' +import {Doodle} from '~/lib/components/doodle' +import {TabedBox, Tab} from '~/lib/components/tabed-box' import {COMPONENT_STATUS} from '~/utils/constants' export const loader = async ({request}: LoaderFunctionArgs) => { const {time, getHeader} = createTimings() + + const url = new URL(request.url) + const doodleIdString = url.searchParams.get('doodle') + let doodleId = 0 + + if (doodleIdString) { + doodleId = parseInt(doodleIdString) + } + const user = await time('getUser', 'Get User from header', () => getUserFromUPN(getUPNFromHeaders(request)) ) - const aupRequired = await getConfigValue('aupRequired') + const prisma = getPrisma() - if (aupRequired === 'yes' && user.type === 'STUDENT' && !user.aupAccepted) { - return redirect('/aup') - } + const [title, dateFormat, logo, headerStrip, snowScript] = await time( + 'getConfig', + 'Get config from database', + () => + getConfigValues([ + 'title', + 'dateFormat', + 'logo', + 'headerStripCache', + 'snowScript' + ]) + ) - const prisma = getPrisma() + const doodle = await time('getDoodle', 'Get doodle', async () => { + if (doodleId !== 0) { + return prisma.doodle.findFirstOrThrow({where: {id: doodleId}}) + } + + const today = new Date() + const doodleDate = new Date( + `${today.getFullYear()}-${(today.getMonth() + 1) + .toString() + .padStart(2, '0')}-${today + .getDate() + .toString() + .padStart(2, '0')} 00:00:00+0000` + ) + + return prisma.doodle.findFirst({ + where: { + startDate: {lte: doodleDate}, + endDate: {gte: doodleDate} + }, + orderBy: {endDate: 'asc'} + }) + }) const {shortcuts, hasOverflow, scopes} = await time( 'getShortcutsForUser', @@ -43,6 +73,36 @@ export const loader = async ({request}: LoaderFunctionArgs) => { () => getShortcutsForUser(user, request) ) + const levels = await time( + 'getSupplyLevels', + 'Get printer supply levels', + async () => { + return (await getSupplyLevels()).filter(({staffOnly}) => { + if (user.type !== 'STAFF') { + return !staffOnly + } + + return true + }) + } + ) + + const advert = await time('getAds', 'Get adverts', async () => { + const allAdverts = await prisma.advert.findMany({ + where: {startDate: {lte: new Date()}, endDate: {gte: new Date()}} + }) + + const adverts = allAdverts.filter(({targets}) => { + const {common} = diffArray(targets, scopes) + + return common.length > 0 + }) + + return adverts.length > 0 + ? adverts[Math.floor(Math.random() * adverts.length)] + : null + }) + const message = await time( 'getMessagesForUser', 'Get messages for the current user', @@ -104,93 +164,35 @@ export const loader = async ({request}: LoaderFunctionArgs) => { } ) - const [title, dateFormat, logo, headerStrip, snowScript] = await time( - 'getConfig', - 'Get config from database', - () => - getConfigValues([ - 'title', - 'dateFormat', - 'logo', - 'headerStripCache', - 'snowScript' - ]) - ) - - const levels = await time( - 'getSupplyLevels', - 'Get printer supply levels', - async () => { - return (await getSupplyLevels()).filter(({staffOnly}) => { - if (user.type !== 'STAFF') { - return !staffOnly - } - - return true - }) - } - ) - - const advert = await time('getAds', 'Get adverts', async () => { - const allAdverts = await prisma.advert.findMany({ - where: {startDate: {lte: new Date()}, endDate: {gte: new Date()}} - }) - - const adverts = allAdverts.filter(({targets}) => { - const {common} = diffArray(targets, scopes) - - return common.length > 0 - }) - - return adverts.length > 0 - ? adverts[Math.floor(Math.random() * adverts.length)] - : null - }) - - const doodle = await time('getDoodle', 'Get doodle', async () => { - const today = new Date() - const doodleDate = new Date( - `${today.getFullYear()}-${(today.getMonth() + 1) - .toString() - .padStart(2, '0')}-${today - .getDate() - .toString() - .padStart(2, '0')} 00:00:00+0000` - ) - - return prisma.doodle.findFirst({ - where: { - startDate: {lte: doodleDate}, - endDate: {gte: doodleDate} - }, - orderBy: {endDate: 'asc'} - }) - }) - const components = await time('getComponents', 'Get Components', async () => { if (user.type !== 'STAFF') { return [] } - return prisma.component.findMany({ - select: {id: true, state: true, name: true}, - orderBy: {updatedAt: 'asc'}, - take: 10 + return prisma.componentGroup.findMany({ + orderBy: {order: 'asc'}, + include: { + components: { + select: {id: true, name: true, state: true}, + orderBy: {name: 'asc'} + } + } }) }) return json( { - user, - shortcuts, title, + user, + headerStrip, + logo, dateFormat, - levels, + doodle: doodle === null ? null : pick(doodle, ['bodyCache']), + shortcuts, hasOverflow, + scopes, + levels, advert, - logo, - headerStrip, - doodle: doodle === null ? null : pick(doodle, ['bodyCache']), snowScript, message, components @@ -205,108 +207,20 @@ export const headers = ({loaderHeaders}: HeadersArgs) => { return loaderHeaders } -const letItSnow = () => { - if (typeof document !== 'undefined') { - var embedimSnow = document.getElementById('embedim--snow') - if (!embedimSnow) { - function embRand(a: number, b: number) { - return Math.floor(Math.random() * (b - a + 1)) + a - } - var embCSS = - '.embedim-snow{position: absolute;width: 10px;height: 10px;background: white;border-radius: 50%;margin-top:-10px}' - var embHTML = '' - for (let i = 1; i < 200; i++) { - embHTML += '' - var rndX = embRand(0, 1000000) * 0.0001, - rndO = embRand(-100000, 100000) * 0.0001, - rndT = (embRand(3, 8) * 10).toFixed(2), - rndS = (embRand(0, 10000) * 0.0001).toFixed(2) - embCSS += - '.embedim-snow:nth-child(' + - i + - '){' + - 'opacity:' + - (embRand(1, 10000) * 0.0001).toFixed(2) + - ';' + - 'transform:translate(' + - rndX.toFixed(2) + - 'vw,-10px) scale(' + - rndS + - ');' + - 'animation:fall-' + - i + - ' ' + - embRand(10, 30) + - 's -' + - embRand(0, 30) + - 's linear infinite' + - '}' + - '@keyframes fall-' + - i + - '{' + - rndT + - '%{' + - 'transform:translate(' + - (rndX + rndO).toFixed(2) + - 'vw,' + - rndT + - 'vh) scale(' + - rndS + - ')' + - '}' + - 'to{' + - 'transform:translate(' + - (rndX + rndO / 2).toFixed(2) + - 'vw, 105vh) scale(' + - rndS + - ')' + - '}' + - '}' - } - embedimSnow = document.createElement('div') - embedimSnow.id = 'embedim--snow' - embedimSnow.innerHTML = - '' + - embHTML - document.body.appendChild(embedimSnow) - } - } -} - const StartPage = () => { const { + headerStrip, user, - shortcuts, + doodle, + logo, title, - dateFormat, + shortcuts, levels, - hasOverflow, advert, - doodle, - logo, - headerStrip, - snowScript, message, - components + components, + hasOverflow } = useLoaderData() - const [searchParams] = useSearchParams() - const buttonDelay = increment({ - increment: (current, count) => { - const addition = Math.log(count + 2) - - return addition / 10 - } - }) - - useEffect(() => { - if (snowScript === 'yes') { - letItSnow() - } - }) - - const newTab = searchParams.get('newtab') !== null let messageColors = '' @@ -334,7 +248,7 @@ const StartPage = () => {
{message ? ( {message.title} @@ -343,114 +257,183 @@ const StartPage = () => { ) : ( '' )} -
-
- Logo - -

- {user.name ? ( -

- {user.name} -

- ) : ( - '' - )} -
- Google Logo - - -
-

- {format(new Date(), dateFormat)} -

- {components.length > 0 ? ( -
-
- {components.map(({id, state}) => { - return ( -
- {COMPONENT_STATUS[state].icon} -
- ) - })} +
+ + + + + +
+ {levels.map(({name, black, cyan, yellow, magenta}, i) => { + return ( +
+
+ {name} +
+
+ {black}% +
+
+ {cyan}% +
+
+ {yellow}% +
+
+ {magenta}% +
+
+ ) + })}
- ) : ( - '' - )} +
+ {components.length > 0 ? ( + +
+

System Status

+
+ {components.map(({name, id, components}) => { + return ( +
+

{name}

+
    + {components.map(({id, name, state}) => { + return ( +
  • + {COMPONENT_STATUS[state].icon} {name} +
  • + ) + })} +
+
+ ) + })} +
+ More Details +
+
+ ) : undefined} + +
+
-
-
- {shortcuts.map(shortcut => { +
+
+ {shortcuts.map(({id, title, icon, target}) => { return ( -
- - {advert === null ? ( '' ) : ( @@ -458,53 +441,15 @@ const StartPage = () => { href={ advert.target === ':ad' ? `/advert/${advert.id}` : advert.target } - className="col-span-2" + className="" > {advert.name} )} -
- {levels.map(({name, black, cyan, yellow, magenta}, i) => { - return ( -
-
- {name} -
-
- {black}% -
-
- {cyan}% -
-
- {yellow}% -
-
- {magenta}% -
-
- ) - })} -
)