diff --git a/src/Components/GoalModal/GoalModal.tsx b/src/Components/GoalModal/GoalModal.tsx index 96bb4d4..44939af 100644 --- a/src/Components/GoalModal/GoalModal.tsx +++ b/src/Components/GoalModal/GoalModal.tsx @@ -24,7 +24,7 @@ export default function GoalModal() { event.preventDefault(); const postData: Goal = { - userId: user ? user.uid : "", + userId: user?.uid as string, text: text, deadline: new Date(dueDate), }; @@ -95,7 +95,7 @@ export default function GoalModal() { aria-describedby="create-goal-description" > 目標を作成 - 自分の目標を入力してください. + 目標を入力してください
(null); - const [imageUrl, setImageUrl] = useState(""); - const [text, setText] = useState(""); - const [error, setError] = useState(""); - const [progress, setProgress] = useState(100); - const { user } = useUser(); - - const handleImageChange = (event: ChangeEvent) => { - const selectedFile = event.target.files?.[0]; - setImage(selectedFile || null); - setError(""); - }; - - const handleTextChange = (event: ChangeEvent) => { - setText(event.target.value); - }; - - const handleUpload = () => { - if (!image) { - setError("ファイルが選択されていません"); - return; - } - - // アップロード開始 - uploadImage( - image, - (percent) => setProgress(percent), - (errorMsg) => setError(errorMsg), - async (url, hash) => { - setImageUrl(url); - console.log("Image is save at:", url); - console.log("Generated storage path hash:", hash); - - const postData: Post = { - userId: user ? user.uid : "", - storedId: url, // TODO: トークン管理ができるまではurlをそのまま管理 - text: text, - goalId: "temp", // TODO: 実際のgoalIdを入れる - submittedAt: new Date(), - }; - - try { - const response = await fetch(`${functionsEndpoint}/post/`, { - method: "POST", - headers: { - "X-Firebase-AppCheck": appCheckToken, - "Content-Type": "application/json", - }, - body: JSON.stringify(postData), - }); - - if (!response.ok) { - throw new Error("データの送信に失敗しました"); - } - - setProgress(100); // アップロード完了の進捗を表示 - const data = await response.json(); - console.log("Success:", data); - } catch (err) { - setError("データの送信に失敗しました"); - console.error(err); - } - } - ); - }; - - return ( -
- 投稿内容を入力 - {error && {error}} - - - - - - - - {progress !== 100 && } - - {imageUrl && ( - - アップロード完了: - - )} -
- ); -} - -interface LinearProgressWithLabelProps { - value: number; -} - -const LinearProgressWithLabel: React.FC = ({ - value, -}) => { - return ( - - - - - - {`${Math.round( - value - )}%`} - - - ); -}; diff --git a/src/Components/PostModal/PostModal.tsx b/src/Components/PostModal/PostModal.tsx new file mode 100644 index 0000000..f86807f --- /dev/null +++ b/src/Components/PostModal/PostModal.tsx @@ -0,0 +1,181 @@ +"use client"; +import { appCheckToken, functionsEndpoint } from "@/app/firebase"; +import { Post } from "@/types/types"; +import { uploadImage } from "@/utils/Uploader"; +import { useUser } from "@/utils/UserContext"; +import { Add } from "@mui/icons-material"; +import { + Button, + DialogContent, + DialogTitle, + Input, + Modal, + ModalDialog, + Stack, +} from "@mui/joy"; +import Box from "@mui/material/Box"; +import LinearProgress from "@mui/material/LinearProgress"; +import Typography from "@mui/material/Typography"; +import React, { ChangeEvent, useState } from "react"; + +export default function PostModal({ goalId }: { goalId: string }) { + const [open, setOpen] = useState(false); + const [text, setText] = useState(""); + const [image, setImage] = useState(null); + const [error, setError] = useState(""); + const [progress, setProgress] = useState(100); + const { user } = useUser(); + + const handleTextChange = (event: ChangeEvent) => { + setText(event.target.value); + }; + + const handleImageChange = (event: ChangeEvent) => { + const selectedFile = event.target.files?.[0]; + setImage(selectedFile || null); + setError(""); + }; + + const handleUpload = () => { + if (!image) { + setError("ファイルが選択されていません"); + return; + } + + uploadImage( + image, + (percent) => setProgress(percent), + (errorMsg) => setError(errorMsg), + async (url) => { + const postData: Post = { + userId: user?.uid as string, + storedId: url, + text: text, + goalId: goalId, + submittedAt: new Date(), + }; + + try { + const response = await fetch(`${functionsEndpoint}/post/`, { + method: "POST", + headers: { + "X-Firebase-AppCheck": appCheckToken, + "Content-Type": "application/json", + }, + body: JSON.stringify(postData), + }); + + if (!response.ok) { + throw new Error("データの送信に失敗しました"); + } + + setProgress(100); + const data = await response.json(); + console.log("Post created:", data); + + setImage(null); + setText(""); + setOpen(false); + } catch (err) { + setError("データの送信に失敗しました"); + console.error(err); + } + } + ); + }; + + // 以下のJoy UIによるエラーを無効化 + try { + const consoleError = console.error; + console.error = (...args) => { + if (args[0]?.includes("Accessing element.ref was removed")) { + return; + } + consoleError(...args); + }; + } catch { + console.error("Failed to disable Joy UI error"); + } + + return ( + <> + + + setOpen(false)} + keepMounted + disablePortal + > + + 完了投稿を作成 + 投稿コメントと画像を入れてください + e.preventDefault()}> + + {error && {error}} + + + {progress !== 100 && } + + + + + + + + + + ); +} + +interface LinearProgressWithLabelProps { + value: number; +} + +const LinearProgressWithLabel: React.FC = ({ + value, +}) => { + return ( + + + + + + {`${Math.round( + value + )}%`} + + + ); +}; diff --git a/src/Components/Progress/Progress.tsx b/src/Components/Progress/Progress.tsx index ef66fce..0222ce9 100644 --- a/src/Components/Progress/Progress.tsx +++ b/src/Components/Progress/Progress.tsx @@ -14,6 +14,7 @@ import Stepper from "@mui/joy/Stepper"; import Typography, { typographyClasses } from "@mui/joy/Typography"; import { Divider } from "@mui/material"; import { ReactNode, useEffect, useState } from "react"; +import PostModal from "../PostModal/PostModal"; interface ProgressProps { successResults?: SuccessResult[]; @@ -188,6 +189,7 @@ const pendingStep = (result: GoalWithId, userName: string) => { goalText={result.text} resultType="pending" /> + ); diff --git a/src/app/page.tsx b/src/app/page.tsx index 0dc78a4..3f610a6 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,7 +1,6 @@ "use client"; import DashBoard from "@/Components/DashBoard/DashBoard"; import GoalModal from "@/Components/GoalModal/GoalModal"; -import PostForm from "@/Components/PostForm/PostForm"; import { requestPermission, revokePermission, @@ -12,7 +11,6 @@ export default function Top() { return ( <> -