diff --git a/src/app.tsx b/src/app.tsx index 8dcbb2e..5b6f9c0 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -13,6 +13,7 @@ import { loadPage } from './data/pages.data' import { loadPost } from './data/post.data' import { loadSearchPage } from './data/search.data' import { loadInformationMenu } from './data/information.data' +import { loadColleaguesPage } from './data/colleagues.data' const ROUTES: RouteDefinition[] = [ { @@ -70,6 +71,11 @@ const ROUTES: RouteDefinition[] = [ ], load: loadInformationMenu, }, + { + path: '/misc/colleagues', + component: lazy(() => import('~/pages/Colleagues')), + load: loadColleaguesPage, + }, { path: '/_debug', component: lazy(() => import('~/pages/Debug')), diff --git a/src/data/colleagues.data.ts b/src/data/colleagues.data.ts new file mode 100644 index 0000000..8afeb59 --- /dev/null +++ b/src/data/colleagues.data.ts @@ -0,0 +1,71 @@ +import { gql, request } from '@solid-primitives/graphql' +import { RouteLoadFunc, cache } from '@solidjs/router' +import { GRAPHQL_BACKEND_URL } from '~/constants' +import { Category, Colleague } from '~/models/colleague' + +const CATEGORY_NAMES: { [K: string]: string } = { + '0': 'Vezetőség', + '1': 'Tanárok', + '2': 'Óraadók', + '3': 'Nevelő, oktató munkát közvetlenül segítők', + '4': 'Karbantartók, portások, takarítók', +} + +const HEAD_TEACHER = 'Szűcs Sándor' + +const QUERY = gql` + query Colleagues { + colleagues { + id + name + jobs + subjects + roles + awards + image + category + } + } +` + +export const queryColleaguesPage = cache(async (): Promise => { + type Response = { + colleagues: Colleague[] + } + + // TODO: error handling + const response = await request(GRAPHQL_BACKEND_URL, QUERY) + + if (response === undefined) { + return [] + } + + const colleagues = Object.groupBy(response.colleagues, ({ category }) => category) + + let categories = [] + + for (const [key, value] of Object.entries(colleagues)) { + let colleagues = value ?? [] + + colleagues.sort((a, b) => { + if (a.name === HEAD_TEACHER) { + return -1 + } else if (b.name === HEAD_TEACHER) { + return 1 + } + + return a.name > b.name ? 1 : -1 + }) + + categories.push({ + name: CATEGORY_NAMES[key], + colleagues, + } satisfies Category) + } + + return categories +}, 'Colleagues.queryColleaguesPage') + +export const loadColleaguesPage: RouteLoadFunc = () => { + void queryColleaguesPage() +} diff --git a/src/models/colleague.ts b/src/models/colleague.ts new file mode 100644 index 0000000..0aa5d39 --- /dev/null +++ b/src/models/colleague.ts @@ -0,0 +1,15 @@ +export type Colleague = { + id: string + name: string + jobs?: string + subjects?: string + roles?: string + awards?: string + image?: string + category: number +} + +export type Category = { + name: string + colleagues: Colleague[] +} diff --git a/src/pages/Colleagues.module.scss b/src/pages/Colleagues.module.scss new file mode 100644 index 0000000..c8e0d88 --- /dev/null +++ b/src/pages/Colleagues.module.scss @@ -0,0 +1,54 @@ +.container { + width: min(var(--page-width), 100% - 2 * var(--page-padding)); + margin-inline: auto; +} + +.category { + margin-top: 3rem; + + h2 { + margin-bottom: 1.5rem; + } + + .grid { + display: grid; + grid-template-columns: 1fr; + gap: 2rem; + + @include md { + grid-template-columns: repeat(auto-fit, minmax(45rem, 1fr)); + } + } +} + +.colleague { + display: grid; + grid-template-columns: 1fr; + gap: 2rem; + background-color: var(--color-surface1); + border-radius: 0.8rem; + padding: 1rem; + + @include md { + grid-template-columns: min-content 1fr; + } + + img { + width: 10rem; + border-radius: 0.4rem; + aspect-ratio: 1 / 1.42; + } + + .name { + font-weight: 700; + font-size: 2rem; + margin-bottom: 1.2rem; + } + + .subjects, + .jobs, + .roles { + margin-bottom: 1rem; + } + +} diff --git a/src/pages/Colleagues.tsx b/src/pages/Colleagues.tsx new file mode 100644 index 0000000..cebd98d --- /dev/null +++ b/src/pages/Colleagues.tsx @@ -0,0 +1,63 @@ +import { createAsync, RouteSectionProps } from '@solidjs/router' +import { Component, For, Show, VoidComponent } from 'solid-js' +import { queryColleaguesPage } from '~/data/colleagues.data' +import styles from './Colleagues.module.scss' +import Title from '~/components/Title' +import { Category as CategoryModel, Colleague as ColleagueModel } from '~/models/colleague' + +type ColleagueProps = { + colleague: ColleagueModel +} + +const Colleague: VoidComponent = (props) => { + const colleague = props.colleague + + return ( +
+ {/* {colleague.name} */} + +
+

{colleague.name}

+

{colleague.subjects}

+

{colleague.jobs}

+

{colleague.roles}

+

{colleague.awards}

+
+
+ ) +} + +type CategoryProps = { + category: CategoryModel +} + +const Category: VoidComponent = (props) => { + const category = props.category + + return ( +
+

{category.name}

+
+ {(colleague) => } +
+
+ ) +} + +const ColleaguesPage: Component = () => { + const data = createAsync(() => queryColleaguesPage()) + + return ( + <> + + + <Show when={data()}> + <div class={styles.container}> + <For each={data()}>{(category) => <Category category={category} />}</For> + </div> + </Show> + </> + ) +} + +export default ColleaguesPage