Organizations page shows a set of links

This commit is contained in:
Matt Aitken
2022-12-08 11:19:58 +00:00
parent 5c53c8c904
commit 7f0b2e8005
6 changed files with 64 additions and 15 deletions
+24
View File
@@ -0,0 +1,24 @@
import type { Organization } from ".prisma/client";
import { useMatchesData } from "~/utils";
function isOrganization(org: any): org is Organization {
return org && typeof org === "object" && typeof org.title === "string";
}
function isOrganizations(orgs: any): orgs is Organization[] {
return (
orgs &&
typeof orgs === "object" &&
Array.isArray(orgs) &&
orgs.every(isOrganization)
);
}
export function useOrganizations(): Organization[] | undefined {
const data = useMatchesData("routes/__app", true);
if (!data || !isOrganizations(data.organizations)) {
return undefined;
}
return data.organizations;
}
@@ -13,6 +13,13 @@ export function getOrganizationFromSlug({
});
}
export function getOrganizations({ userId }: { userId: User["id"] }) {
return prisma.organization.findMany({
where: { users: { some: { id: userId } } },
orderBy: { createdAt: "desc" },
});
}
export async function createFirstOrganization(user: User) {
//We want the slug to be based on their name if they have one, otherwise their email
let desiredSlug = user.name ? slug(user.name) : slug(user.email);
+9 -5
View File
@@ -1,21 +1,25 @@
import { Outlet } from "@remix-run/react";
import type { LoaderArgs } from "@remix-run/server-runtime";
import { typedjson } from "remix-typedjson";
import type { UseDataFunctionReturn } from "remix-typedjson/dist/remix";
import { getOrganizations } from "~/models/organization.server";
import { clearRedirectTo, commitSession } from "~/services/redirectTo.server";
import { requireUserId } from "~/services/session.server";
export type LoaderData = UseDataFunctionReturn<typeof loader>;
export const loader = async ({ request }: LoaderArgs) => {
const userId = await requireUserId(request);
const organizations = await getOrganizations({ userId });
export async function loader({ request }: LoaderArgs) {
return typedjson(
{},
{
organizations,
},
{
headers: {
"Set-Cookie": await commitSession(await clearRedirectTo(request)),
},
}
);
}
};
export default function AppLayout() {
return (
+18 -9
View File
@@ -1,18 +1,27 @@
import type { LoaderArgs } from "@remix-run/server-runtime";
import { typedjson } from "remix-typedjson";
import { Link } from "@remix-run/react";
import { Header } from "~/components/Header";
export const loader = async ({ request }: LoaderArgs) => {
return typedjson({});
};
import { useOrganizations } from "~/hooks/useOrganizations";
export default function AppLayout() {
const organizations = useOrganizations();
return (
<>
<Header>Home</Header>
<div className="flex h-screen flex-col overflow-auto">
adsadsdasasd asads asa dsa ds ads
</div>
<ul className="flex h-screen flex-col overflow-auto">
{organizations ? (
organizations.map((organization) => (
<li key={organization.id}>
<Link to={`orgs/${organization.slug}`}>{organization.title}</Link>
</li>
))
) : (
<li>No organizations</li>
)}
<li>
<Link to="orgs/new">Create a new organization</Link>
</li>
</ul>
</>
);
}
+6 -1
View File
@@ -32,9 +32,14 @@ export function safeRedirect(
* @returns {JSON|undefined} The router data or undefined if not found
*/
export function useMatchesData(
id: string
id: string,
debug: boolean = false
): Record<string, unknown> | undefined {
const matchingRoutes = useMatches();
if (debug) {
console.log("matchingRoutes", matchingRoutes);
}
const route = useMemo(
() => matchingRoutes.find((route) => route.id === id),
[matchingRoutes, id]