protect /setup and use links for button

This commit is contained in:
Milo Schwartz 2024-11-26 20:30:52 -05:00
parent 7c9e57ef12
commit 41e531306d
No known key found for this signature in database
11 changed files with 48 additions and 63 deletions

View file

@ -1,4 +1,4 @@
import { render } from "@react-email/components"; import { render } from "@react-email/render";
import { ReactElement } from "react"; import { ReactElement } from "react";
import emailClient from "@server/emails"; import emailClient from "@server/emails";
import logger from "@server/logger"; import logger from "@server/logger";
@ -21,7 +21,9 @@ export async function sendEmail(
return; return;
} }
logger.debug("Rendering email templatee...")
const emailHtml = await render(template); const emailHtml = await render(template);
logger.debug("Done rendering email templatee")
const options = { const options = {
from: opts.from, from: opts.from,

View file

@ -76,7 +76,7 @@ export function RolesDataTable<TData, TValue>({
} }
className="w-full pl-8" className="w-full pl-8"
/> />
<Search className="h-5 w-5 absolute left-2 top-1/2 transform -translate-y-1/2" /> <Search className="h-4 w-4 absolute left-2 top-1/2 transform -translate-y-1/2" />
</div> </div>
<Button <Button
onClick={() => { onClick={() => {

View file

@ -76,7 +76,7 @@ export function UsersDataTable<TData, TValue>({
} }
className="w-full pl-8" className="w-full pl-8"
/> />
<Search className="h-5 w-5 absolute left-2 top-1/2 transform -translate-y-1/2" /> <Search className="h-4 w-4 absolute left-2 top-1/2 transform -translate-y-1/2" />
</div> </div>
<Button <Button
onClick={() => { onClick={() => {

View file

@ -116,7 +116,10 @@ export default function UsersTable({ users: u }: UsersTableProps) {
<> <>
<div className="flex items-center justify-end"> <div className="flex items-center justify-end">
{userRow.isOwner && ( {userRow.isOwner && (
<Button variant="ghost" className="opacity-0 cursor-default"> <Button
variant="ghost"
className="opacity-0 cursor-default"
>
Placeholder Placeholder
</Button> </Button>
)} )}
@ -161,18 +164,17 @@ export default function UsersTable({ users: u }: UsersTableProps) {
)} )}
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenu> </DropdownMenu>
<Link
href={`/${org?.org.orgId}/settings/access/users/${userRow.id}`}
>
<Button <Button
variant={"gray"} variant={"gray"}
className="ml-2" className="ml-2"
onClick={() =>
router.push(
`/${org?.org.orgId}/settings/access/users/${userRow.id}`,
)
}
> >
Manage{" "} Manage
<ArrowRight className="ml-2 w-4 h-4" /> <ArrowRight className="ml-2 w-4 h-4" />
</Button> </Button>
</Link>
</> </>
)} )}
</div> </div>

View file

@ -149,7 +149,7 @@ export default function Header({ email, orgId, name, orgs }: HeaderProps) {
size="lg" size="lg"
role="combobox" role="combobox"
aria-expanded={open} aria-expanded={open}
className="w-full md:w-[200px] h-12 px-3 py-4 bg-neutral hover:bg-muted" className="w-full md:w-[200px] h-12 px-3 py-4 bg-neutral hover:bg-neutral"
> >
<div className="flex items-center justify-between w-full"> <div className="flex items-center justify-between w-full">
<div className="flex flex-col items-start"> <div className="flex flex-col items-start">
@ -202,29 +202,6 @@ export default function Header({ email, orgId, name, orgs }: HeaderProps) {
</Command> </Command>
</PopoverContent> </PopoverContent>
</Popover> </Popover>
{/* <Select
defaultValue={orgId}
onValueChange={(val) => {
router.push(`/${val}/settings`);
}}
>
<SelectTrigger className="w-[100px] md:w-[180px]">
<SelectValue placeholder="Select an org" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
{orgs.map((org) => (
<SelectItem
value={org.name}
key={org.orgId}
>
{org.name}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select> */}
</div> </div>
</div> </div>
</> </>

View file

@ -77,7 +77,7 @@ export function ResourcesDataTable<TData, TValue>({
} }
className="w-full pl-8" className="w-full pl-8"
/> />
<Search className="h-5 w-5 absolute left-2 top-1/2 transform -translate-y-1/2" /> <Search className="h-4 w-4 absolute left-2 top-1/2 transform -translate-y-1/2" />
</div> </div>
<Button <Button
onClick={() => { onClick={() => {

View file

@ -253,17 +253,14 @@ export default function SitesTable({ resources, orgId }: ResourcesTableProps) {
</DropdownMenuItem> </DropdownMenuItem>
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenu> </DropdownMenu>
<Button <Link
variant={"gray"} href={`/${resourceRow.orgId}/settings/resources/${resourceRow.id}`}
className="ml-2"
onClick={() =>
router.push(
`/${resourceRow.orgId}/settings/resources/${resourceRow.id}`,
)
}
> >
Edit <ArrowRight className="ml-2 w-4 h-4" /> <Button variant={"gray"} className="ml-2">
Edit
<ArrowRight className="ml-2 w-4 h-4" />
</Button> </Button>
</Link>
</div> </div>
</> </>
); );

View file

@ -77,7 +77,7 @@ export function SitesDataTable<TData, TValue>({
} }
className="w-full pl-8" className="w-full pl-8"
/> />
<Search className="h-5 w-5 absolute left-2 top-1/2 transform -translate-y-1/2" /> <Search className="h-4 w-4 absolute left-2 top-1/2 transform -translate-y-1/2" />
</div> </div>
<Button <Button
onClick={() => { onClick={() => {

View file

@ -202,17 +202,14 @@ export default function SitesTable({ sites, orgId }: SitesTableProps) {
</DropdownMenuItem> </DropdownMenuItem>
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenu> </DropdownMenu>
<Button <Link
variant={"gray"} href={`/${siteRow.orgId}/settings/sites/${siteRow.nice}`}
className="ml-2"
onClick={() =>
router.push(
`/${siteRow.orgId}/settings/sites/${siteRow.nice}`,
)
}
> >
Edit <ArrowRight className="ml-2 w-4 h-4" /> <Button variant={"gray"} className="ml-2">
Edit
<ArrowRight className="ml-2 w-4 h-4" />
</Button> </Button>
</Link>
</div> </div>
); );
}, },

View file

@ -1,4 +1,7 @@
import { verifySession } from "@app/lib/auth/verifySession";
import { Metadata } from "next"; import { Metadata } from "next";
import { redirect } from "next/navigation";
import { cache } from "react";
export const metadata: Metadata = { export const metadata: Metadata = {
title: `Setup - Pangolin`, title: `Setup - Pangolin`,
@ -10,5 +13,12 @@ export default async function SetupLayout({
}: { }: {
children: React.ReactNode; children: React.ReactNode;
}) { }) {
const getUser = cache(verifySession);
const user = await getUser();
if (!user) {
redirect("/");
}
return <div className="mt-32">{children}</div>; return <div className="mt-32">{children}</div>;
} }

View file

@ -44,7 +44,7 @@ export default function StepperForm() {
const debouncedCheckOrgIdAvailability = useCallback( const debouncedCheckOrgIdAvailability = useCallback(
debounce(checkOrgIdAvailability, 300), debounce(checkOrgIdAvailability, 300),
[checkOrgIdAvailability] [checkOrgIdAvailability],
); );
useEffect(() => { useEffect(() => {
@ -278,7 +278,7 @@ export default function StepperForm() {
function debounce<T extends (...args: any[]) => any>( function debounce<T extends (...args: any[]) => any>(
func: T, func: T,
wait: number wait: number,
): (...args: Parameters<T>) => void { ): (...args: Parameters<T>) => void {
let timeout: NodeJS.Timeout | null = null; let timeout: NodeJS.Timeout | null = null;