Remove redundant files

This commit is contained in:
Simon Gruber
2026-03-29 16:09:25 +02:00
parent 86ac1b2205
commit 8f8f6b9dea
2 changed files with 0 additions and 297 deletions
-69
View File
@@ -1,69 +0,0 @@
import React, { useState } from "react";
import { UserOutlined } from "@ant-design/icons";
import { Button, Card, Flex, Popover, Space, Tooltip, Typography } from "antd";
import AccountSettingsPopoverContent from "./AccountSettingsPopoverContent";
import ThemeModeToggle from "./utils/ThemeModeToggle";
const { Text } = Typography;
export default function TopNav({
themeMode,
onThemeChange,
onHome,
userEmail,
onUserEmailChange,
}: {
themeMode: "light" | "dark";
onThemeChange: (mode: "light" | "dark") => void;
onHome: () => void;
userEmail: string;
onUserEmailChange: (nextUserEmail: string) => void | Promise<string>;
}) {
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
return (
<Card size="small">
<Flex justify="space-between" align="center" wrap="wrap" gap={12}>
<Button
type="text"
onClick={onHome}
aria-label="Go to home"
style={{ paddingInline: 0 }}
>
<Text style={{ fontSize: 18 }} strong>
Lunchtime
</Text>
</Button>
<Space size={8} align="center">
<ThemeModeToggle
themeMode={themeMode}
onThemeChange={onThemeChange}
/>
<Popover
trigger="click"
placement="bottomRight"
open={isPopoverOpen}
onOpenChange={setIsPopoverOpen}
content={
<AccountSettingsPopoverContent
userEmail={userEmail}
onUserEmailChange={onUserEmailChange}
/>
}
>
<Tooltip title="Account settings">
<Button
type="text"
shape="circle"
icon={<UserOutlined />}
aria-label="User settings"
/>
</Tooltip>
</Popover>
</Space>
</Flex>
</Card>
);
}
@@ -1,228 +0,0 @@
import React, { useEffect, useMemo, useRef, useState } from "react";
import { Alert, Button, Flex, Form, Input, Modal, Space, Typography } from "antd";
import ThemeModeToggle from "./utils/ThemeModeToggle";
type ThemeMode = "light" | "dark";
type EmailLookupState = "idle" | "checking" | "exists" | "new";
export default function WelcomeOnboardingModal({
open,
themeMode,
onThemeChange,
onCheckAccountExists,
onCreateAccount,
onMigrateAccount,
}: {
open: boolean;
themeMode: ThemeMode;
onThemeChange: (mode: ThemeMode) => void;
onCheckAccountExists: (email: string) => Promise<boolean>;
onCreateAccount: (email: string) => void | Promise<void>;
onMigrateAccount: (email: string) => void | Promise<void>;
}) {
const [form] = Form.useForm<{ email: string }>();
const [lookupState, setLookupState] = useState<EmailLookupState>("idle");
const [isSubmitting, setIsSubmitting] = useState(false);
const [hasSentEmail, setHasSentEmail] = useState(false);
const lookupTimerRef = useRef<number | null>(null);
const lookupRequestIdRef = useRef(0);
const normalizeEmail = (email: string) => email.trim().toLowerCase();
const isValidEmail = (email: string) =>
/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
const resolveAccountExists = async (email: string) => {
const normalized = normalizeEmail(email);
if (!normalized || !isValidEmail(normalized)) {
setLookupState("idle");
return null;
}
const requestId = ++lookupRequestIdRef.current;
setLookupState("checking");
try {
const exists = await onCheckAccountExists(normalized);
if (requestId !== lookupRequestIdRef.current) {
return null;
}
setLookupState(exists ? "exists" : "new");
return exists;
} catch {
if (requestId === lookupRequestIdRef.current) {
setLookupState("idle");
}
return null;
}
};
useEffect(() => {
if (!open) {
form.resetFields();
setLookupState("idle");
setIsSubmitting(false);
setHasSentEmail(false);
lookupRequestIdRef.current += 1;
if (lookupTimerRef.current) {
window.clearTimeout(lookupTimerRef.current);
lookupTimerRef.current = null;
}
}
}, [form, open]);
useEffect(
() => () => {
if (lookupTimerRef.current) {
window.clearTimeout(lookupTimerRef.current);
}
},
[],
);
const buttonLabel = useMemo(() => {
if (hasSentEmail) {
return "Email sent";
}
if (lookupState === "exists") {
return "Migrate account";
}
if (lookupState === "checking") {
return "Checking account...";
}
if (lookupState === "new") {
return "Create new account";
}
return "Continue";
}, [hasSentEmail, lookupState]);
const isLookupResolved = lookupState === "exists" || lookupState === "new";
const helperText = useMemo(() => {
if (lookupState === "exists") {
return "Log in using this email.";
}
if (lookupState === "new") {
return "Register using this email.";
}
return "";
}, [lookupState]);
return (
<Modal
open={open}
maskClosable={false}
keyboard={false}
closable={false}
footer={null}
centered
>
<Space direction="vertical" size={14} style={{ width: "100%" }}>
<Flex align="center" justify="space-between" style={{ width: "100%" }}>
<Typography.Title level={4} style={{ margin: 0 }}>
Welcome to Lunchtime
</Typography.Title>
<ThemeModeToggle themeMode={themeMode} onThemeChange={onThemeChange} />
</Flex>
<Typography.Paragraph style={{ marginBottom: 6 }}>
Enter your account email to continue. We'll automatically detect whether to create a new account or migrate an existing one.
</Typography.Paragraph>
<Form
form={form}
layout="vertical"
onValuesChange={(_changedValues, values) => {
if (hasSentEmail) {
return;
}
const currentEmail = String(values.email || "");
if (lookupTimerRef.current) {
window.clearTimeout(lookupTimerRef.current);
lookupTimerRef.current = null;
}
lookupTimerRef.current = window.setTimeout(() => {
void resolveAccountExists(currentEmail);
}, 350);
}}
onFinish={async (values) => {
if (hasSentEmail) {
return;
}
const normalizedEmail = normalizeEmail(values.email);
setIsSubmitting(true);
try {
let exists = lookupState === "exists";
if (lookupState !== "exists" && lookupState !== "new") {
const checked = await resolveAccountExists(normalizedEmail);
exists = checked === true;
}
if (exists) {
await onMigrateAccount(normalizedEmail);
} else {
await onCreateAccount(normalizedEmail);
}
setHasSentEmail(true);
} finally {
setIsSubmitting(false);
}
}}
>
<Form.Item
label="Email"
name="email"
rules={[
{ required: true, message: "Email cannot be empty." },
{ type: "email", message: "Enter a valid email address." },
]}
extra={helperText || undefined}
>
<Input
placeholder="alex@example.com"
autoFocus
maxLength={320}
disabled={hasSentEmail}
/>
</Form.Item>
{hasSentEmail ? (
<Alert
type="info"
showIcon
description="Email sent! Please check your inbox and spam folder for the confirmation email."
/>
) : null}
{hasSentEmail ? (
<Button
type="link"
onClick={() => {
setHasSentEmail(false);
setLookupState("idle");
}}
style={{ paddingInline: 0 }}
>
Change email
</Button>
) : null}
<Button
type="primary"
htmlType="submit"
block
loading={!hasSentEmail && (isSubmitting || lookupState === "checking")}
disabled={hasSentEmail || !isLookupResolved}
>
{buttonLabel}
</Button>
</Form>
</Space>
</Modal>
);
}