master
Raw Download raw file
 1import { DateTime } from "luxon";
 2import React from "react";
 3import { Navigate, useNavigate } from "react-router-dom";
 4
 5import { Callout } from "./Callout";
 6import { useMySecrets } from "./useMySecrets";
 7import { useUser } from "./useUser";
 8
 9import styles from "./CreateSecret.module.scss";
10
11export const CreateSecret = () => {
12	const { user } = useUser();
13	const { createSecret } = useMySecrets();
14	const navigate = useNavigate();
15	const [name, setName] = React.useState("");
16	const [secret, setSecret] = React.useState("");
17	const [revealAt, setRevealAt] = React.useState(DateTime.now().toFormat("yyyy-MM-dd'T'HH:mm"));
18	const [submitting, setSubmitting] = React.useState(false);
19	const [failed, setFailed] = React.useState(false);
20	const [now, setNow] = React.useState(DateTime.now());
21
22	React.useEffect(() => {
23		const interval = setInterval(() => {
24			setNow(DateTime.now());
25		}, 250);
26		return () => clearInterval(interval);
27	});
28
29	if (user.loading) {
30		return <div>Loading...</div>;
31	} else if (user.value === undefined) {
32		return <Navigate to="/login" />;
33	}
34
35	const revealTimeValid = DateTime.fromISO(revealAt) > now;
36
37	return (
38		<>
39			<h1>Create Secret</h1>
40			<form
41				className={styles.form}
42				onSubmit={async (e) => {
43					e.preventDefault();
44					if (submitting) {
45						return;
46					}
47					setSubmitting(true);
48					try {
49						const id = await createSecret(name, secret, DateTime.fromISO(revealAt));
50						navigate(`/secret/${id}`);
51					} catch (error) {
52						setFailed(true);
53						setSubmitting(false);
54					}
55				}}
56			>
57				{failed && <Callout>Failed to create secret</Callout>}
58				<label>
59					<span>Name</span>
60					<input type="text" value={name} onChange={(e) => setName(e.target.value)} />
61				</label>
62				<label>
63					<span>Secret</span>
64					<input type="text" value={secret} onChange={(e) => setSecret(e.target.value)} />
65				</label>
66				<label>
67					<span>Reveal At</span>
68					<input type="datetime-local" value={revealAt} onChange={(e) => setRevealAt(e.target.value)} />
69				</label>
70				<label>
71					<span></span>
72					{revealTimeValid ? (
73						<span className={styles.relative}>{DateTime.fromISO(revealAt).toRelative()}</span>
74					) : (
75						<span className={styles.relative + " " + styles.error}>Reveal time must be in the future</span>
76					)}
77				</label>
78				<input type="submit" value="Create" disabled={!revealTimeValid} />
79			</form>
80		</>
81	);
82};