Skip to content

Commit

Permalink
Merge pull request #91 from MurakawaTakuya/feat/81-link-post-button-t…
Browse files Browse the repository at this point in the history
…o-goal

目標に投稿ボタンを追加して完了投稿をリンクして作成する機能を実装
  • Loading branch information
MurakawaTakuya authored Dec 6, 2024
2 parents 9118090 + ec1cda0 commit 94d9b52
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 133 deletions.
4 changes: 2 additions & 2 deletions src/Components/GoalModal/GoalModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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),
};
Expand Down Expand Up @@ -95,7 +95,7 @@ export default function GoalModal() {
aria-describedby="create-goal-description"
>
<DialogTitle>目標を作成</DialogTitle>
<DialogContent>自分の目標を入力してください.</DialogContent>
<DialogContent>目標を入力してください</DialogContent>
<form onSubmit={handleSubmit}>
<Stack spacing={2} sx={{ mt: 2 }}>
<Input
Expand Down
129 changes: 0 additions & 129 deletions src/Components/PostForm/PostForm.tsx

This file was deleted.

181 changes: 181 additions & 0 deletions src/Components/PostModal/PostModal.tsx
Original file line number Diff line number Diff line change
@@ -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<string>("");
const [image, setImage] = useState<File | null>(null);
const [error, setError] = useState<string>("");
const [progress, setProgress] = useState<number>(100);
const { user } = useUser();

const handleTextChange = (event: ChangeEvent<HTMLInputElement>) => {
setText(event.target.value);
};

const handleImageChange = (event: ChangeEvent<HTMLInputElement>) => {
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 (
<>
<Button
variant="outlined"
color="primary"
startDecorator={<Add />}
onClick={() => setOpen(true)}
disabled={!user || user?.loginType === "Guest"}
>
写真を撮って完了する
</Button>

<Modal
open={open}
onClose={() => setOpen(false)}
keepMounted
disablePortal
>
<ModalDialog
aria-labelledby="create-post-title"
aria-describedby="create-post-description"
>
<DialogTitle>完了投稿を作成</DialogTitle>
<DialogContent>投稿コメントと画像を入れてください</DialogContent>
<form onSubmit={(e) => e.preventDefault()}>
<Stack spacing={2} sx={{ mt: 2 }}>
{error && <Typography color="error">{error}</Typography>}
<Input
type="text"
value={text}
onChange={handleTextChange}
placeholder="投稿コメントを入力して下さい"
required
/>
<input type="file" onChange={handleImageChange} />
{progress !== 100 && <LinearProgressWithLabel value={progress} />}
<Stack direction="row" spacing={1} justifyContent="flex-end">
<Button
variant="plain"
color="neutral"
onClick={() => setOpen(false)}
>
Cancel
</Button>
<Button
type="submit"
variant="solid"
color="primary"
disabled={!user || user?.loginType === "Guest"}
onClick={handleUpload}
>
投稿
</Button>
</Stack>
</Stack>
</form>
</ModalDialog>
</Modal>
</>
);
}

interface LinearProgressWithLabelProps {
value: number;
}

const LinearProgressWithLabel: React.FC<LinearProgressWithLabelProps> = ({
value,
}) => {
return (
<Box display="flex" alignItems="center">
<Box width="100%" mr={1}>
<LinearProgress variant="determinate" value={value} />
</Box>
<Box minWidth={35}>
<Typography variant="body2" color="textSecondary">{`${Math.round(
value
)}%`}</Typography>
</Box>
</Box>
);
};
2 changes: 2 additions & 0 deletions src/Components/Progress/Progress.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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[];
Expand Down Expand Up @@ -188,6 +189,7 @@ const pendingStep = (result: GoalWithId, userName: string) => {
goalText={result.text}
resultType="pending"
/>
<PostModal goalId={result.goalId} />
</Step>
</StepperBlock>
);
Expand Down
2 changes: 0 additions & 2 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -12,7 +11,6 @@ export default function Top() {
return (
<>
<DashBoard />
<PostForm />
<GoalModal />
<Button variant="contained" onClick={requestPermission}>
通知を受信
Expand Down

0 comments on commit 94d9b52

Please sign in to comment.