Skip to content

Commit

Permalink
Merge pull request #186 from sohosai/impl-#32
Browse files Browse the repository at this point in the history
WIP: `/committee/forms` の実装 (骨組みだけ)
  • Loading branch information
appare45 authored Apr 14, 2024
2 parents dbd069a + f59213f commit dddfd3f
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 4 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

89 changes: 89 additions & 0 deletions src/app/committee/forms/FormsList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { css } from "@styled-system/css";
import Link from "next/link";
import dayjs from "dayjs";
import { FC } from "react";

import { components } from "@/schema";

import { NoResultNotice } from "@/components/NoResultNotice";
import { getCommitteeTimeLeftText, getFormStatus } from "@/lib/formHelpers";
import { FormStatusBadge } from "@/components/FormStatusBadge";

type Form = components["schemas"]["FormSummary"];

export const FormsList: FC<{
forms: Form[];
}> = ({ forms }) => {
return (
<div>
<div
className={css({
width: "full",
display: "grid",
justifyContent: "flex-end",
})}>
<Link href="/committee/forms/new">+ 新規作成</Link>
</div>
<div
className={css({
width: "full",
display: "grid",
alignItems: "center",
gridTemplateColumns: "1fr 1fr 1fr 3fr 2fr",
"& > * > *": {
pr: 4,
lineHeight: 2,
},
})}>
<div
className={css({
display: "contents",
color: "gray.500",
fontSize: "sm",
"& > *": {
borderColor: "gray.500",
borderBottom: "1px solid",
},
})}>
<div>状態</div>
<div>配信日</div>
<div>締切日</div>
<div>タイトル</div>
<div>締切まで</div>
</div>
{forms.length == 0 && (
<div className={css({ gridColumn: "1/7" })}>
<NoResultNotice message="申請はありません" />
</div>
)}
{forms.map((form) => {
const startsAt = dayjs(form.starts_at);
const endsAt = dayjs(form.ends_at);
const status = getFormStatus(dayjs(), startsAt, endsAt);

return (
<div
key={form.id}
className={css({
display: "contents",
})}>
<Link
href={`/committee/forms/${form.id}`}
className={css({
display: "contents",
})}>
<div className={css({ paddingBlock: 2 })}>
<FormStatusBadge status={status} />
</div>
<div>{startsAt.format("YYYY/MM/DD")}</div>
<div>{endsAt.format("YYYY/MM/DD")}</div>
<div>{form.title}</div>
<div>{getCommitteeTimeLeftText(dayjs(), endsAt)}</div>
</Link>
</div>
);
})}
</div>
</div>
);
};
47 changes: 46 additions & 1 deletion src/app/committee/forms/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,54 @@
"use client";

import { css } from "@styled-system/css";
import { NextPage } from "next";
import { FormsList } from "./FormsList";
import { stack } from "@styled-system/patterns";
import { assignType } from "@/lib/openapi";
import useSWR from "swr";

const DashboardPage: NextPage = () => {
return <></>;
const { data: formsRes, error, isLoading } = useSWR(() => `/forms`);
const forms = formsRes ? assignType("/forms", formsRes) : undefined;

if (isLoading) {
return <div>Loading...</div>;
}

if (error || !forms) {
return (
<p>
申請の取得中にエラーが発生しました
<span>({String(error)})</span>
</p>
);
}

return (
<>
<div
className={css({
padding: 5,
maxWidth: "900px",
marginInline: "auto",
})}>
<div>
<h2
className={css({
fontSize: "xl",
fontWeight: "bold",
display: "flex",
gap: 1,
})}>
申請一覧
</h2>
</div>
<div className={stack({ padding: 10, gap: 4, alignItems: "flex-start", width: "100%" })}>
<FormsList forms={forms} />
</div>
</div>
</>
);
};

export default DashboardPage;
5 changes: 3 additions & 2 deletions src/app/forms/FormsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import Image from "next/image";
import { hiddenFormIdsAtom } from "./hiddenFormIds";
import toast from "react-hot-toast";
import { NoResultNotice } from "@/components/NoResultNotice";
import Link from "next/link";

type Form = components["schemas"]["FormSummary"];
type Answer = components["schemas"]["FormAnswerSummary"];
Expand Down Expand Up @@ -94,7 +95,7 @@ export const FormsList: FC<{
}}>
{isShown ? <Image src={EyesClosedIcon} alt="非表示" /> : <Image src={EyesOpenIcon} alt="表示" />}
</button>
<a
<Link
href={`/forms/${form.id}`}
className={css({
display: "contents",
Expand All @@ -106,7 +107,7 @@ export const FormsList: FC<{
<div>{endsAt.format("YYYY/MM/DD")}</div>
<div>{form.title}</div>
<div>{getTimeLeftText(dayjs(), endsAt, status)}</div>
</a>
</Link>
</div>
);
})}
Expand Down
38 changes: 38 additions & 0 deletions src/components/FormStatusBadge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { formStatus } from "@/lib/formHelpers";
import { cva, cx } from "@styled-system/css";

type Props = {
status: formStatus;
className?: string;
};

export const FormStatusBadge = ({ status, className }: Props) => {
const formStatus = cva({
base: {
borderRadius: "md",
paddingInline: 3,
paddingBlock: 1,
width: "fit-content",
lineHeight: 1.5,
},
variants: {
status: {
受付終了: {
backgroundColor: "gray.200",
color: "black",
},
開始前: {
backgroundColor: "sohosai.blue",
color: "white",
},
受付中: {
backgroundColor: "sohosai.orange",
color: "white",
},
不明: {},
},
},
});

return <span className={cx(formStatus({ status }), className)}>{status}</span>;
};
5 changes: 5 additions & 0 deletions src/lib/formHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,8 @@ export const getTimeLeftText = (now: dayjs.Dayjs, deadline: dayjs.Dayjs, status:
const diff = getTimeLeft(now, deadline);
return status === "未提出" ? (diff >= 0 ? `残り${diff}日` : "締切を過ぎています") : "";
};

export const getCommitteeTimeLeftText = (now: dayjs.Dayjs, deadline: dayjs.Dayjs) => {
const diff = getTimeLeft(now, deadline);
return diff >= 0 ? `残り${diff}日` : "締切を過ぎています";
};

0 comments on commit dddfd3f

Please sign in to comment.