Skip to content

Commit

Permalink
Merge pull request #195 from npocccties/feat-page-components
Browse files Browse the repository at this point in the history
feat: ページコンポーネントの実装
  • Loading branch information
knokmki612 committed Oct 7, 2022
2 parents fd69f18 + 9177b4e commit cd131ef
Show file tree
Hide file tree
Showing 19 changed files with 354 additions and 100 deletions.
6 changes: 6 additions & 0 deletions frontend/lib/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import aspida from "@aspida/fetch";
import api from "api/$api";

export const client = api(
aspida(fetch, { baseURL: process.env.NEXT_PUBLIC_API_BASE_URL })
);
36 changes: 27 additions & 9 deletions frontend/mocks/faker.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,44 @@
import { faker } from "@faker-js/faker";
import {
Consumer,
FieldDetail,
PortalCategory,
BadgeDetail1,
Framework,
Stage,
Criteria,
} from "api/@types";

export const consumer = () => ({
export const consumer = (): Consumer => ({
consumer_id: faker.datatype.number(),
name: faker.company.name(),
url: faker.internet.url(),
email: faker.internet.email(),
});

export const field = () => ({
export const field = (): FieldDetail => ({
field1: [...Array(3)].map(() => ({
field1_name: faker.animal.bear(),
field2: [...Array(3)].map(() => ({
field2_name: faker.animal.bear(),
field3: [...Array(3)].map(() => ({
field_id: faker.datatype.number(),
field3_name: faker.animal.bear(),
wisdom_badges: [...Array(3)].map(faker.datatype.number),
})),
})),
})),
});

export const portalCategory = () => ({
export const portalCategory = (): PortalCategory => ({
portal_category_id: faker.datatype.number(),
name: faker.animal.bird(),
descritpion: faker.lorem.paragraphs(),
description: faker.lorem.paragraphs(),
image_url_path: faker.system.filePath(),
badges_count: faker.datatype.number(),
});

export const wisdomBadges = () => ({
export const wisdomBadges = (): BadgeDetail1 => ({
badges_id: faker.datatype.number(),
type: "wisdom" as const,
name: faker.animal.cat(),
Expand All @@ -39,13 +49,17 @@ export const wisdomBadges = () => ({
issuer_name: faker.company.name(),
issuer_url: faker.internet.url(),
issuer_email: faker.internet.email(),
portal_category_id: faker.datatype.number(),
portal_category_name: faker.animal.bird(),
portal_category_description: faker.lorem.paragraphs(),
portal_category_image_url_path: faker.system.filePath(),
degital_badge_class_id: faker.datatype.string(),
detail: {
knowledge_badges_list: [...Array(3)].map(faker.datatype.number),
},
});

export const knowledgeBadges = () => ({
export const knowledgeBadges = (): BadgeDetail1 => ({
badges_id: faker.datatype.number(),
type: "knowledge" as const,
name: faker.animal.cat(),
Expand All @@ -56,26 +70,30 @@ export const knowledgeBadges = () => ({
issuer_name: faker.company.name(),
issuer_url: faker.internet.url(),
issuer_email: faker.internet.email(),
portal_category_id: faker.datatype.number(),
portal_category_name: faker.animal.bird(),
portal_category_description: faker.lorem.paragraphs(),
portal_category_image_url_path: faker.system.filePath(),
degital_badge_class_id: faker.datatype.string(),
detail: [...Array(3)].map(criteria),
});

export const framework = () => ({
export const framework = (): Framework => ({
framework_id: faker.datatype.number(),
name: faker.animal.cow(),
description: faker.lorem.paragraphs(),
supplementary: faker.lorem.paragraphs(),
url: faker.internet.url(),
});

export const stage = () => ({
export const stage = (): Stage => ({
stage_id: faker.datatype.number(),
name: faker.animal.crocodilia(),
sub_name: faker.animal.crocodilia(),
description: faker.lorem.paragraphs(),
});

export const criteria = () => ({
export const criteria = (): Criteria => ({
criteria_id: faker.datatype.number(),
type: faker.datatype.string(),
name: faker.animal.cetacean(),
Expand Down
7 changes: 1 addition & 6 deletions frontend/mocks/handlers.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import aspida from "@aspida/fetch";
import api from "../api/$api";
import { client } from "lib/client";
import { restGet } from "./rest";
import { faker } from "@faker-js/faker";
import {
Expand All @@ -13,10 +12,6 @@ import {
criteria,
} from "./faker";

const client = api(
aspida(fetch, { baseURL: process.env.NEXT_PUBLIC_API_BASE_URL })
);

export const handlers = [
restGet(client.consumer, (_req, res, ctx) => res(ctx.json(consumer()))),
restGet(client.consumer.list, (_req, res, ctx) =>
Expand Down
3 changes: 3 additions & 0 deletions frontend/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
eslint: {
dirs: ["pages", "templates", "components", "lib"],
},
};

module.exports = nextConfig;
2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
},
"scripts": {
"api": "run-s api:clean api:build",
"api:build": "openapi2aspida -i ../backend/doc/openapi.yaml",
"api:build": "openapi2aspida -i ../backend/openapi.yaml",
"api:clean": "rimraf api",
"build": "run-s api build:clean build:app",
"build:app": "next build",
Expand Down
13 changes: 0 additions & 13 deletions frontend/pages/api/hello.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import Error from "next/error";
import { client } from "lib/client";
import { Consumer, Framework, Stage, Field, BadgeDetail2 } from "api/@types";
import Template from "templates/Stage";

export type Context = {
params: { consumerId: string; frameworkId: string; stageId: string };
};

type ErrorProps = {
title: string;
statusCode: number;
};

export type Props = {
consumer: Consumer;
framework: Framework;
stages: Stage[];
stage: Stage;
fields: Field[];
wisdomBadgesMap: Map<number, BadgeDetail2[]>;
};

export async function getServerSideProps({
params: { consumerId, frameworkId, stageId },
}: Context): Promise<{ props: ErrorProps | Props }> {
const { body: consumer } = await client.consumer.get({
query: { consumer_id: Number(consumerId) },
});
const { body: framework } = await client.framework.get({
query: { framework_id: Number(frameworkId) },
});
const { body: stages } = await client.framework.stage.list.get({
query: { framework_id: Number(frameworkId) },
});
const stage = stages.find((stage) => stage.stage_id === Number(stageId));
if (!stage) return { props: { title: "Stage Not Found", statusCode: 404 } };
const { body: fields } = await client.stage.field.list.get({
query: { stage_id: Number(stageId) },
});
const wisdomBadgesMap = new Map<number, BadgeDetail2[]>();
const fieldIds = fields.flatMap(({ field1 }) =>
field1.flatMap(({ field2 }) =>
field2.flatMap(({ field3 }) => field3.flatMap(({ field_id }) => field_id))
)
);
for (const fieldId of fieldIds) {
const { body: wisdomBadges } = await client.wisdomBadges.list.get({
query: { field_id: fieldId, stage_id: Number(stageId) },
});
wisdomBadgesMap.set(fieldId, wisdomBadges.badges);
}
return {
props: { consumer, framework, stages, stage, fields, wisdomBadgesMap },
};
}

export default function Page(props: ErrorProps | Props) {
if ("statusCode" in props)
return <Error title={props.title} statusCode={props.statusCode} />;
return <Template {...props} />;
}
36 changes: 36 additions & 0 deletions frontend/pages/consumers/[consumerId]/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { client } from "lib/client";
import { Consumer, Framework, Stage } from "api/@types";
import Template from "templates/Frameworks";

export type Context = {
params: { consumerId: string };
};

export type Props = {
consumer: Consumer;
frameworks: Framework[];
stagesPerFrameworks: Stage[][];
};

export async function getServerSideProps({
params: { consumerId },
}: Context): Promise<{
props: Props;
}> {
const { body: consumer } = await client.consumer.get({
query: { consumer_id: Number(consumerId) },
});
const { body: frameworks } = await client.consumer.framework.list.get({
query: { consumer_id: Number(consumerId) },
});
const stagesPerFrameworks = await Promise.all(
frameworks.map(({ framework_id }) =>
client.framework.stage.list.get({ query: { framework_id } })
)
).then((value) => value.map((res) => res.body));
return {
props: { consumer, frameworks, stagesPerFrameworks },
};
}

export default Template;
97 changes: 27 additions & 70 deletions frontend/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,72 +1,29 @@
import type { NextPage } from "next";
import Head from "next/head";
import Image from "next/image";
import styles from "../styles/Home.module.css";

const Home: NextPage = () => {
return (
<div className={styles.container}>
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>

<main className={styles.main}>
<h1 className={styles.title}>
Welcome to <a href="https://nextjs.org">Next.js!</a>
</h1>

<p className={styles.description}>
Get started by editing{" "}
<code className={styles.code}>pages/index.tsx</code>
</p>

<div className={styles.grid}>
<a href="https://nextjs.org/docs" className={styles.card}>
<h2>Documentation &rarr;</h2>
<p>Find in-depth information about Next.js features and API.</p>
</a>

<a href="https://nextjs.org/learn" className={styles.card}>
<h2>Learn &rarr;</h2>
<p>Learn about Next.js in an interactive course with quizzes!</p>
</a>

<a
href="https://github.com/vercel/next.js/tree/canary/examples"
className={styles.card}
>
<h2>Examples &rarr;</h2>
<p>Discover and deploy boilerplate example Next.js projects.</p>
</a>

<a
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
className={styles.card}
>
<h2>Deploy &rarr;</h2>
<p>
Instantly deploy your Next.js site to a public URL with Vercel.
</p>
</a>
</div>
</main>

<footer className={styles.footer}>
<a
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Powered by{" "}
<span className={styles.logo}>
<Image src="/vercel.svg" alt="Vercel Logo" width={72} height={16} />
</span>
</a>
</footer>
</div>
);
import { client } from "lib/client";
import { Consumer, PortalCategory, BadgeDetail1 } from "api/@types";
import Template from "templates/Top";

export type Props = {
articles: { title: string; slug: string }[];
recommendedWisdomBadgesList: BadgeDetail1[];
learningContents: { name: string; url: string }[];
consumers: Consumer[];
portalCategories: PortalCategory[];
};

export default Home;
export async function getServerSideProps(): Promise<{
props: Props;
}> {
const { body: consumers } = await client.consumer.list.get();
const { body: portalCategories } = await client.portalCategory.list.get();
return {
props: {
articles: [],
recommendedWisdomBadgesList: [],
learningContents: [],
consumers,
portalCategories,
},
};
}

export default Template;
Loading

0 comments on commit cd131ef

Please sign in to comment.