mirror of
https://gitlab.com/MisterBiggs/hello-remix.git
synced 2025-06-15 13:06:40 +00:00
113 lines
2.9 KiB
TypeScript
113 lines
2.9 KiB
TypeScript
import type { LinksFunction } from "@remix-run/node";
|
|
import {
|
|
Form,
|
|
Link,
|
|
Links,
|
|
Meta,
|
|
NavLink,
|
|
Outlet,
|
|
Scripts,
|
|
ScrollRestoration,
|
|
useLoaderData,
|
|
useNavigation,
|
|
} from "@remix-run/react";
|
|
|
|
import { redirect } from "@remix-run/node";
|
|
|
|
import appStylesHref from "./app.css?url"
|
|
import { getContacts, createEmptyContact } from "./data";
|
|
|
|
export const links: LinksFunction = () => [
|
|
{ rel: "stylesheet", href: appStylesHref },
|
|
];
|
|
|
|
export const action = async () => {
|
|
const contact = await createEmptyContact();
|
|
return redirect(`/contacts/${contact.id}/edit`)
|
|
}
|
|
|
|
export const loader = async () => {
|
|
const contacts = await getContacts();
|
|
return { contacts };
|
|
};
|
|
|
|
export default function App() {
|
|
const { contacts } = useLoaderData<typeof loader>();
|
|
const navigation = useNavigation();
|
|
|
|
return (
|
|
<html lang="en">
|
|
<head>
|
|
<meta charSet="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<Meta />
|
|
<Links />
|
|
</head>
|
|
<body>
|
|
<div id="sidebar">
|
|
<h1>Remix Contacts</h1>
|
|
<div>
|
|
<Form id="search-form" role="search">
|
|
<input
|
|
id="q"
|
|
aria-label="Search contacts"
|
|
placeholder="Search"
|
|
type="search"
|
|
name="q"
|
|
/>
|
|
<div id="search-spinner" aria-hidden hidden={true} />
|
|
</Form>
|
|
<Form method="post">
|
|
<button type="submit">New</button>
|
|
</Form>
|
|
</div>
|
|
<nav>
|
|
{contacts.length ? (
|
|
<ul>
|
|
{contacts.map((contact) => (
|
|
<li key={contact.id}> <NavLink
|
|
className={({ isActive, isPending }) =>
|
|
isActive
|
|
? "active"
|
|
: isPending
|
|
? "pending"
|
|
: ""
|
|
}
|
|
to={`contacts/${contact.id}`}
|
|
>
|
|
<Link to={`contacts/${contact.id}`}>
|
|
{contact.first || contact.last ? (
|
|
<>
|
|
{contact.first} {contact.last}
|
|
</>
|
|
) : (
|
|
<i>No Name</i>
|
|
)}{" "}
|
|
{contact.favorite ? (
|
|
<span>★</span>
|
|
) : null}
|
|
</Link>
|
|
</NavLink>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
) : (
|
|
<p>
|
|
<i>No contacts</i>
|
|
</p>
|
|
)}
|
|
</nav>
|
|
</div>
|
|
<div className={
|
|
navigation.state === "loading" ? "loading" : ""
|
|
} id="detail">
|
|
<Outlet />
|
|
</div>
|
|
|
|
<ScrollRestoration />
|
|
<Scripts />
|
|
</body>
|
|
</html>
|
|
);
|
|
}
|