Skip to content

Commit

Permalink
Prepare new edit page
Browse files Browse the repository at this point in the history
  • Loading branch information
superfaz committed Sep 1, 2024
1 parent 65c67da commit 338da8b
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 47 deletions.
63 changes: 34 additions & 29 deletions src/app/edit/PageContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import { Badge, Card } from "app/components";
import { CharacterVM } from "./viewmodel";
import { deleteCharacter } from "./actions";

export function CharacterCard({ character }: Readonly<{ character: CharacterVM }>) {
export function CharacterCard({
character,
noAction = false,
}: Readonly<{ character: CharacterVM; noAction?: boolean }>) {
const [show, setShow] = useState(false);

function handleDelete() {
Expand All @@ -32,7 +35,7 @@ export function CharacterCard({ character }: Readonly<{ character: CharacterVM }
<Col xs={3}>
{character.avatar && (
<picture>
<img className="img-fluid rounded-start m-1" src={character.avatar} alt="" />
<img className="img-fluid rounded-start m-1" src={"/" + character.avatar} alt="" />
</picture>
)}
</Col>
Expand All @@ -48,34 +51,36 @@ export function CharacterCard({ character }: Readonly<{ character: CharacterVM }
</Card.Body>
</Col>
</Row>
<Card.Footer className="d-flex">
<Link className="card-link btn btn-primary flex-fill" href={`/edit/${character.id}`}>
Modifier
</Link>
<ButtonGroup className="ms-2">
{!show && (
<Button variant="danger" aria-label="Supprimer" onClick={handleDelete}>
<i className="bi bi-trash"></i>
</Button>
)}
{show && (
<>
<Button
variant="outline-danger"
className="position-relative"
aria-label="Annuler"
onClick={handleCancel}
>
<i className="bi bi-trash position-absolute"></i>
<i className="bi bi-slash-lg"></i>
</Button>
<Button variant="danger" aria-label="Confirmer la suppression" onClick={handleConfirm}>
Confirmer
{!noAction && (
<Card.Footer className="d-flex">
<Link className="card-link btn btn-primary flex-fill" href={`/edit/${character.id}`}>
Modifier
</Link>
<ButtonGroup className="ms-2">
{!show && (
<Button variant="danger" aria-label="Supprimer" onClick={handleDelete}>
<i className="bi bi-trash"></i>
</Button>
</>
)}
</ButtonGroup>
</Card.Footer>
)}
{show && (
<>
<Button
variant="outline-danger"
className="position-relative"
aria-label="Annuler"
onClick={handleCancel}
>
<i className="bi bi-trash position-absolute"></i>
<i className="bi bi-slash-lg"></i>
</Button>
<Button variant="danger" aria-label="Confirmer la suppression" onClick={handleConfirm}>
Confirmer
</Button>
</>
)}
</ButtonGroup>
</Card.Footer>
)}
</Card>
);
}
Expand Down
40 changes: 38 additions & 2 deletions src/app/edit/[character]/PageContent.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,46 @@
import { Character } from "model";
import { Button, ButtonGroup, Row } from "react-bootstrap";
import Col from "react-bootstrap/Col";
import Stack from "react-bootstrap/Stack";
import { CharacterCard } from "../PageContent";
import { toViewModel } from "../viewmodel";
import { DataSource, type IDataSource } from "data";

export function PageContent() {
export async function PageContent({ character }: Readonly<{ character: Character }>) {
const dataSource: IDataSource = new DataSource();
return (
<Col lg={6}>
<Stack direction="vertical" gap={2}>
<Row className="row-cols-1 row-cols-sm-2 row-cols-md-3 row-cols-lg-4">
<Col className="mt-3">
<CharacterCard character={await toViewModel(dataSource, character)} noAction />
</Col>
</Row>
<Row>
<Col xs={12}>
<Stack direction="vertical">
<h3 className="mt-5">Affiliations</h3>
<Button className="me-auto">
<i className="bi bi-exclamation-diamond"></i>
</Button>
<ButtonGroup>
<Button className="me-auto">
<i className="bi bi-exclamation-diamond"></i>
</Button>
<Button className="me-auto">
<i className="bi bi-exclamation-diamond"></i>
</Button>
<Button>Race</Button>
</ButtonGroup>
</Stack>
</Col>
<Col xs={12}>
<h3 className="mt-5">Détails</h3>
</Col>
<Col xs={12}>
<h3 className="mt-5">Equipement</h3>
</Col>
</Row>
<Stack direction="vertical" gap={2} className="mt-5">
<h2>Introduction</h2>
<p>
Bienvenue dans le créateur de personnage pour le jeu de rôle <strong>StarFinder</strong> de Paizo Publishing.
Expand Down
31 changes: 27 additions & 4 deletions src/app/edit/[character]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,39 @@
import { Metadata } from "next";
import { getKindeServerSession } from "@kinde-oss/kinde-auth-nextjs/server";
import { type Metadata } from "next";
import { isSecure } from "./helpers-server";
import { PageContent } from "./PageContent";
import { DataSets, DataSource, type IDataSource } from "data";
import { IdSchema } from "model";
import { notFound } from "next/navigation";

export const metadata: Metadata = {
title: "Création",
};

export default async function Page({ params }: Readonly<{ params: { character: string } }>) {
const characterId = params.character;
const returnTo = `/edit/${characterId}`;
const returnTo = `/edit/${params.character}`;

if (await isSecure(returnTo)) {
return <PageContent />;
// Validate the parameter
const parse = IdSchema.safeParse(params.character);
if (!parse.success) {
return notFound();
}

// Validate the request
const characterId: string = parse.data;
const { getUser } = getKindeServerSession();
const user = await getUser();
const dataSource: IDataSource = new DataSource();
const characters = await dataSource.get(DataSets.Characters).find({ id: characterId, userId: user.id });

if (characters.length === 0) {
return notFound();
} else if (characters.length > 1) {
throw new Error("Multiple characters found with the same id");
}

// Render the page
return <PageContent character={characters[0]} />;
}
}
32 changes: 20 additions & 12 deletions src/app/edit/viewmodel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,24 @@ export interface CharacterVM {
level?: number;
}

export async function toViewModel(dataSource: IDataSource, characters: Character[]): Promise<CharacterVM[]> {
return await Promise.all(
characters.map(async (c) => ({
id: c.id,
name: c.name,
avatar: (await dataSource.get(DataSets.Avatar).findOne(c.avatar))?.image,
race: (await dataSource.get(DataSets.Races).findOne(c.race))?.name,
theme: (await dataSource.get(DataSets.Themes).findOne(c.theme))?.name,
class: (await dataSource.get(DataSets.Class).findOne(c.class))?.name,
level: c.level,
}))
);
export async function toViewModel(dataSource: IDataSource, characters: Character[]): Promise<CharacterVM[]>;
export async function toViewModel(dataSource: IDataSource, characters: Character): Promise<CharacterVM>;
export async function toViewModel(
dataSource: IDataSource,
characters: Character[] | Character
): Promise<CharacterVM[] | CharacterVM> {
if (Array.isArray(characters)) {
return await Promise.all(characters.map((c) => toViewModel(dataSource, c)));
}

const c = characters;
return {
id: c.id,
name: c.name,
avatar: (await dataSource.get(DataSets.Avatar).findOne(c.avatar))?.image,
race: (await dataSource.get(DataSets.Races).findOne(c.race))?.name,
theme: (await dataSource.get(DataSets.Themes).findOne(c.theme))?.name,
class: (await dataSource.get(DataSets.Class).findOne(c.class))?.name,
level: c.level,
};
}

0 comments on commit 338da8b

Please sign in to comment.