Skip to content

Commit

Permalink
Merge pull request #415 from sohosai/fix-#414
Browse files Browse the repository at this point in the history
fix#414
  • Loading branch information
appare45 authored Aug 14, 2024
2 parents 6a98f55 + 33254bf commit 1e5f232
Show file tree
Hide file tree
Showing 15 changed files with 651 additions and 228 deletions.
18 changes: 14 additions & 4 deletions src/app/committee/forms/[form_id]/FormDetailedView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,13 @@ export const FormDetailedView: React.FC<{ form: components["schemas"]["Form"] }>
const { data, isLoading, error } = useSWR(`/form-answers?form_id=${form.id}`);
const answers = assignType("/form-answers", data);
const { user } = useAuthState();
const { data: data_user, isLoading: isLoading_user } = useSWR("/users/me");
const me = assignType("/users/me", data_user);
if (isLoading) return;
if (error) return `エラーが発生しました${error}`;

return (
<div className={vstack({ gap: 4, alignItems: "start", width: "full" })}>
<div className={vstack({ gap: 4, alignItems: "start", width: "full", marginBottom: "20px" })}>
<div className={hstack({ justifyContent: "space-between", width: "full", flexWrap: "wrap" })}>
<div>
作成日: <time dateTime={form.created_at}> {dayjs(form.created_at).format("YYYY/MM/DD")}</time>
Expand Down Expand Up @@ -81,9 +83,13 @@ export const FormDetailedView: React.FC<{ form: components["schemas"]["Form"] }>
);
}}
/>
<Link href={`/committee/forms/${form.id}/edit`} className={buttonStyle({ color: "blue", visual: "outline" })}>
編集
</Link>
{!isLoading && !isLoading_user && (answers.length == 0 || ["administrator"].includes(me.role)) && (
<Link
href={`/committee/forms/${form.id}/edit`}
className={buttonStyle({ color: "blue", visual: "outline" })}>
編集
</Link>
)}
<button
className={buttonStyle({ visual: "outline", color: "purple" })}
onClick={() =>
Expand Down Expand Up @@ -176,6 +182,9 @@ export const FormDetailedView: React.FC<{ form: components["schemas"]["Form"] }>
width: "full",
rowGap: 3,
})}>
<div className={css({ borderBottom: "2px solid black", width: "full" })}>
<h2 className={css({ fontSize: "lg", fontWeight: "bold", marginBottom: 3 })}>設問</h2>
</div>
<FormItems
items={form.items}
getValues={getValues}
Expand All @@ -185,6 +194,7 @@ export const FormDetailedView: React.FC<{ form: components["schemas"]["Form"] }>
files={new Map()}
setFiles={setState}
setFileErrors={setFileErrors}
disabled={true}
/>
</form>
<FormAnswerList answers={answers} deadline={form.ends_at} />
Expand Down
65 changes: 62 additions & 3 deletions src/app/committee/forms/[form_id]/edit/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import { stack } from "@styled-system/patterns";
import { css } from "@styled-system/css";
import dayjs from "dayjs";
import { useRouter } from "next/navigation";
import Link from "next/link";
import { Button } from "@/recipes/button";

export const runtime = "edge";

Expand All @@ -27,8 +29,44 @@ const EditFormPage: NextPage<{ params: { form_id: string } }> = ({ params }) =>
return `/forms/` + params.form_id;
});

const {
error: answerError,
data: asnwerData,
isLoading: answerLoading,
} = useSWR(`/form-answers?form_id=${params.form_id}`);

if (answerLoading) {
return (
<div
className={css({
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "85vh",
})}>
<p>読み込み中...</p>
</div>
);
} else if (answerError && answerError.name !== "form-answer/form-not-found") {
return (
<div>
Error! <p>{JSON.stringify(answerError)}</p>
</div>
);
}

if (isLoading) {
return <div>Loading...</div>;
return (
<div
className={css({
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "85vh",
})}>
<p>読み込み中...</p>
</div>
);
}

if (error) {
Expand Down Expand Up @@ -78,7 +116,7 @@ const EditFormPage: NextPage<{ params: { form_id: string } }> = ({ params }) =>
{
loading: "申請を更新しています",
success: () => {
router.push("/committee/forms");
router.push(`/committee/forms/${params.form_id}`);
return "申請を更新しました";
},
error: "申請の更新に失敗しました",
Expand All @@ -95,14 +133,35 @@ const EditFormPage: NextPage<{ params: { form_id: string } }> = ({ params }) =>
padding: 5,
gap: 4,
})}>
<Link
href={`/committee/forms/${params.form_id}`}
className={css({ color: "tsukuba.purple", display: "block" })}>
← 申請詳細に戻る
</Link>
<h1
className={css({
fontSize: "2xl",
fontWeight: "bold",
})}>
申請編集
</h1>
<FormEditor onSubmit={onSubmit} defaultValues={defaultValues} />
<FormEditor
onSubmit={onSubmit}
editable={!answerLoading && !answerError && asnwerData.length === 0}
defaultValues={defaultValues}
/>
{!(!answerLoading && !answerError && asnwerData.length === 0) && (
<Link href={`/committee/forms/${params.form_id}`}>
<Button
visual="solid"
color="purple"
className={css({
alignSelf: "center",
})}>
戻る
</Button>
</Link>
)}
</div>
</>
);
Expand Down
12 changes: 11 additions & 1 deletion src/app/committee/forms/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,17 @@ const DashboardPage: NextPage = () => {
const forms = formsRes ? assignType("/forms", formsRes) : undefined;

if (isLoading) {
return <div>Loading...</div>;
return (
<div
className={css({
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "85vh",
})}>
<p>読み込み中...</p>
</div>
);
}

if (error || !forms) {
Expand Down
31 changes: 18 additions & 13 deletions src/app/committee/news/[news_id]/edit/EditNewsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import { useRouter } from "next/navigation";
import { ProjectCategorySelector } from "@/common_components/ProjectCategorySelector";
import { TitleField } from "@/common_components/news/TitleField";
import { BodyField } from "@/common_components/news/BodyField";
import { FilesField } from "@/common_components/formFields/Files";
import { FileErrorsType, FilesFormType } from "@/common_components/form_answer/FormItems";
import { deleteAllUploadedFiles, postFiles } from "@/lib/postFile";
import { FilesField } from "@/common_components/form_editor/FilesEditor";
import { filesStatus } from "@/common_components/form_editor/FilesInterfaces";
import { FileErrorsType } from "@/common_components/form_answer/FormItems";

export const EditNewsForm: FC<{
news_id: string;
Expand All @@ -34,8 +34,9 @@ export const EditNewsForm: FC<{
resolver: valibotResolver(UpdateNewsSchema),
});

const [attachments, setAttachments] = useState<FilesFormType>(new Map([["attachments", null]]));
const [filesStatus, setFilesStatus] = useState<filesStatus[]>([]);
const [fileErrors, setFileErrors] = useState<FileErrorsType>(new Map([["attachments", null]]));
type FileIds = { [itemId: string]: string[] };

const { data, error, isLoading, mutate } = useSWR(`/news/${news_id}`);
if (isLoading) {
Expand All @@ -54,21 +55,27 @@ export const EditNewsForm: FC<{

if (!isFormInitialized) {
setIsFormInitialized(true);
const fileDatas =
news.attachments.map((uuid) => ({
name: null,
uuid: uuid,
uploaded: true,
})) ?? [];
setFilesStatus(fileDatas);
reset({
title: news.title,
body: news.body,
categories: news.categories,
});
}

const onSubmit = async (data: UpdateNewsSchemaType) => {
if (fileErrors.get("attachments")) {
toast.error("添付ファイルを正しく選択してください");
return;
}
const fileIds = await postFiles("public", attachments);
// 企画区分が未選択の場合はfalseが渡される
let fileIds: FileIds = { attachments: filesStatus.map((fileStatus) => fileStatus.uuid) };
const categories = data.categories === false ? projectCategories : data.categories;

await toast.promise(
client
.PUT(`/news/{news_id}`, {
Expand All @@ -78,12 +85,11 @@ export const EditNewsForm: FC<{
body: data.body,
categories: categories as components["schemas"]["ProjectCategory"][],
attributes: [...projectAttributes] as components["schemas"]["ProjectAttribute"][],
attachments: fileIds ? fileIds["attachments"] ?? [] : [],
attachments: fileIds["attachments"] ?? [],
},
})
.then(({ error }) => {
if (error) {
fileIds && deleteAllUploadedFiles(fileIds);
throw error;
}
mutate();
Expand All @@ -92,14 +98,12 @@ export const EditNewsForm: FC<{
{
loading: "お知らせを保存しています",
error: () => {
fileIds && deleteAllUploadedFiles(fileIds);
return "お知らせの保存中にエラーが発生しました";
},
success: "お知らせを保存しました",
},
);
};

return (
<form onSubmit={handleSubmit(onSubmit)} className={stack({ gap: 4 })}>
<div
Expand Down Expand Up @@ -129,11 +133,12 @@ export const EditNewsForm: FC<{
<TitleField register={register("title")} error={errors.title?.message} />
<BodyField register={register("body")} error={errors.body?.message} />
<FilesField
label="添付ファイル"
register={register("attachments")}
id="attachments"
label="添付ファイル"
filesStatus={filesStatus}
setFilesStatus={setFilesStatus}
setErrorState={setFileErrors}
setFiles={setAttachments}
/>
<div className={center()}>
<Button
Expand Down
22 changes: 11 additions & 11 deletions src/app/committee/news/new/NewNewsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ import toast from "react-hot-toast";
import { ProjectCategorySelector } from "@/common_components/ProjectCategorySelector";
import { TitleField } from "@/common_components/news/TitleField";
import { BodyField } from "@/common_components/news/BodyField";
import { FilesField } from "@/common_components/formFields/Files";
import { useState } from "react";
import { FileErrorsType, FilesFormType } from "@/common_components/form_answer/FormItems";
import { deleteAllUploadedFiles, postFiles } from "@/lib/postFile";
import { FileErrorsType } from "@/common_components/form_answer/FormItems";
import { FilesField } from "@/common_components/form_editor/FilesEditor";
import { filesStatus } from "@/common_components/form_editor/FilesInterfaces";

export const NewNewsForm = () => {
const router = useRouter();
Expand All @@ -28,16 +28,16 @@ export const NewNewsForm = () => {
mode: "onBlur",
resolver: valibotResolver(NewNewsSchema),
});
const [attachments, setAttachments] = useState<FilesFormType>(new Map([["attachments", null]]));
const [filesStatus, setFilesStatus] = useState<filesStatus[]>([]);
const [fileErrors, setFileErrors] = useState<FileErrorsType>(new Map([["attachments", null]]));
type FileIds = { [itemId: string]: string[] };

const onSubmit = async (data: NewNewsSchemaType) => {
if (fileErrors.get("attachments")) {
toast.error("添付ファイルを正しく選択してください");
return;
}
const fileIds = await postFiles("public", attachments);
// 企画区分が未選択の場合はfalseが渡される
let fileIds: FileIds = { attachments: filesStatus.map((fileStatus) => fileStatus.uuid) };
const categories = data.categories === false ? projectCategories : data.categories;

await toast.promise(
Expand All @@ -48,12 +48,11 @@ export const NewNewsForm = () => {
body: data.body,
categories: categories as components["schemas"]["ProjectCategory"][],
attributes: [...projectAttributes] as components["schemas"]["ProjectAttribute"][],
attachments: fileIds ? fileIds["attachments"] ?? [] : [],
attachments: fileIds["attachments"] ?? [],
},
})
.then(({ data, error }) => {
if (error) {
fileIds && deleteAllUploadedFiles(fileIds);
throw error;
}
router.push(`/committee/news/${data.id}`);
Expand Down Expand Up @@ -95,11 +94,12 @@ export const NewNewsForm = () => {
<TitleField register={register("title")} error={errors.title?.message} />
<BodyField register={register("body")} error={errors.body?.message} />
<FilesField
id="attachments"
setFiles={setAttachments}
setErrorState={setFileErrors}
label="添付ファイル"
register={register("attachments")}
id="attachments"
filesStatus={filesStatus}
setFilesStatus={setFilesStatus}
setErrorState={setFileErrors}
/>
</form>
);
Expand Down
4 changes: 4 additions & 0 deletions src/assets/FileView/file.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/assets/FileView/image.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 1e5f232

Please sign in to comment.