Skip to content
This repository was archived by the owner on Feb 10, 2025. It is now read-only.

Commit 57a4b8f

Browse files
vincit-matujoonatank
authored andcommitted
fix: update feedback-page url
- the url is defined as EMAIL_VARAAMO_EXT_LINK env-variable - implemented in the Footer on ui pages - implemented in 403 & 5xx error pages on admin pages - reorganise the error "translations", make 5xx texts dynamic - fixes admin-ui App.tsx’s use of withAuthorization()
1 parent 43738b2 commit 57a4b8f

15 files changed

Lines changed: 154 additions & 59 deletions

File tree

apps/admin-ui/src/App.tsx

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,22 @@ const ApplicationRoundAllocation = dynamic(
6060
const withAuthorization = (
6161
component: JSX.Element,
6262
apiBaseUrl: string,
63+
feedbackUrl: string,
6364
permission?: Permission
6465
) => (
65-
<AuthorizationChecker permission={permission} apiUrl={apiBaseUrl}>
66+
<AuthorizationChecker
67+
permission={permission}
68+
apiUrl={apiBaseUrl}
69+
feedbackUrl={feedbackUrl}
70+
>
6671
{component}
6772
</AuthorizationChecker>
6873
);
6974

7075
type Props = {
7176
reservationUnitPreviewUrl: string;
7277
apiBaseUrl: string;
78+
feedbackUrl: string;
7379
};
7480
const UnitsRouter = ({
7581
reservationUnitPreviewUrl,
@@ -117,82 +123,125 @@ const ApplicationRoundsRouter = () => (
117123
</Routes>
118124
);
119125

120-
const PremisesRouter = () => (
126+
const PremisesRouter = ({
127+
apiBaseUrl,
128+
feedbackUrl,
129+
}: Omit<Props, "reservationUnitPreviewUrl">) => (
121130
<Routes>
122131
<Route
123132
path="spaces"
124-
element={withAuthorization(<SpacesList />, Permission.CAN_MANAGE_SPACES)}
133+
element={withAuthorization(
134+
<SpacesList />,
135+
apiBaseUrl,
136+
feedbackUrl,
137+
Permission.CAN_MANAGE_SPACES
138+
)}
125139
/>
126140
<Route
127141
path={`${prefixes.reservationUnits}`}
128142
element={withAuthorization(
129143
<ReservationUnits />,
144+
apiBaseUrl,
145+
feedbackUrl,
130146
Permission.CAN_MANAGE_UNITS
131147
)}
132148
/>
133149
<Route
134150
path="resources"
135151
element={withAuthorization(
136152
<ResourcesList />,
153+
apiBaseUrl,
154+
feedbackUrl,
137155
Permission.CAN_MANAGE_RESOURCES
138156
)}
139157
/>
140158
<Route
141159
path="units"
142-
element={withAuthorization(<Units />, Permission.CAN_MANAGE_UNITS)}
160+
element={withAuthorization(
161+
<Units />,
162+
apiBaseUrl,
163+
feedbackUrl,
164+
Permission.CAN_MANAGE_UNITS
165+
)}
143166
/>
144167
</Routes>
145168
);
146169

147-
function ClientApp({ reservationUnitPreviewUrl, apiBaseUrl }: Props) {
170+
function ClientApp({
171+
reservationUnitPreviewUrl,
172+
apiBaseUrl,
173+
feedbackUrl,
174+
}: Props) {
148175
return (
149176
<BrowserRouter basename={PUBLIC_URL}>
150-
<PageWrapper apiBaseUrl={apiBaseUrl}>
177+
<PageWrapper apiBaseUrl={apiBaseUrl} feedbackUrl={feedbackUrl}>
151178
<Routes>
152179
<Route path="*" element={<Error404 />} />
153180
<Route
154181
path="/"
155-
element={withAuthorization(<HomePage />, apiBaseUrl)}
182+
element={withAuthorization(<HomePage />, apiBaseUrl, feedbackUrl)}
156183
/>
157184
<Route
158185
path={`${prefixes.applications}/*`}
159186
element={withAuthorization(
160187
<ApplicationRouter />,
188+
apiBaseUrl,
189+
feedbackUrl,
161190
Permission.CAN_VALIDATE_APPLICATIONS
162191
)}
163192
/>
164193
<Route
165194
path={`${prefixes.recurringReservations}/application-rounds/*`}
166195
element={withAuthorization(
167196
<ApplicationRoundsRouter />,
197+
apiBaseUrl,
198+
feedbackUrl,
168199
Permission.CAN_VALIDATE_APPLICATIONS
169200
)}
170201
/>
171202
<Route
172203
path="/premises-and-settings/*"
173-
element={withAuthorization(<PremisesRouter />, apiBaseUrl)}
204+
element={withAuthorization(
205+
<PremisesRouter
206+
apiBaseUrl={apiBaseUrl}
207+
feedbackUrl={feedbackUrl}
208+
/>,
209+
apiBaseUrl,
210+
feedbackUrl
211+
)}
174212
/>
175213
<Route
176214
path="/unit/*"
177215
element={withAuthorization(
178216
<UnitsRouter
179217
reservationUnitPreviewUrl={reservationUnitPreviewUrl}
180218
/>,
181-
apiBaseUrl
219+
apiBaseUrl,
220+
feedbackUrl
182221
)}
183222
/>
184223
<Route
185224
path="/reservations/*"
186-
element={withAuthorization(<ReservationsRouter />, apiBaseUrl)}
225+
element={withAuthorization(
226+
<ReservationsRouter />,
227+
apiBaseUrl,
228+
feedbackUrl
229+
)}
187230
/>
188231
<Route
189232
path="/my-units/*"
190-
element={withAuthorization(<MyUnitsRouter />, apiBaseUrl)}
233+
element={withAuthorization(
234+
<MyUnitsRouter />,
235+
apiBaseUrl,
236+
feedbackUrl
237+
)}
191238
/>
192239
<Route
193240
path="/messaging/notifications/*"
194241
element={withAuthorization(
195242
<NotificationsRouter />,
243+
apiBaseUrl,
244+
feedbackUrl,
196245
Permission.CAN_MANAGE_BANNER_NOTIFICATIONS
197246
)}
198247
/>

apps/admin-ui/src/common/AuthorizationChecker.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ const AuthorisationChecker = ({
1010
apiUrl,
1111
children,
1212
permission,
13+
feedbackUrl,
1314
}: {
1415
apiUrl: string;
1516
children: React.ReactNode;
17+
feedbackUrl: string;
1618
permission?: Permission;
1719
}) => {
1820
const { hasAnyPermission, hasSomePermission } = usePermissionSuspended();
@@ -29,7 +31,11 @@ const AuthorisationChecker = ({
2931
// Use suspense to avoid flash of unauthorised content
3032
return (
3133
<Suspense fallback={<Loader />}>
32-
{hasAccess ? children : <Error403 apiBaseUrl={apiUrl} />}
34+
{hasAccess ? (
35+
children
36+
) : (
37+
<Error403 apiBaseUrl={apiUrl} feedbackUrl={feedbackUrl} />
38+
)}
3339
</Suspense>
3440
);
3541
};

apps/admin-ui/src/common/Error403.tsx

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,35 @@ import { breakpoints } from "common/src/common/style";
88
import { PUBLIC_URL } from "./const";
99

1010
const Wrapper = styled.div`
11-
margin: var(--spacing-layout-s);
11+
padding: var(--spacing-layout-s);
1212
word-break: break-word;
1313
gap: var(--spacing-layout-m);
1414
h1 {
1515
margin-bottom: 0;
1616
font-size: 2.5em;
1717
}
18+
p {
19+
margin-bottom: var(--spacing-layout-m);
20+
}
1821
1922
display: grid;
20-
grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
23+
grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
2124
2225
@media (min-width: ${breakpoints.l}) {
23-
margin: var(--spacing-layout-m);
26+
grid-template-columns: minmax(400px, 600px) 400px;
27+
margin: 0 auto;
2428
h1 {
2529
font-size: 4em;
2630
}
2731
}
2832
`;
2933

34+
const Column = styled.div`
35+
display: flex;
36+
flex-direction: column;
37+
gap: var(--spacing-layout-2-xs);
38+
`;
39+
3040
const Image = styled.img`
3141
width: 100%;
3242
`;
@@ -35,21 +45,24 @@ const ButtonContainer = styled.div`
3545
margin-top: var(--spacing-s);
3646
`;
3747

38-
const LogoutSection = ({ apiBaseUrl }: { apiBaseUrl: string }): JSX.Element => {
48+
const LogoutSection = ({
49+
apiBaseUrl,
50+
feedbackUrl,
51+
}: {
52+
apiBaseUrl: string;
53+
feedbackUrl: string;
54+
}): JSX.Element => {
3955
const { isAuthenticated } = useSession();
4056

4157
const { t } = useTranslation();
4258

4359
return (
44-
<>
60+
<Column>
4561
<Link external href="/">
46-
{t("errorPages.accessForbidden.linkToVaraamo")}
62+
{t("errorPages.linkToVaraamo")}
4763
</Link>
48-
<Link
49-
external
50-
href="https://app.helmet-kirjasto.fi/forms/?site=varaamopalaute&ref=https://tilavaraus.hel.fi/"
51-
>
52-
{t("errorPages.accessForbidden.giveFeedback")}
64+
<Link external href={feedbackUrl}>
65+
{t("errorPages.giveFeedback")}
5366
</Link>
5467
{isAuthenticated && (
5568
<ButtonContainer>
@@ -58,16 +71,16 @@ const LogoutSection = ({ apiBaseUrl }: { apiBaseUrl: string }): JSX.Element => {
5871
</Button>
5972
</ButtonContainer>
6073
)}
61-
</>
74+
</Column>
6275
);
6376
};
6477

6578
const Error403 = ({
6679
apiBaseUrl,
67-
showLogoutSection,
80+
feedbackUrl,
6881
}: {
6982
apiBaseUrl: string;
70-
showLogoutSection?: boolean;
83+
feedbackUrl: string;
7184
}): JSX.Element => {
7285
const { t } = useTranslation();
7386

@@ -76,7 +89,7 @@ const Error403 = ({
7689
<div>
7790
<H1 $legacy>403 - {t("errorPages.accessForbidden.title")}</H1>
7891
<p>{t("errorPages.accessForbidden.description")}</p>
79-
{showLogoutSection && <LogoutSection apiBaseUrl={apiBaseUrl} />}
92+
<LogoutSection apiBaseUrl={apiBaseUrl} feedbackUrl={feedbackUrl} />
8093
</div>
8194
<Image src={`${PUBLIC_URL}/403.png`} />
8295
</Wrapper>

apps/admin-ui/src/common/Error5xx.tsx

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import styled from "styled-components";
44
import { H1 } from "common/src/common/typography";
55
import { breakpoints } from "common/src/common/style";
66
import { PUBLIC_URL } from "./const";
7+
import { useTranslation } from "react-i18next";
78

89
const Wrapper = styled.div`
910
margin: 0 var(--spacing-s);
@@ -42,23 +43,19 @@ const Image = styled.img`
4243
}
4344
`;
4445

45-
const Error5xx = (): JSX.Element => {
46+
const Error5xx = ({ feedbackUrl }: { feedbackUrl: string }): JSX.Element => {
47+
const { t } = useTranslation();
48+
4649
return (
4750
<Wrapper>
4851
<Content>
49-
<H1 $legacy>Jokin meni vikaan</H1>
50-
<p>
51-
Pahoittelut, emme valitettavasti pysty näyttämään sivua juuri nyt.
52-
Yritä myöhemmin uudelleen!
53-
</p>
52+
<H1 $legacy>{t("errorPages.generalError.title")}</H1>
53+
<p>{t("errorPages.generalError.title")}</p>
5454
<Link external href="/">
55-
Siirry Varaamon etusivulle
55+
{t("errorPages.linkToVaraamo")}
5656
</Link>
57-
<Link
58-
external
59-
href="https://app.helmet-kirjasto.fi/forms/?site=varaamopalaute&ref=https://tilavaraus.hel.fi/"
60-
>
61-
Anna palautetta
57+
<Link external href={feedbackUrl}>
58+
{t("errorPages.giveFeedback")}
6259
</Link>
6360
</Content>
6461
<Image src={`${PUBLIC_URL}/5xx.png`} />

apps/admin-ui/src/component/PageWrapper.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { MainLander } from "./MainLander";
1616

1717
type Props = {
1818
apiBaseUrl: string;
19+
feedbackUrl: string;
1920
children: React.ReactNode;
2021
};
2122

@@ -32,22 +33,23 @@ const Wrapper = styled.div`
3233
flex-grow: 1;
3334
`;
3435

35-
const FallbackComponent = (err: unknown) => {
36+
const FallbackComponent = (err: unknown, feedbackUrl: string) => {
3637
// eslint-disable-next-line no-console
3738
console.error(err);
3839
Sentry.captureException(err);
39-
return <Error5xx />;
40+
return <Error5xx feedbackUrl={feedbackUrl} />;
4041
};
4142

4243
// NOTE client only because Navigation requires react-router-dom
4344
export default function PageWrapper({
4445
apiBaseUrl,
46+
feedbackUrl,
4547
children,
4648
}: Props): JSX.Element {
4749
const { hasAnyPermission, user } = usePermission();
4850
const hasAccess = user && hasAnyPermission();
4951
return (
50-
<ErrorBoundary FallbackComponent={FallbackComponent}>
52+
<ErrorBoundary FallbackComponent={(e) => FallbackComponent(e, feedbackUrl)}>
5153
<ClientOnly>
5254
<Navigation apiBaseUrl={apiBaseUrl} />
5355
<Wrapper>

apps/admin-ui/src/env.mjs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ const ServerSchema = z.object({
1717
TUNNISTAMO_URL: z.string().optional(),
1818
RESERVATION_UNIT_PREVIEW_URL_PREFIX: z.string().optional(),
1919
// mandatory because the SSR can't connect to the API without it
20-
// frontend SSR is running on a different host than the backend
20+
// frontend SSR is running on a different
21+
// host than the backend
2122
TILAVARAUS_API_URL: z.string().url(),
23+
EMAIL_VARAAMO_EXT_LINK: z.string().url().optional(),
2224
});
2325

2426
// NOTE if you add a new variable to client it will be fixed in the build

apps/admin-ui/src/i18n/messages.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,15 @@ const translations: ITranslations = {
255255
description: [
256256
"Sivu on nähtävillä vain kirjautuneille käyttäjille. Voit nähdä sivun sisällön, jos kirjaudut sisään ja sinulla on riittävän laajat käyttöoikeudet.",
257257
],
258-
linkToVaraamo: ["Siirry Varaamon etusivulle"],
259-
giveFeedback: ["Anna palautetta"],
260258
},
259+
generalError: {
260+
title: ["Jokin meni vikaan"],
261+
description: [
262+
"Pahoittelut, emme valitettavasti pysty näyttämään sivua juuri nyt. Yritä myöhemmin uudelleen!",
263+
],
264+
},
265+
linkToVaraamo: ["Siirry Varaamon etusivulle"],
266+
giveFeedback: ["Ota yhteyttä"],
261267
},
262268
// TODO used inside the ReservationUnitEditor
263269
ArchiveReservationUnitDialog: {

apps/admin-ui/src/pages/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export const getServerSideProps = async () => {
1818
props: {
1919
reservationUnitPreviewUrl: env.RESERVATION_UNIT_PREVIEW_URL_PREFIX ?? "",
2020
apiBaseUrl: env.TILAVARAUS_API_URL ?? "",
21+
feedbackUrl: env.EMAIL_VARAAMO_EXT_LINK ?? "",
2122
// TODO can't use SSR translations because our translations aren't in public folder
2223
// ...(await serverSideTranslations(locale ?? "fi")),
2324
},

0 commit comments

Comments
 (0)