Spaces:
Sleeping
Sleeping
import { | |
Form, | |
Outlet, | |
useLoaderData, | |
redirect, | |
NavLink, | |
useNavigation, | |
useSubmit, | |
} from "react-router-dom"; | |
import { createContact, getContacts } from "../contacts"; | |
import { useEffect } from "react"; | |
import { useAuth } from "../providers/AuthProvider"; | |
export async function loader({ request }) { | |
const url = new URL(request.url); | |
const q = url.searchParams.get("q"); | |
const contacts = await getContacts(q); | |
return { contacts, q }; | |
} | |
export async function action() { | |
const contact = await createContact(); | |
return redirect(`/contacts/${contact.id}/edit`); | |
} | |
export default function Root() { | |
const { contacts, q } = useLoaderData(); | |
const navigation = useNavigation(); | |
const submit = useSubmit(); | |
const { user } = useAuth(); | |
const searching = | |
navigation.location && | |
new URLSearchParams(navigation.location.search).has("q"); | |
useEffect(() => { | |
document.getElementById("q").value = q; | |
}, [q]); | |
return ( | |
<> | |
<div id="sidebar"> | |
<h1>React Router Contacts</h1> | |
<div> | |
<Form id="search-form" role="search"> | |
<input | |
id="q" | |
className={searching ? "loading" : ""} | |
aria-label="Search contacts" | |
placeholder="Search" | |
type="search" | |
name="q" | |
defaultValue={q} | |
onChange={(event) => { | |
const isFirstSearch = q == null; | |
submit(event.currentTarget.form, { | |
replace: !isFirstSearch, | |
}); | |
}} | |
/> | |
<div id="search-spinner" aria-hidden hidden={!searching} /> | |
<div className="sr-only" aria-live="polite"></div> | |
</Form> | |
<Form method="post"> | |
<button type="submit">New</button> | |
</Form> | |
</div> | |
<nav> | |
<ul> | |
{contacts.length ? ( | |
<ul> | |
{contacts.map((contact) => ( | |
<li key={contact.id}> | |
<NavLink | |
to={`contacts/${contact.id}`} | |
className={({ isActive, isPending }) => | |
isActive ? "active" : isPending ? "pending" : "" | |
} | |
> | |
{contact.first || contact.last ? ( | |
<> | |
{contact.first} {contact.last} | |
</> | |
) : ( | |
<i>No Name</i> | |
)}{" "} | |
{contact.favorite && <span>★</span>} | |
</NavLink> | |
</li> | |
))} | |
</ul> | |
) : ( | |
<p> | |
<i>No contacts</i> | |
</p> | |
)} | |
</ul> | |
</nav> | |
</div> | |
<div | |
id="detail" | |
className={navigation.state === "loading" ? "loading" : ""} | |
> | |
<p>Un mensaje {user.name}</p> | |
<Outlet /> | |
</div> | |
</> | |
); | |
} | |