-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
cf9830a
commit 9d220ed
Showing
9 changed files
with
281 additions
and
95 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,12 +7,6 @@ export const RootDocument: FC<PropsWithChildren<{ title: string }>> = ({ title, | |
<meta charset="UTF-8"></meta> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"></meta> | ||
<title>{title}</title> | ||
<script | ||
src="https://unpkg.com/[email protected]" | ||
integrity="sha384-D1Kt99CQMDuVetoL1lrYwg5t+9QdHe7NLX/SoJYkXDFfX37iInKRy5xLSi8nO7UC" | ||
crossorigin="anonymous" | ||
></script> | ||
<script src="https://unpkg.com/htmx.org/dist/ext/json-enc.js"></script> | ||
<script src="https://cdn.tailwindcss.com"></script> | ||
</head> | ||
<body class="bg-gray-50 dark:bg-gray-900">{children}</body> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import type { FC } from "hono/jsx"; | ||
import type { User } from "lucia"; | ||
|
||
import { RootDocument } from "../layouts/root-document.js"; | ||
import { Card } from "../components/card.js"; | ||
import { getButtonStyles } from "../components/button.js"; | ||
import { dateFormatter } from "../utils/date.mjs"; | ||
|
||
import type { TenantRecord } from "@/types/db.mjs"; | ||
|
||
export const DashboardLandingPage: FC<{ | ||
user: User; | ||
tenants: Array<TenantRecord>; | ||
}> = ({ user, tenants }) => { | ||
const githubId = user.githubId; | ||
const githubMessage = | ||
user && githubId ? `, ${user.username} with a github id of "${githubId}"` : " user with no github-id"; | ||
|
||
return ( | ||
<RootDocument title="Simple Logging Server"> | ||
<section class="mx-auto max-w-7xl h-full grid place-items-center px-2"> | ||
<Card class="lg:max-w-2xl w-full"> | ||
<div class="p-4"> | ||
<h2 class="text-2xl lg:text-3xl font-semibold pb-2 text-gray-900">Welcome!!!</h2> | ||
<p class="lg:text-sm pb-2 text-gray-700">{`Hello${githubMessage}`}</p> | ||
<a class={getButtonStyles("secondary", "xs")} href="/app/logout"> | ||
Logout 👋🏼 | ||
</a> | ||
</div> | ||
<div class="border-t overflow-hidden"> | ||
<table class="min-w-full divide-y divide-gray-300"> | ||
<thead class="bg-gray-50"> | ||
<tr> | ||
<th | ||
scope="col" | ||
class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6 lg:pl-8" | ||
> | ||
Name | ||
</th> | ||
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900"> | ||
Created at | ||
</th> | ||
<th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-6 lg:pr-8"> | ||
<span class="sr-only">Edit</span> | ||
</th> | ||
</tr> | ||
</thead> | ||
<tbody class="divide-y divide-gray-200 bg-white"> | ||
{tenants.map((tenant) => ( | ||
<tr> | ||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6 lg:pl-8"> | ||
<a | ||
href={`/app/${tenant.workspace}`} | ||
class="text-indigo-600 hover:text-indigo-900 hover:underline" | ||
> | ||
{tenant.name} | ||
</a> | ||
</td> | ||
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500"> | ||
{dateFormatter.humanReadable(tenant.createdAt)} | ||
</td> | ||
<td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8"> | ||
<a href={`/app/${tenant.workspace}/edit`} class="text-indigo-600 hover:text-indigo-900"> | ||
Edit<span class="sr-only">, {tenant.name}</span> | ||
</a> | ||
</td> | ||
</tr> | ||
))} | ||
</tbody> | ||
</table> | ||
</div> | ||
</Card> | ||
</section> | ||
</RootDocument> | ||
); | ||
}; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import type { FC } from "hono/jsx"; | ||
|
||
import { RootDocument } from "../layouts/root-document.js"; | ||
import { Card } from "../components/card.js"; | ||
import { getButtonStyles } from "../components/button.js"; | ||
import { dateFormatter } from "../utils/date.mjs"; | ||
|
||
import type { ServiceRecord, TenantRecord } from "@/types/db.mjs"; | ||
|
||
export const WorkspaceLandingPage: FC<{ | ||
tenant: TenantRecord; | ||
services: Array<ServiceRecord>; | ||
}> = ({ tenant, services }) => { | ||
return ( | ||
<RootDocument title="Simple Logging Server"> | ||
<section class="mx-auto max-w-7xl h-full grid place-items-center px-2"> | ||
<Card class="lg:max-w-2xl w-full"> | ||
<div class="p-4"> | ||
<h2 class="text-2xl lg:text-3xl font-semibold pb-2 text-gray-900">{tenant.name}</h2> | ||
<p class="lg:text-sm pb-2 text-gray-700">These are the services for {tenant.name}</p> | ||
<div class="flex gap-1"> | ||
<a class={getButtonStyles("secondary", "xs")} href="/app/logout"> | ||
Logout 👋🏼 | ||
</a> | ||
<a class={getButtonStyles("secondary", "xs")} href={`/app/${tenant.workspace}/edit`}> | ||
Edit ✏️ | ||
</a> | ||
</div> | ||
</div> | ||
<div class="border-t overflow-hidden"> | ||
<table class="min-w-full divide-y divide-gray-300"> | ||
<thead class="bg-gray-50"> | ||
<tr> | ||
<th | ||
scope="col" | ||
class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6 lg:pl-8" | ||
> | ||
Service name | ||
</th> | ||
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900"> | ||
Created at | ||
</th> | ||
<th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-6 lg:pr-8"> | ||
<span class="sr-only">Edit</span> | ||
</th> | ||
</tr> | ||
</thead> | ||
<tbody class="divide-y divide-gray-200 bg-white"> | ||
{services.map((service) => ( | ||
<tr> | ||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6 lg:pl-8"> | ||
<a | ||
href={`/app/${tenant.workspace}/${service.name}`} | ||
class="text-indigo-600 hover:text-indigo-900 hover:underline" | ||
> | ||
{service.name} | ||
</a> | ||
</td> | ||
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500"> | ||
{dateFormatter.humanReadable(new Date(service.createdAt))} | ||
</td> | ||
<td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8"> | ||
<a | ||
href={`/app/${tenant.workspace}/${service.id}/edit`} | ||
class="text-indigo-600 hover:text-indigo-900" | ||
> | ||
Edit<span class="sr-only">, {service.name}</span> | ||
</a> | ||
</td> | ||
</tr> | ||
))} | ||
</tbody> | ||
</table> | ||
</div> | ||
</Card> | ||
</section> | ||
</RootDocument> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
function intlDateFormatter(date: Date) { | ||
return new Intl.DateTimeFormat(undefined, { | ||
year: "numeric", | ||
month: "long", | ||
day: "numeric", | ||
hour: "numeric", | ||
minute: "numeric", | ||
second: "numeric", | ||
}).format(date); | ||
} | ||
|
||
export const dateFormatter = { | ||
humanReadable: intlDateFormatter, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { createMiddleware } from "hono/factory"; | ||
import { HTTPException } from "hono/http-exception"; | ||
|
||
import { db } from "@/config/db/index.mjs"; | ||
|
||
import type { ServerContext } from "@/types/hono.mjs"; | ||
|
||
export const checkUserAuthed = createMiddleware<ServerContext>(async (c, next) => { | ||
const user = c.var.user; | ||
|
||
if (!user) { | ||
return c.redirect("/app/login"); | ||
} | ||
|
||
return await next(); | ||
}); | ||
|
||
export const checkTenantMembership = createMiddleware<ServerContext>(async (c, next) => { | ||
const userId = c.var.user!.id; | ||
const workspace = c.req.param("workspace"); | ||
|
||
const tenant = await db.query.tenants.findFirst({ | ||
where: (fields, { eq }) => eq(fields.workspace, workspace), | ||
}); | ||
|
||
if (!tenant) { | ||
throw new HTTPException(404, { message: "Workspace not found." }); | ||
} | ||
|
||
const relationship = await db.query.usersToTenants.findFirst({ | ||
where: (fields, { and, eq }) => and(eq(fields.userId, userId), eq(fields.tenantId, tenant.id)), | ||
}); | ||
|
||
if (!relationship) { | ||
throw new HTTPException(403, { message: "You do not have access to this workspace." }); | ||
} | ||
|
||
c.set("tenant", tenant); | ||
|
||
return await next(); | ||
}); | ||
|
||
export const checkServiceTenantMembership = createMiddleware<ServerContext>(async (c, next) => { | ||
const tenant = c.var.tenant!; | ||
const serviceId = c.req.param("service_id"); | ||
|
||
const service = await db.query.services.findFirst({ | ||
where: (fields, { and, eq }) => and(eq(fields.id, serviceId), eq(fields.tenantId, tenant.id)), | ||
}); | ||
|
||
if (!service) { | ||
throw new HTTPException(404, { message: "Service not found." }); | ||
} | ||
|
||
c.set("service", service); | ||
|
||
return await next(); | ||
}); |
Oops, something went wrong.