Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ログイン試行中にログインボタンをローディングにする #122

Merged
merged 2 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 77 additions & 8 deletions src/Components/Account/AuthForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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 (
Expand Down Expand Up @@ -98,8 +119,20 @@ export default function AuthForm() {
required
autoComplete="new-password"
/>
<RoundedButton type="submit" variant="contained" fullWidth>
アカウント作成
<RoundedButton
type="submit"
variant="contained"
fullWidth
disabled={loading}
>
{loading && loadingType === "Mail" ? (
<>
<CircularProgress size={24} sx={{ marginRight: 1 }} />
アカウント作成
</>
) : (
"アカウント作成"
)}
</RoundedButton>
</Box>
</form>
Expand Down Expand Up @@ -133,19 +166,55 @@ export default function AuthForm() {
required
autoComplete="current-password"
/>
<RoundedButton type="submit" variant="contained" fullWidth>
ログイン
<RoundedButton
type="submit"
variant="contained"
fullWidth
disabled={loading}
>
{loading && loadingType === "Mail" ? (
<>
<CircularProgress size={24} sx={{ marginRight: 1 }} />
ログイン
</>
) : (
"ログイン"
)}
</RoundedButton>
</Box>
</form>
</>
)}
<Divider>または</Divider>
<RoundedButton fullWidth variant="outlined" onClick={handleGoogleLogin}>
Googleでログイン
<RoundedButton
fullWidth
variant="outlined"
onClick={handleGoogleLogin}
disabled={loading}
>
{loading && loadingType === "Google" ? (
<>
<CircularProgress size={24} sx={{ marginRight: 1 }} />
Googleアカウントでログイン
</>
) : (
"Googleアカウントでログイン"
)}
</RoundedButton>
<RoundedButton fullWidth variant="outlined" onClick={handleGuestLogin}>
ゲストログイン
<RoundedButton
fullWidth
variant="outlined"
onClick={handleGuestLogin}
disabled={loading}
>
{loading && loadingType === "Guest" ? (
<>
<CircularProgress size={24} sx={{ marginRight: 1 }} />
ゲストログイン
</>
) : (
"ゲストログイン"
)}
</RoundedButton>
</>
);
Expand Down
38 changes: 32 additions & 6 deletions src/Components/PostModal/PostModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -29,6 +30,7 @@ export default function PostModal({ goalId }: { goalId: string }) {
const [image, setImage] = useState<File | null>(null);
const [progress, setProgress] = useState<number>(100);
const [fileName, setFileName] = useState<string>("");
const [loading, setLoading] = useState<boolean>(false);
const { user } = useUser();

const handleTextChange = (event: ChangeEvent<HTMLInputElement>) => {
Expand All @@ -37,11 +39,18 @@ export default function PostModal({ goalId }: { goalId: string }) {

const handleImageChange = (event: ChangeEvent<HTMLInputElement>) => {
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: "ファイルが選択されていません",
Expand All @@ -50,8 +59,10 @@ export default function PostModal({ goalId }: { goalId: string }) {
return;
}

setLoading(true);

try {
uploadImage(
await uploadImage(
image,
(percent) => setProgress(percent),
async (url) => {
Expand All @@ -78,13 +89,15 @@ 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);
showSnackBar({
message,
type: "warning",
});
setLoading(false);
}
}
);
Expand All @@ -94,6 +107,7 @@ export default function PostModal({ goalId }: { goalId: string }) {
message: "画像のアップロードに失敗しました",
type: "warning",
});
setLoading(false);
}
};

Expand Down Expand Up @@ -169,13 +183,14 @@ export default function PostModal({ goalId }: { goalId: string }) {
variant="contained"
tabIndex={-1}
startIcon={<AddAPhotoIcon />}
sx={{ margin: "20px auto 0 !important", height: "40px" }}
sx={{ margin: "16px auto 0 !important", height: "40px" }}
>
<FileName>
{fileName ? fileName : "画像をアップロード"}
</FileName>
<VisuallyHiddenInput
type="file"
accept="image/*"
onChange={handleImageChange}
multiple
/>
Expand All @@ -195,8 +210,16 @@ export default function PostModal({ goalId }: { goalId: string }) {
color="primary"
endDecorator={<SendIcon />}
onClick={handleUpload}
disabled={loading}
>
投稿
{loading ? (
<>
<CircularProgress size={24} sx={{ marginRight: 1 }} />
投稿中
</>
) : (
"投稿"
)}
</JoyButton>
</Stack>
</Stack>
Expand All @@ -216,8 +239,11 @@ const LinearProgressWithLabel: React.FC<LinearProgressWithLabelProps> = ({
}) => {
return (
<>
<Typography>アップロード中...</Typography>
<Box display="flex" alignItems="center" sx={{ margin: "0 !important" }}>
<Box
display="flex"
alignItems="center"
sx={{ marginTop: "16px !important" }}
>
<Box width="100%" mr={1}>
<LinearProgress variant="determinate" value={value} />
</Box>
Expand Down
7 changes: 6 additions & 1 deletion src/utils/Auth/signInWithGoogleAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",
});
}
Expand Down
4 changes: 2 additions & 2 deletions src/utils/Auth/signInWithMail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: "メールでログインしました",
Expand Down
4 changes: 2 additions & 2 deletions src/utils/Auth/signUpWithMail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
Loading