Skip to content

Instantly share code, notes, and snippets.

@ryanflorence
Created January 28, 2022 14:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ryanflorence/d7a03bb136a4c8cef68168a1f696366d to your computer and use it in GitHub Desktop.
Save ryanflorence/d7a03bb136a4c8cef68168a1f696366d to your computer and use it in GitHub Desktop.
import { useEffect, useRef } from "react";
import {
Form,
useFetcher,
useLoaderData,
useTransition,
} from "remix";
import { arc } from "~/arc.server";
export async function loader() {
let db = await arc.tables();
return db.people.scan();
}
export async function action({ request }) {
let db = await arc.tables();
let formData = await request.formData();
let { _action, ...values } = Object.fromEntries(formData);
if (_action === "create") {
return db.people.put({
...values,
createdAt: new Date().toISOString(),
id: Math.random().toString(32).slice(2),
});
}
if (_action === "delete") {
return db.people.delete(values);
}
}
export default function People() {
let people = useLoaderData().Items;
let transition = useTransition();
let isAdding =
transition.submission &&
transition.submission.formData.get("_action") === "create";
let formRef = useRef();
let firstNameRef = useRef();
useEffect(() => {
if (!isAdding) {
formRef.current?.reset();
firstNameRef.current?.focus();
}
}, [isAdding]);
return (
<main>
<h1>People</h1>
<ul>
{people.sort(byCreatedAt).map((person) => (
<PersonItem person={person} key={person.id} />
))}
<li>
<Form ref={formRef} replace method="post">
<input
ref={firstNameRef}
type="text"
name="firstName"
/>{" "}
<input type="text" name="lastName" />{" "}
<button
disabled={isAdding}
type="submit"
name="_action"
value="create"
>
{isAdding ? "Adding..." : "Add"}
</button>
</Form>
</li>
</ul>
</main>
);
}
function PersonItem({ person }) {
let fetcher = useFetcher();
let isDeleting =
fetcher.submission?.formData.get("id") === person.id;
return (
<li
style={{
opacity: isDeleting ? 0.25 : 1,
}}
key={person.id}
>
{person.firstName} {person.lastName}{" "}
<fetcher.Form
replace
style={{
display: "inline",
}}
method="post"
>
<input type="hidden" name="id" value={person.id} />
<input
type="hidden"
name="createdAt"
value={person.createdAt}
/>
<button
type="submit"
aria-label="delete"
name="_action"
value="delete"
>
</button>
</fetcher.Form>
</li>
);
}
let byCreatedAt = (a, b) =>
new Date(a.createdAt) - new Date(b.createdAt);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment