diff --git a/src/Components/Account/AuthForm.tsx b/src/Components/Account/AuthForm.tsx index 7a38ce6..e114896 100644 --- a/src/Components/Account/AuthForm.tsx +++ b/src/Components/Account/AuthForm.tsx @@ -3,6 +3,7 @@ import { signInWithGoogleAccount } from "@/utils/Auth/signInWithGoogleAccount"; import { signInWithMail } from "@/utils/Auth/signInWithMail"; import { signUpWithMail } from "@/utils/Auth/signUpWithMail"; import Box from "@mui/material/Box"; +import CircularProgress from "@mui/material/CircularProgress"; import Divider from "@mui/material/Divider"; import TextField from "@mui/material/TextField"; import ToggleButton from "@mui/material/ToggleButton"; @@ -23,23 +24,43 @@ export default function AuthForm() { const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [formMode, setFormMode] = useState<"register" | "login">("register"); + const [loading, setLoading] = useState(false); + const [loadingType, setLoadingType] = useState< + "Mail" | "Google" | "Guest" | null + >(null); const handleRegisterSubmit = async (event: React.FormEvent) => { event.preventDefault(); + setLoading(true); + setLoadingType("Mail"); await signUpWithMail(email, password, name); + setLoading(false); + setLoadingType(null); }; const handleLoginSubmit = async (event: React.FormEvent) => { event.preventDefault(); + setLoading(true); + setLoadingType("Mail"); await signInWithMail(email, password); + setLoading(false); + setLoadingType(null); }; const handleGoogleLogin = async () => { + setLoading(true); + setLoadingType("Google"); await signInWithGoogleAccount(); + setLoading(false); + setLoadingType(null); }; const handleGuestLogin = async () => { + setLoading(true); + setLoadingType("Guest"); await signInAsGuest(); + setLoading(false); + setLoadingType(null); }; return ( @@ -98,8 +119,20 @@ export default function AuthForm() { required autoComplete="new-password" /> - - アカウント作成 + + {loading && loadingType === "Mail" ? ( + <> + + アカウント作成 + + ) : ( + "アカウント作成" + )} @@ -133,19 +166,55 @@ export default function AuthForm() { required autoComplete="current-password" /> - - ログイン + + {loading && loadingType === "Mail" ? ( + <> + + ログイン + + ) : ( + "ログイン" + )} )} または - - Googleでログイン + + {loading && loadingType === "Google" ? ( + <> + + Googleアカウントでログイン + + ) : ( + "Googleアカウントでログイン" + )} - - ゲストログイン + + {loading && loadingType === "Guest" ? ( + <> + + ゲストログイン + + ) : ( + "ゲストログイン" + )} ); diff --git a/src/Components/PostModal/PostModal.tsx b/src/Components/PostModal/PostModal.tsx index 082565b..011351b 100644 --- a/src/Components/PostModal/PostModal.tsx +++ b/src/Components/PostModal/PostModal.tsx @@ -18,6 +18,7 @@ import { } from "@mui/joy"; import Box from "@mui/material/Box"; import MuiButton from "@mui/material/Button"; +import CircularProgress from "@mui/material/CircularProgress"; import LinearProgress from "@mui/material/LinearProgress"; import Typography from "@mui/material/Typography"; import { styled } from "@mui/material/styles"; @@ -29,6 +30,7 @@ export default function PostModal({ goalId }: { goalId: string }) { const [image, setImage] = useState(null); const [progress, setProgress] = useState(100); const [fileName, setFileName] = useState(""); + const [loading, setLoading] = useState(false); const { user } = useUser(); const handleTextChange = (event: ChangeEvent) => { @@ -37,11 +39,18 @@ export default function PostModal({ goalId }: { goalId: string }) { const handleImageChange = (event: ChangeEvent) => { const selectedFile = event.target.files?.[0]; + if (selectedFile && !selectedFile.type.startsWith("image/")) { + showSnackBar({ + message: "画像ファイルのみアップロードできます", + type: "warning", + }); + return; + } setImage(selectedFile || null); setFileName(selectedFile ? selectedFile.name : ""); }; - const handleUpload = () => { + const handleUpload = async () => { if (!image) { showSnackBar({ message: "ファイルが選択されていません", @@ -50,8 +59,10 @@ export default function PostModal({ goalId }: { goalId: string }) { return; } + setLoading(true); + try { - uploadImage( + await uploadImage( image, (percent) => setProgress(percent), async (url) => { @@ -78,6 +89,7 @@ export default function PostModal({ goalId }: { goalId: string }) { setText(""); setOpen(false); setFileName(""); + setLoading(false); } catch (error: unknown) { console.error("Error creating post:", error); const message = handleCreatePostError(error); @@ -85,6 +97,7 @@ export default function PostModal({ goalId }: { goalId: string }) { message, type: "warning", }); + setLoading(false); } } ); @@ -94,6 +107,7 @@ export default function PostModal({ goalId }: { goalId: string }) { message: "画像のアップロードに失敗しました", type: "warning", }); + setLoading(false); } }; @@ -169,13 +183,14 @@ export default function PostModal({ goalId }: { goalId: string }) { variant="contained" tabIndex={-1} startIcon={} - sx={{ margin: "20px auto 0 !important", height: "40px" }} + sx={{ margin: "16px auto 0 !important", height: "40px" }} > {fileName ? fileName : "画像をアップロード"} @@ -195,8 +210,16 @@ export default function PostModal({ goalId }: { goalId: string }) { color="primary" endDecorator={} onClick={handleUpload} + disabled={loading} > - 投稿 + {loading ? ( + <> + + 投稿中 + + ) : ( + "投稿" + )} @@ -216,8 +239,11 @@ const LinearProgressWithLabel: React.FC = ({ }) => { return ( <> - アップロード中... - + diff --git a/src/utils/Auth/signInWithGoogleAccount.ts b/src/utils/Auth/signInWithGoogleAccount.ts index a41b7ae..d76be42 100644 --- a/src/utils/Auth/signInWithGoogleAccount.ts +++ b/src/utils/Auth/signInWithGoogleAccount.ts @@ -33,8 +33,13 @@ export const signInWithGoogleAccount = async () => { } catch (error) { console.error("errorCode:", (error as Error)?.name); console.error("errorMessage:", (error as Error)?.message); + let message = + "Googleアカウントでのログインに失敗しました。ページを更新して再度お試しください。"; + if ((error as Error)?.message.includes("auth/popup-closed-by-user")) { + message = "ログインがキャンセルされました"; + } showSnackBar({ - message: "Googleアカウントでのログインに失敗しました", + message, type: "warning", }); } diff --git a/src/utils/Auth/signInWithMail.ts b/src/utils/Auth/signInWithMail.ts index 4dee55e..b524a17 100644 --- a/src/utils/Auth/signInWithMail.ts +++ b/src/utils/Auth/signInWithMail.ts @@ -9,8 +9,8 @@ import { signInWithEmailAndPassword } from "firebase/auth"; * @param {string} password * @return {*} */ -export const signInWithMail = (email: string, password: string) => { - signInWithEmailAndPassword(auth, email, password) +export const signInWithMail = async (email: string, password: string) => { + await signInWithEmailAndPassword(auth, email, password) .then(() => { showSnackBar({ message: "メールでログインしました", diff --git a/src/utils/Auth/signUpWithMail.tsx b/src/utils/Auth/signUpWithMail.tsx index 776a803..c5c0ce8 100644 --- a/src/utils/Auth/signUpWithMail.tsx +++ b/src/utils/Auth/signUpWithMail.tsx @@ -15,13 +15,13 @@ import { * @param {string} password * @param {string} name */ -export const signUpWithMail = ( +export const signUpWithMail = async ( email: string, password: string, name: string ) => { // メールは初回ログインの時のみ成功する、2回目以降はエラーになるので、ログインを使う - createUserWithEmailAndPassword(auth, email, password) + await createUserWithEmailAndPassword(auth, email, password) .then(async (userCredential) => { const user = userCredential.user;