Skip to content

Commit

Permalink
Merge branch 'main' into DDFBRA-159-global-route-helper-function
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomasGross committed Nov 12, 2024
2 parents df09ec2 + 121fa20 commit 7305595
Show file tree
Hide file tree
Showing 39 changed files with 813 additions and 427 deletions.
13 changes: 4 additions & 9 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
{
"root": true,
"plugins": [
"@typescript-eslint"
],
"plugins": ["@typescript-eslint"],
"extends": [
"next/core-web-vitals",
"next/typescript",
"plugin:storybook/recommended"
"plugin:storybook/recommended",
"prettier"
],
"rules": {
"no-console": [
"error",
{
"allow": [
"warn",
"error",
"info"
]
"allow": ["warn", "error", "info"]
}
],
"@typescript-eslint/ban-ts-comment": "off"
Expand Down
31 changes: 31 additions & 0 deletions .github/workflows/prettier-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Prettier check

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
# Make sure the actual branch is checked out when running on pull requests.
ref: ${{ github.head_ref }}
fetch-depth: 0 # 👈 Required to retrieve git history

- uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"

- name: Install dependencies
run: yarn install --frozen-lockfile

- name: Check Prettier formatting
run: yarn run format:check
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,5 @@ next-env.d.ts
*storybook.log

.env.local

certificates
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.next
generated
node_modules
3 changes: 1 addition & 2 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ vars:
# Where is the docker file(s) we use for our builds residing?
LAGOON_DIR: "lagoon"


tasks:
ghcr:login:
summary: Login into Github Container Registry
Expand All @@ -33,7 +32,7 @@ tasks:
preconditions:
- sh: "[ ! -z {{.CR_PAT}} ]"
msg: "Env variable CR_PAT is not set or empty."

source:build:
summary: Build node image.
cmds:
Expand Down
3 changes: 2 additions & 1 deletion app/auth/callback/unilogin/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { NextRequest } from "next/server"
import { IntrospectionResponse } from "openid-client"

import goConfig from "@/lib/config/config"
import { getUniloginClient, uniloginClientConfig } from "@/lib/session/oauth/uniloginClient"
import { getSession, setTokensOnSession } from "@/lib/session/session"
import { TTokenSet } from "@/lib/types/session"
Expand Down Expand Up @@ -52,6 +53,6 @@ export async function GET(request: NextRequest) {
} catch (error) {
console.error(error)
// TODO: Error page or redirect to login page.
return Response.redirect("/")
return Response.redirect(goConfig("app.url"))
}
}
14 changes: 7 additions & 7 deletions app/auth/callback/unilogin/schemas.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import { z } from "zod";
import { z } from "zod"

const schemas = {
tokenSet: z.object({
access_token: z.string(),
refresh_token: z.string(),
id_token: z.string(),
expires_in: z.number(),
refresh_expires_in: z.number()
refresh_expires_in: z.number(),
}),
introspect: z.object({
uniid: z.string(),
institutionIds: z.string()
institutionIds: z.string(),
}),
userInfo: z.object({
sub: z.string()
})
};
sub: z.string(),
}),
}

export default schemas;
export default schemas
25 changes: 11 additions & 14 deletions app/auth/login/unilogin/route.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,24 @@
import { generators } from "openid-client";
import { generators } from "openid-client"

import {
getUniloginClient,
uniloginClientConfig
} from "@/lib/session/oauth/uniloginClient";
import { getSession } from "@/lib/session/session";
import { getUniloginClient, uniloginClientConfig } from "@/lib/session/oauth/uniloginClient"
import { getSession } from "@/lib/session/session"

export async function GET() {
const session = await getSession();
const session = await getSession()

session.code_verifier = generators.codeVerifier();
session.code_verifier = generators.codeVerifier()

const code_challenge = generators.codeChallenge(session.code_verifier);
const code_challenge = generators.codeChallenge(session.code_verifier)

const client = await getUniloginClient();
const client = await getUniloginClient()
const url = client.authorizationUrl({
scope: uniloginClientConfig.scope,
audience: uniloginClientConfig.audience,
redirect_uri: uniloginClientConfig.redirect_uri,
code_challenge,
code_challenge_method: "S256"
});
code_challenge_method: "S256",
})

await session.save();
return Response.redirect(url);
await session.save()
return Response.redirect(url)
}
3 changes: 2 additions & 1 deletion app/auth/logout/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { cookies } from "next/headers"
import { generators } from "openid-client"

import goConfig from "@/lib/config/config"
import { getUniloginClient, uniloginClientConfig } from "@/lib/session/oauth/uniloginClient"
import { getSession } from "@/lib/session/session"

Expand All @@ -10,7 +11,7 @@ export async function GET() {
const id_token = cookies().get("go-session:id_token")?.value
// TODO: Is this where we want to redirect to if id token cannot be resolved?
if (!id_token) {
return Response.redirect("/")
return Response.redirect(goConfig("app.url"))
}
const client = await getUniloginClient()
const endSession = client.endSessionUrl({
Expand Down
12 changes: 6 additions & 6 deletions app/auth/session/route.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { defaultSession, getSession } from "@/lib/session/session";
import { defaultSession, getSession } from "@/lib/session/session"

export async function GET() {
try {
const session = await getSession();
const session = await getSession()
if (!session) {
return Response.json({ defaultSession });
return Response.json({ defaultSession })
}
return Response.json({
isLoggedIn: session.isLoggedIn,
userInfo: session.userInfo
});
userInfo: session.userInfo,
})
} catch (e) {
return Response.json({ error: e }, { status: 500 });
return Response.json({ error: e }, { status: 500 })
}
}
4 changes: 3 additions & 1 deletion app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ export default function RootLayout({
<Theme>
<ReactQueryProvider>
<Header />
{children}
<div className="flex h-full min-h-screen-minus-navigation-height w-full flex-col">
{children}
</div>
<Footer />
</ReactQueryProvider>
</Theme>
Expand Down
2 changes: 1 addition & 1 deletion app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Image from "next/image";
import Image from "next/image"

export default async function Home() {
return (
Expand Down
83 changes: 55 additions & 28 deletions components/pages/searchPageLayout/SearchPageLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { motion } from "framer-motion"
import { useSearchParams } from "next/navigation"
import { useEffect, useRef, useState } from "react"

import SearchFiltersMobile from "@/components/shared/searchFilters/SearchFiltersMobile"
import { getFacetMachineNames } from "@/components/shared/searchFilters/helper"
import goConfig from "@/lib/config/config"
import {
Expand All @@ -15,8 +16,10 @@ import {
useSearchWithPaginationQuery,
} from "@/lib/graphql/generated/fbi/graphql"

import SearchFilterBar from "../../shared/searchFilters/SearchFilterBar"
import SearchResults from "./SearchResults"
import SearchFiltersDesktop, {
SearchFiltersDesktopGhost,
} from "../../shared/searchFilters/SearchFiltersDesktop"
import SearchResults, { SearchResultsGhost } from "./SearchResults"
import { getFacetsForSearchRequest, getNextPageParamsFunc, getSearchQueryArguments } from "./helper"

const SEARCH_RESULTS_LIMIT = goConfig<number>("search.item.limit")
Expand Down Expand Up @@ -44,6 +47,9 @@ const SearchPageLayout = ({ searchQuery }: { searchQuery?: string }) => {
data,
fetchNextPage,
isLoading: isLoadingResults,
isFetchingNextPage: isFetchingMoreResults,
isFetching: isFetchingResults,
isPending: isPendingResults,
} = useInfiniteQuery({
queryKey: useSearchWithPaginationQuery.getKey({
...searchQueryArguments,
Expand Down Expand Up @@ -109,36 +115,57 @@ const SearchPageLayout = ({ searchQuery }: { searchQuery?: string }) => {

const facetData = dataFacets?.search?.facets
const hitcount = data?.pages?.[0]?.search.hitcount ?? 0
const isNoFilters = !!(!isLoadingFacets && !facetData?.length)
const isNoSearchResult = !!(!isLoadingResults && hitcount === 0)
const isLoading =
isLoadingResults || isFetchingMoreResults || isFetchingResults || isPendingResults

return (
<div className="content-container">
<h1 className="mt-8 text-typo-heading-3 lg:mt-[88px] lg:text-typo-heading-2">
<div className="content-container my-grid-gap-2 space-y-grid-gap-2">
<h1 className="text-typo-heading-3 lg:text-typo-heading-2">
{`Viser resultater for "${q}" ${hitcount ? "(" + hitcount + ")" : ""}`}
</h1>
{/* TODO: add ghost loading and cleanup the code below */}
{isLoadingFacets && <p>isLoadingFacets...</p>}
{isNoFilters && <p>Ingen filter</p>}
{facetData && facetData?.length > 0 && <SearchFilterBar facets={dataFacets.search.facets} />}
{isLoadingResults && <p>isLoading...</p>}
{isNoSearchResult && <p>Ingen søgeresultat</p>}
<div className="mb-space-y flex flex-col gap-y-[calc(var(--grid-gap-x)*2)]">
{data?.pages.map(
(page, i) =>
page.search.works && (
<motion.div
key={i}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.5 }}
exit={{ opacity: 0 }}>
<SearchResults works={page.search.works} />
</motion.div>
)
)}
</div>
<div ref={loadMoreRef} className="h-0 opacity-0"></div>
{q ? (
<>
{!isLoadingFacets && facetData && facetData?.length > 0 ? (
<div className="relative">
<div className="xl:hidden">
<SearchFiltersMobile facets={dataFacets.search.facets} />
</div>
<div className="hidden xl:block">
<SearchFiltersDesktop facets={dataFacets.search.facets} />
</div>
</div>
) : (
<>
<div className="xl:hidden">{/* <SearchFiltersMobileGhost /> */}</div>
<div className="hidden xl:block">
<SearchFiltersDesktopGhost />
</div>
</>
)}
<hr className="-mx-grid-edge w-screen border-foreground opacity-10 md:mx-auto md:w-full" />
<div className="mb-space-y flex flex-col gap-y-[calc(var(--grid-gap-x)*2)]">
{data?.pages.map(
(page, i) =>
page.search.works && (
<motion.div
key={i}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.5 }}
exit={{ opacity: 0 }}>
<SearchResults works={page.search.works} />
</motion.div>
)
)}
{isLoading && <SearchResultsGhost />}
</div>
<div ref={loadMoreRef} className="h-0 opacity-0"></div>
</>
) : (
<div className="text-typo-body-1">
<p className="text-foreground opacity-80">Ingen søgeord fundet</p>
</div>
)}
</div>
)
}
Expand Down
22 changes: 19 additions & 3 deletions components/pages/searchPageLayout/SearchResults.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import React from "react"

import WorkCard from "@/components/shared/workCard/WorkCard"
import WorkCard, { WorkCardGhost } from "@/components/shared/workCard/WorkCard"
import { SearchWithPaginationQuery } from "@/lib/graphql/generated/fbi/graphql"

type SearchResultProps = {
Expand All @@ -11,9 +11,25 @@ type SearchResultProps = {

const SearchResults = ({ works }: SearchResultProps) => {
return (
<div className="grid grid-cols-2 gap-x-grid-gap-x gap-y-[calc(var(--grid-gap-x)*2)] md:grid-cols-3">
<div className="grid-go gap-x-grid-gap-x gap-y-[calc(var(--grid-gap-x)*2)]">
{works.map(work => (
<WorkCard key={work.workId} work={work} />
<div key={work.workId} className="col-span-3 lg:col-span-4">
<WorkCard work={work} />
</div>
))}
</div>
)
}

export const SearchResultsGhost = () => {
const ghostItems = Array.from({ length: 6 })

return (
<div className="grid-go gap-x-grid-gap-x gap-y-[calc(var(--grid-gap-x)*2)]">
{ghostItems.map((_, index) => (
<div className="col-span-3 lg:col-span-4" key={index}>
<WorkCardGhost />
</div>
))}
</div>
)
Expand Down
Loading

0 comments on commit 7305595

Please sign in to comment.