Skip to content

Commit

Permalink
add: query params to application view
Browse files Browse the repository at this point in the history
  • Loading branch information
joonatank committed Dec 18, 2024
1 parent 2a8a2c1 commit 6ffeecf
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 8 deletions.
13 changes: 12 additions & 1 deletion apps/ui/components/AccordionWithIcons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { truncatedText } from "common/styles/cssFragments";
import { Flex } from "common/styles/util";
import { IconAngleDown, IconAngleUp, useAccordion } from "hds-react";
import { useTranslation } from "next-i18next";
import { useEffect, useRef } from "react";
import styled from "styled-components";

type Props = {
Expand All @@ -16,6 +17,8 @@ type Props = {
textPostfix?: string;
icon: React.ReactNode;
}>;
id?: string;
shouldScrollIntoView?: boolean;
};

const Heading = styled.h2<{ as: "h1" | "h2" | "h3" | "h4" | "h5" | "h6" }>`
Expand Down Expand Up @@ -111,12 +114,20 @@ export function AccordionWithIcons({
initiallyOpen = false,
icons = [],
children,
shouldScrollIntoView,
...rest
}: Props): JSX.Element {
const { isOpen, openAccordion, closeAccordion } = useAccordion({
initiallyOpen,
});
const { t } = useTranslation();
const ref = useRef<HTMLDivElement>(null);

useEffect(() => {
if (shouldScrollIntoView && ref.current) {
ref.current.scrollIntoView();
}
}, [shouldScrollIntoView]);

const handleToggle = () => {
if (isOpen) {
Expand All @@ -127,7 +138,7 @@ export function AccordionWithIcons({
};

return (
<div {...rest}>
<div {...rest} ref={ref}>
<ClosedAccordionWrapper>
<Heading as={`h${headingLevel}`}>{heading}</Heading>
<IconListWrapper>
Expand Down
14 changes: 10 additions & 4 deletions apps/ui/components/application/ApprovedReservations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
formatApiTimeInterval,
fromMondayFirst,
getLocalizationLang,
toNumber,
type LocalizationLanguages,
} from "common/src/helpers";
import {
Expand Down Expand Up @@ -55,6 +56,7 @@ import {
} from "@/modules/reservation";
import { formatDateTimeStrings } from "@/modules/util";
import { PopupMenu } from "common/src/components/PopupMenu";
import { useSearchParams } from "next/navigation";

const N_RESERVATIONS_TO_SHOW = 20;

Expand Down Expand Up @@ -236,6 +238,7 @@ function formatReservationTimes(

export function ApprovedReservations({ application }: Props) {
const { t, i18n } = useTranslation();
const searchParams = useSearchParams();
const { data, loading } = useApplicationReservationsQuery({
variables: {
id: application.id,
Expand All @@ -244,8 +247,6 @@ export function ApprovedReservations({ application }: Props) {
});
const { application: app } = data || {};

const lang = getLocalizationLang(i18n.language);

const sections = filterNonNullable(
app?.applicationSections?.filter((aes) => {
const slots = aes.reservationUnitOptions.flatMap(
Expand All @@ -254,14 +255,19 @@ export function ApprovedReservations({ application }: Props) {
return slots.length > 0;
})
);
const initiallyOpen = sections.length === 1;

const lang = getLocalizationLang(i18n.language);
const selectedSection = toNumber(searchParams.get("section"));
const hasOnlyOneSection = sections.length === 1;

return (
<Flex>
{loading && <CenterSpinner />}
{sections.map((aes) => (
<AccordionWithIcons
heading={aes.name}
initiallyOpen={initiallyOpen}
initiallyOpen={hasOnlyOneSection || selectedSection === aes.pk}
shouldScrollIntoView={selectedSection === aes.pk}
headingLevel={2}
icons={[
{
Expand Down
24 changes: 21 additions & 3 deletions apps/ui/pages/applications/[id]/view/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from "react";
import React from "react";
import { useTranslation } from "next-i18next";
import { getTranslationSafe } from "common/src/common/util";
import type { GetServerSidePropsContext } from "next";
Expand Down Expand Up @@ -32,6 +32,7 @@ import { H1 } from "common";
import styled from "styled-components";
import { useToastIfQueryParam } from "@/hooks";
import { useRouter } from "next/router";
import { useSearchParams } from "next/navigation";

const TabPanel = styled(Tabs.TabPanel)`
&& {
Expand All @@ -47,7 +48,6 @@ function View({ application, tos }: PropsNarrowed): JSX.Element {
const router = useRouter();

type TabOptions = "reservations" | "application";
const [tab, setTab] = useState<TabOptions>("reservations");

useToastIfQueryParam({
key: "deletedReservationPk",
Expand Down Expand Up @@ -78,10 +78,28 @@ function View({ application, tos }: PropsNarrowed): JSX.Element {
successMessage: translateDeletedSectionMessage,
});

const searchParams = useSearchParams();

const handleRouteChange = (query: URLSearchParams) => {
// [id] param is not included in the URLSearchParams object but required when routing
if (router.query.id) {
query.set("id", router.query.id as string);
}
router.replace({ query: query.toString() }, undefined, {
shallow: true,
scroll: false,
});
};

const handleTabChange = (tab_: TabOptions) => {
setTab(tab_);
const params = new URLSearchParams(searchParams);
params.set("tab", tab_);
handleRouteChange(params);
};

const tab =
searchParams.get("tab") === "application" ? "application" : "reservations";

const round = application.applicationRound;
const lang = getLocalizationLang(i18n.language);
const applicationRoundName = getTranslationSafe(round, "name", lang);
Expand Down

0 comments on commit 6ffeecf

Please sign in to comment.