diff --git a/tasks/components/FeatureDisplay.tsx b/tasks/components/FeatureDisplay.tsx index bf51ce13..a0e93475 100644 --- a/tasks/components/FeatureDisplay.tsx +++ b/tasks/components/FeatureDisplay.tsx @@ -2,34 +2,7 @@ import { tw, tx } from '@helpwave/common/twind' import { TimeDisplay } from '@helpwave/common/components/TimeDisplay' import Link from 'next/link' import { Span } from '@helpwave/common/components/Span' -import { z } from 'zod' - -export const featureSchema = z.object({ - title: z.string(), - description: z.string(), - date: z.string(), - image: z.string().url().optional(), - externalResource: z.string().url().optional(), -}).transform((obj) => { - let description: (string | URL)[] = [obj.description] - if (obj.image) description = [new URL(obj.image), ...description] - - return { - title: obj.title, - date: new Date(obj.date), - description, - externalResource: obj.externalResource ? new URL(obj.externalResource) : undefined - } -}) - -export const featuresSchema = z.array(featureSchema) - -export type Feature = { - title: string, - date: Date, - description: (string | URL)[], - externalResource?: URL -} +import type { Feature } from '../utils/features' export type FeatureDisplayProps = { feature: Feature, diff --git a/tasks/components/layout/FeatureDetails.tsx b/tasks/components/layout/FeatureDetails.tsx index e7f03518..859d5696 100644 --- a/tasks/components/layout/FeatureDetails.tsx +++ b/tasks/components/layout/FeatureDetails.tsx @@ -3,8 +3,8 @@ import type { Languages } from '@helpwave/common/hooks/useLanguage' import type { PropsWithLanguage } from '@helpwave/common/hooks/useTranslation' import { useTranslation } from '@helpwave/common/hooks/useTranslation' import { ColumnTitle } from '../ColumnTitle' -import type { Feature } from '../FeatureDisplay' import { FeatureDisplay } from '../FeatureDisplay' +import type { Feature } from '../../utils/features' type FeatureDetailsTranslation = { title: string diff --git a/tasks/pages/index.tsx b/tasks/pages/index.tsx index 89f2985e..89657352 100644 --- a/tasks/pages/index.tsx +++ b/tasks/pages/index.tsx @@ -13,8 +13,7 @@ import { useWardOverviewsQuery } from '../mutations/ward_mutations' import { useOrganizationsByUserQuery } from '../mutations/organization_mutations' import { LoadingAndErrorComponent } from '@helpwave/common/components/LoadingAndErrorComponent' import { tw } from '@twind/core' -import type { Feature } from '../components/FeatureDisplay' -import { featuresSchema } from '../components/FeatureDisplay' +import { featuresSchema, fetchFeatures } from '../utils/features' type DashboardTranslation = { dashboard: string @@ -34,13 +33,7 @@ type DashboardServerSideProps = { } export const getServerSideProps: GetServerSideProps = async () => { - const json = await fetch('https://cdn.helpwave.de/feed.json') - .then((res) => res.json()) - .then(async (json) => { - await featuresSchema.parseAsync(json) - return json as Feature[] - }) - + const json = await fetchFeatures() return { props: { jsonFeed: json } } } diff --git a/tasks/utils/config.ts b/tasks/utils/config.ts index 766a7c9a..6bc03aa2 100644 --- a/tasks/utils/config.ts +++ b/tasks/utils/config.ts @@ -36,7 +36,8 @@ const configSchema = z.object({ NEXT_PUBLIC_OAUTH_CLIENT_ID: z.string().default('425f8b8d-c786-4ff7-b2bf-e52f505fb588'), NEXT_PUBLIC_OAUTH_SCOPES: z.string().default('openid,offline_access,email,nickname,name,organizations'), NEXT_PUBLIC_FAKE_TOKEN_ENABLE: z.literal('true').or(z.literal('false')).default('false'), - NEXT_PUBLIC_FAKE_TOKEN: z.object({ sub: z.string().uuid(), name: z.string(), nickname: z.string(), email: z.string().email(), organizations: z.string().array() }).default({ sub: '18159713-5d4e-4ad5-94ad-fbb6bb147984', name: 'Max Mustermann', nickname: 'max.mustermann', email: 'max.mustermann@helpwave.de', organizations: ['3b25c6f5-4705-4074-9fc6-a50c28eba406'] }) + NEXT_PUBLIC_FAKE_TOKEN: z.object({ sub: z.string().uuid(), name: z.string(), nickname: z.string(), email: z.string().email(), organizations: z.string().array() }).default({ sub: '18159713-5d4e-4ad5-94ad-fbb6bb147984', name: 'Max Mustermann', nickname: 'max.mustermann', email: 'max.mustermann@helpwave.de', organizations: ['3b25c6f5-4705-4074-9fc6-a50c28eba406'] }), + NEXT_PUBLIC_FEATURES_FEED_URL: z.string().url().default('https://cdn.helpwave.de/feed.json'), }).transform(obj => ({ env: obj.NODE_ENV, apiUrl: obj.NEXT_PUBLIC_API_URL, @@ -54,6 +55,7 @@ const configSchema = z.object({ }, fakeTokenEnable: obj.NEXT_PUBLIC_FAKE_TOKEN_ENABLE === 'true', fakeToken: Buffer.from(JSON.stringify(obj.NEXT_PUBLIC_FAKE_TOKEN)).toString('base64'), + featuresFeedUrl: obj.NEXT_PUBLIC_FEATURES_FEED_URL, })) const getConfig = () => { diff --git a/tasks/utils/features.ts b/tasks/utils/features.ts new file mode 100644 index 00000000..27a81f59 --- /dev/null +++ b/tasks/utils/features.ts @@ -0,0 +1,39 @@ +import { z } from 'zod' +import { getConfig } from './config'; + +export type Feature = { + title: string, + date: Date, + description: (string | URL)[], + externalResource?: URL +} + +export const featureSchema = z.object({ + title: z.string(), + description: z.string(), + date: z.string(), + image: z.string().url().optional(), + externalResource: z.string().url().optional(), +}).transform((obj) => { + let description: (string | URL)[] = [obj.description] + if (obj.image) description = [new URL(obj.image), ...description] + + return { + title: obj.title, + date: new Date(obj.date), + description, + externalResource: obj.externalResource ? new URL(obj.externalResource) : undefined + } +}) + +export const featuresSchema = z.array(featureSchema) + +export const fetchFeatures = (): Promise => { + const { featuresFeedUrl } = getConfig() + return fetch(featuresFeedUrl) + .then((res) => res.json()) + .then(async (json) => { + await featuresSchema.parseAsync(json) + return json as Feature[] + }) +}