Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions copier.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ keyprefix:
help: The prefix for various keys used in the app
default: "{{ appname | lower | replace('_', '-') }}"

identity:
type: bool
help: Whether to include identity features in the app
default: true

access:
type: bool
help: Whether to include access features in the app
default: true
when: "{{ identity }}"

docs:
type: bool
help: Whether to include a documentation site for the app
Expand Down
3 changes: 3 additions & 0 deletions src/docker-compose.yaml.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ services:
- "{{ envprefix }}__APIS__ICANHAZDADJOKE__PORT=${ {{- envprefix }}__APIS__ICANHAZDADJOKE__PORT:-}"
- "{{ envprefix }}__APIS__ICANHAZDADJOKE__SCHEME=${ {{- envprefix }}__APIS__ICANHAZDADJOKE__SCHEME:-https}"
- "{{ envprefix }}__DEBUG=${ {{- envprefix }}__DEBUG:-true}"
{%- if identity %}
- "{{ envprefix }}__IDENTITY__USERS__DEBUG__ID=${ {{- envprefix }}__IDENTITY__USERS__DEBUG__ID:-debug}"
{%- endif %}
- "{{ envprefix }}__SERVER__HOST=${ {{- envprefix }}__SERVER__HOST:-0.0.0.0}"
- "{{ envprefix }}__SERVER__PORT=${ {{- envprefix }}__SERVER__PORT:-{{ port -}} }"
network_mode: host
3 changes: 3 additions & 0 deletions src/next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ export default {
distDir: "build",

experimental: {
// Enable authentication and authorization interrupts
authInterrupts: true,

// Optimize import from Mantine packages
optimizePackageImports: [
"@mantine/core",
Expand Down
7 changes: 5 additions & 2 deletions src/src/app/(root)/(main)/(home)/page.tsx.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import type {
import type { Keys } from "./types";

import { Metadata } from "../../../../isomorphic/metadata/components/metadata";
{%- if identity and access %}
import { Authenticated } from "../../../../server/access/components/authenticated";
{%- endif %}
import { createMetadata } from "../../../../server/metadata/lib/create-metadata";
import { HomePageView } from "./page.view";
import { Schemas } from "./schemas";
Expand Down Expand Up @@ -38,9 +41,9 @@ export default async function HomePage({
const queryParameters = await Schemas.Query.parseAsync(await searchParams);

return (
<>
<{% if identity and access %}Authenticated{% endif %}>
<Metadata title={await getTitle({ queryParameters: queryParameters })} />
<HomePageView queryParameters={queryParameters} />
</>
</{% if identity and access %}Authenticated{% endif %}>
);
}
19 changes: 19 additions & 0 deletions src/src/app/(root)/layout.tsx.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,18 @@ import type { Schemas } from "./schemas";
import type { Keys } from "./types";

import { ThemeScript } from "../../common/theme/components/theme-script";
{%- if identity %}
import { IdentityProvider } from "../../isomorphic/identity/components/identity-provider";
{%- endif %}
import { LocalizationProvider } from "../../isomorphic/localization/components/localization-provider";
import { Metadata } from "../../isomorphic/metadata/components/metadata";
import { MetadataProvider } from "../../isomorphic/metadata/components/metadata-provider";
import { QueryProvider } from "../../isomorphic/query/components/query-provider";
import { StateProvider } from "../../isomorphic/state/components/state-provider";
import { ThemeProvider } from "../../isomorphic/theme/components/theme-provider";
{%- if identity %}
import { getIdentity } from "../../server/identity/lib/get-identity";
{%- endif %}
import { resolveLocale } from "../../server/localization/lib/resolve-locale";
import { createMetadata } from "../../server/metadata/lib/create-metadata";
import { createViewport } from "../../server/metadata/lib/create-viewport";
Expand Down Expand Up @@ -80,6 +86,9 @@ export default async function RootLayout({

const { queryClient } = getQueryClient();
const { locale } = await resolveLocale({ queryClient: queryClient });
{%- if identity %}
const { identity } = await getIdentity({ queryClient: queryClient });
{%- endif %}

return (
<html lang={locale} suppressHydrationWarning={true}>
Expand All @@ -97,11 +106,21 @@ export default async function RootLayout({
primaryColor={constants.colors.primary.name}
primaryShade={constants.colors.primary.shade}
>
{%- if identity %}
<IdentityProvider user={identity.user}>
<Metadata
description={await getDescription()}
title={await getTitle()}
/>
<RootLayoutView>{children}</RootLayoutView>
</IdentityProvider>
{%- else %}
<Metadata
description={await getDescription()}
title={await getTitle()}
/>
<RootLayoutView>{children}</RootLayoutView>
{%- endif %}
</ThemeProvider>
</LocalizationProvider>
</HydrationBoundary>
Expand Down
9 changes: 0 additions & 9 deletions src/src/app/(root)/layout.view.tsx

This file was deleted.

23 changes: 23 additions & 0 deletions src/src/app/(root)/layout.view.tsx.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { LayoutViewInput } from "../types";
import type { Schemas } from "./schemas";
import type { Keys } from "./types";

import { PageLayout } from "../../common/core/components/generic/page-layout";
{%- if identity %}
import { IdentityWidget } from "../../isomorphic/identity/components/identity-widget";
{%- endif %}

export async function RootLayoutView({
children,
}: LayoutViewInput<typeof Schemas.Path, Keys.Slots>) {
{%- if identity %}
return (
<PageLayout>
<IdentityWidget />
{children}
</PageLayout>
);
{%- else %}
return <PageLayout>{children}</PageLayout>;
{%- endif %}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"use client";

import { msg } from "@lingui/core/macro";

import type { ForbiddenInput, ForbiddenMetadataUtilityInput } from "../types";

import { Metadata } from "../../isomorphic/metadata/components/metadata";
import { RootForbiddenView } from "./forbidden.view";

function getTitle({}: ForbiddenMetadataUtilityInput = {}) {
return msg({ message: "Forbidden • {{ appname }}" });
}

export default function RootForbidden({}: ForbiddenInput) {
return (
<>
<Metadata title={getTitle()} />
<RootForbiddenView />
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { ForbiddenViewInput } from "../types";

import { MainLayout } from "../../common/core/components/generic/main-layout";
import { ForbiddenWidget } from "../../isomorphic/access/components/forbidden-widget";

export function RootForbiddenView({}: ForbiddenViewInput) {
return (
<MainLayout>
<ForbiddenWidget />
</MainLayout>
);
}
9 changes: 6 additions & 3 deletions src/src/app/global-error.view.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import type { ErrorViewInput } from "./types";

import { SafeMainLayout } from "../common/core/components/generic/safe-main-layout";
import { SafePageLayout } from "../common/core/components/generic/safe-page-layout";
import { SafeErrorWidget } from "../isomorphic/core/components/generic/safe-error-widget";

export function GlobalErrorView({ reset }: ErrorViewInput) {
return (
<SafeMainLayout>
<SafeErrorWidget reset={reset} />
</SafeMainLayout>
<SafePageLayout>
<SafeMainLayout>
<SafeErrorWidget reset={reset} />
</SafeMainLayout>
</SafePageLayout>
);
}
16 changes: 16 additions & 0 deletions src/src/app/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ export type ErrorInput = {
reset: () => void;
};

export type ForbiddenInput = object;

export type LayoutInput<
PathParametersKeysType extends string = never,
SlotsKeysType extends string = never,
Expand Down Expand Up @@ -77,8 +79,12 @@ export type RouteInput<PathParametersKeysType extends string = never> = {

export type TemplateInput = Simplify<PropsWithChildren<object>>;

export type UnauthorizedInput = object;

export type ErrorMetadataUtilityInput = object;

export type ForbiddenMetadataUtilityInput = object;

export type LayoutMetadataInput<PathParametersKeysType extends string = never> =
{
params: Promise<PathParameters<PathParametersKeysType>>;
Expand Down Expand Up @@ -120,8 +126,12 @@ export type PageMetadataUtilityInput<
})
>;

export type UnauthorizedMetadataUtilityInput = object;

export type ErrorViewportUtilityInput = object;

export type ForbiddenViewportUtilityInput = object;

export type LayoutViewportInput<PathParametersKeysType extends string = never> =
{
params: Promise<PathParameters<PathParametersKeysType>>;
Expand Down Expand Up @@ -163,6 +173,8 @@ export type PageViewportUtilityInput<
})
>;

export type UnauthorizedViewportUtilityInput = object;

export type DefaultViewInput<
PathParametersSchemaType extends z.core.$ZodObject = never,
> = [PathParametersSchemaType] extends [never]
Expand All @@ -173,6 +185,8 @@ export type ErrorViewInput = {
reset: () => void;
};

export type ForbiddenViewInput = object;

export type LayoutViewInput<
PathParametersSchemaType extends z.core.$ZodObject = never,
SlotsKeysType extends string = never,
Expand Down Expand Up @@ -208,3 +222,5 @@ export type PageViewInput<
>;

export type TemplateViewInput = Simplify<PropsWithChildren<object>>;

export type UnauthorizedViewInput = object;
10 changes: 1 addition & 9 deletions src/src/common/core/components/generic/main-layout/main.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
import { Box } from "@mantine/core";
import { Notifications } from "@mantine/notifications";

import type { MainLayoutInput } from "./types";

import classes from "./styles.module.css";

export function MainLayout({ children }: MainLayoutInput) {
return (
<>
<Notifications position="bottom-right" />
<Box className={classes.outer}>
<Box className={classes.inner}>{children}</Box>
</Box>
</>
);
return <Box className={classes.box}>{children}</Box>;
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,4 @@
.outer {
background-color: light-dark(
var(--mantine-color-gray-1),
var(--mantine-color-dark-7)
);
height: 100%;
padding: 0;
width: 100%;
}

.inner {
.box {
align-items: center;
display: flex;
flex-direction: column;
Expand Down
2 changes: 2 additions & 0 deletions src/src/common/core/components/generic/page-layout/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { PageLayout } from "./main";
export type { PageLayoutInput } from "./types";
15 changes: 15 additions & 0 deletions src/src/common/core/components/generic/page-layout/main.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Box } from "@mantine/core";
import { Notifications } from "@mantine/notifications";

import type { PageLayoutInput } from "./types";

import classes from "./styles.module.css";

export function PageLayout({ children }: PageLayoutInput) {
return (
<>
<Notifications position="bottom-right" />
<Box className={classes.box}>{children}</Box>
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.box {
background-color: light-dark(
var(--mantine-color-gray-1),
var(--mantine-color-dark-7)
);
height: 100%;
padding: 0;
width: 100%;
}
3 changes: 3 additions & 0 deletions src/src/common/core/components/generic/page-layout/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import type { PropsWithChildren } from "react";

export type PageLayoutInput = PropsWithChildren<object>;
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,5 @@ import type { SafeMainLayoutInput } from "./types";
import classes from "./styles.module.css";

export function SafeMainLayout({ children }: SafeMainLayoutInput) {
return (
<div className={classes.outer}>
<div className={classes.inner}>{children}</div>
</div>
);
return <div className={classes.box}>{children}</div>;
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
.outer {
height: 100%;
padding: 0;
width: 100%;
}

.inner {
.box {
align-items: center;
display: flex;
flex-direction: column;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { SafePageLayout } from "./main";
export type { SafePageLayoutInput } from "./types";
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { SafePageLayoutInput } from "./types";

import classes from "./styles.module.css";

export function SafePageLayout({ children }: SafePageLayoutInput) {
return <div className={classes.box}>{children}</div>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.box {
height: 100%;
padding: 0;
width: 100%;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import type { PropsWithChildren } from "react";

export type SafePageLayoutInput = PropsWithChildren<object>;
Loading
Loading