INIT
CI / build (push) Has been skipped
CI / deploy (push) Successful in 1m11s

This commit is contained in:
eewing
2026-02-18 15:17:47 -06:00
parent e74c106f85
commit ec317eb17c
11532 changed files with 1631690 additions and 1 deletions
@@ -0,0 +1,23 @@
import { json } from "@sveltejs/kit";
const POST = async ({ request, locals }) => {
if (!locals.user) {
return json({ error: "Unauthorized" }, { status: 401 });
}
let body;
try {
body = await request.json();
} catch {
return json({ error: "Invalid JSON" }, { status: 400 });
}
const darkmode = !!body.darkmode;
try {
await locals.pb.collection("users").update(locals.user.id, { darkmode });
await locals.pb.collection("users").authRefresh();
} catch (e) {
return json({ error: "Update failed" }, { status: 500 });
}
return json({ darkmode });
};
export {
POST
};
@@ -0,0 +1,45 @@
import { g as getContext, f as escape_html } from "../../chunks/index2.js";
import "clsx";
import "../../chunks/state.svelte.js";
import "@sveltejs/kit/internal";
import "../../chunks/exports.js";
import "../../chunks/utils.js";
import { w as writable } from "../../chunks/index.js";
import "@sveltejs/kit/internal/server";
import "../../chunks/root.js";
function create_updated_store() {
const { set, subscribe } = writable(false);
{
return {
subscribe,
// eslint-disable-next-line @typescript-eslint/require-await
check: async () => false
};
}
}
const stores = {
updated: /* @__PURE__ */ create_updated_store()
};
({
check: stores.updated.check
});
function context() {
return getContext("__request__");
}
const page$1 = {
get error() {
return context().page.error;
},
get status() {
return context().page.status;
}
};
const page = page$1;
function Error$1($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
$$renderer2.push(`<h1>${escape_html(page.status)}</h1> <p>${escape_html(page.error?.message)}</p>`);
});
}
export {
Error$1 as default
};
@@ -0,0 +1,41 @@
import { redirect } from "@sveltejs/kit";
import PocketBase from "pocketbase";
const POCKETBASE_URL = process.env.VITE_POCKETBASE_URL ?? "https://pocketbase.ccllc.pro";
const LOGIN_PATH = "/login";
const LOGOUT_PATH = "/logout";
function isPublicRoute(pathname) {
return pathname === LOGIN_PATH || pathname.startsWith(LOGIN_PATH + "/") || pathname === LOGOUT_PATH;
}
const handle = async ({ event, resolve }) => {
event.locals.pb = new PocketBase(POCKETBASE_URL);
event.locals.pb.authStore.loadFromCookie(event.request.headers.get("cookie") ?? "");
try {
if (event.locals.pb.authStore.isValid) {
await event.locals.pb.collection("users").authRefresh();
}
} catch {
event.locals.pb.authStore.clear();
}
const record = event.locals.pb.authStore.record;
event.locals.user = record ? {
id: record.id,
email: record.email,
name: record.name,
avatar: record.avatar,
darkmode: !!record.darkmode
} : null;
if (!event.locals.user && !isPublicRoute(event.url.pathname)) {
const redirectTo = event.url.pathname + event.url.search;
const loginUrl = redirectTo && redirectTo !== "/" ? `${LOGIN_PATH}?redirectTo=${encodeURIComponent(redirectTo)}` : LOGIN_PATH;
throw redirect(303, loginUrl);
}
const response = await resolve(event);
response.headers.append(
"set-cookie",
event.locals.pb.authStore.exportToCookie({ httpOnly: false, sameSite: "Lax" })
);
return response;
};
export {
handle
};
@@ -0,0 +1,8 @@
const load = async ({ locals }) => {
return {
user: locals.user
};
};
export {
load
};
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,48 @@
import "clsx";
import { B as Button } from "../../chunks/button.js";
function _page($$renderer, $$props) {
let { data } = $$props;
{
$$renderer.push("<!--[!-->");
$$renderer.push(`<main class="flex min-h-0 flex-1 flex-col items-center justify-center gap-6 p-6"><h1 class="text-2xl font-semibold">Base</h1> <div class="flex w-full max-w-xs flex-col gap-3"><a href="https://prism.ccllc.pro" class="block" target="_blank" rel="noopener noreferrer">`);
Button($$renderer, {
class: "h-12 w-full min-h-12",
children: ($$renderer2) => {
$$renderer2.push(`<!---->Prism`);
},
$$slots: { default: true }
});
$$renderer.push(`<!----></a> <a href="https://tasgrid.ccllc.pro" class="block" target="_blank" rel="noopener noreferrer">`);
Button($$renderer, {
class: "h-12 min-h-12 w-full",
variant: "outline",
children: ($$renderer2) => {
$$renderer2.push(`<!---->TasGrid`);
},
$$slots: { default: true }
});
$$renderer.push(`<!----></a> <a href="https://stackq.ccllc.pro" class="block" target="_blank" rel="noopener noreferrer">`);
Button($$renderer, {
class: "h-12 min-h-12 w-full",
variant: "outline",
children: ($$renderer2) => {
$$renderer2.push(`<!---->Stackq`);
},
$$slots: { default: true }
});
$$renderer.push(`<!----></a> <a href="https://hrm.ccllc.pro" class="block" target="_blank" rel="noopener noreferrer">`);
Button($$renderer, {
class: "h-12 min-h-12 w-full",
variant: "outline",
children: ($$renderer2) => {
$$renderer2.push(`<!---->HRM`);
},
$$slots: { default: true }
});
$$renderer.push(`<!----></a></div></main>`);
}
$$renderer.push(`<!--]-->`);
}
export {
_page as default
};
@@ -0,0 +1,38 @@
import { redirect } from "@sveltejs/kit";
const load = async ({ url, locals }) => {
if (locals.user) {
throw redirect(303, url.searchParams.get("redirectTo") ?? "/");
}
return {
redirectTo: url.searchParams.get("redirectTo") ?? "",
error: null
};
};
const actions = {
default: async ({ request, locals, url }) => {
const formData = await request.formData();
const email = String(formData.get("email") ?? "").trim();
const password = String(formData.get("password") ?? "");
const redirectTo = String(formData.get("redirectTo") ?? "").trim() || "/";
if (!email || !password) {
return {
redirectTo,
error: "Email and password are required."
};
}
try {
await locals.pb.collection("users").authWithPassword(email, password);
} catch (err) {
const message = err && typeof err === "object" && "message" in err ? String(err.message) : "Invalid email or password.";
return {
redirectTo,
error: message
};
}
throw redirect(303, redirectTo);
}
};
export {
actions,
load
};
@@ -0,0 +1,256 @@
import { b as attributes, j as clsx, c as bind_props, i as attr, f as escape_html } from "../../../chunks/index2.js";
import "@sveltejs/kit/internal";
import "../../../chunks/exports.js";
import "../../../chunks/utils.js";
import "@sveltejs/kit/internal/server";
import "../../../chunks/root.js";
import "../../../chunks/state.svelte.js";
import { B as Button } from "../../../chunks/button.js";
import { c as cn } from "../../../chunks/utils2.js";
import { L as Label } from "../../../chunks/label.js";
import "clsx";
function Input($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let {
ref = null,
value = void 0,
type,
files = void 0,
class: className,
"data-slot": dataSlot = "input",
$$slots,
$$events,
...restProps
} = $$props;
if (type === "file") {
$$renderer2.push("<!--[-->");
$$renderer2.push(`<input${attributes(
{
"data-slot": dataSlot,
class: clsx(cn("selection:bg-primary dark:bg-input/30 selection:text-primary-foreground border-input ring-offset-background placeholder:text-muted-foreground flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 pt-1.5 text-sm font-medium shadow-xs transition-[color,box-shadow] outline-none disabled:cursor-not-allowed disabled:opacity-50", "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]", "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", className)),
type: "file",
...restProps
},
void 0,
void 0,
void 0,
4
)}/>`);
} else {
$$renderer2.push("<!--[!-->");
$$renderer2.push(`<input${attributes(
{
"data-slot": dataSlot,
class: clsx(cn("border-input bg-background selection:bg-primary dark:bg-input/30 selection:text-primary-foreground ring-offset-background placeholder:text-muted-foreground flex h-9 w-full min-w-0 rounded-md border px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]", "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", className)),
type,
value,
...restProps
},
void 0,
void 0,
void 0,
4
)}/>`);
}
$$renderer2.push(`<!--]-->`);
bind_props($$props, { ref, value, files });
});
}
function Card($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let {
ref = null,
class: className,
children,
$$slots,
$$events,
...restProps
} = $$props;
$$renderer2.push(`<div${attributes({
"data-slot": "card",
class: clsx(cn("bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm", className)),
...restProps
})}>`);
children?.($$renderer2);
$$renderer2.push(`<!----></div>`);
bind_props($$props, { ref });
});
}
function Card_content($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let {
ref = null,
class: className,
children,
$$slots,
$$events,
...restProps
} = $$props;
$$renderer2.push(`<div${attributes({
"data-slot": "card-content",
class: clsx(cn("px-6", className)),
...restProps
})}>`);
children?.($$renderer2);
$$renderer2.push(`<!----></div>`);
bind_props($$props, { ref });
});
}
function Card_description($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let {
ref = null,
class: className,
children,
$$slots,
$$events,
...restProps
} = $$props;
$$renderer2.push(`<p${attributes({
"data-slot": "card-description",
class: clsx(cn("text-muted-foreground text-sm", className)),
...restProps
})}>`);
children?.($$renderer2);
$$renderer2.push(`<!----></p>`);
bind_props($$props, { ref });
});
}
function Card_header($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let {
ref = null,
class: className,
children,
$$slots,
$$events,
...restProps
} = $$props;
$$renderer2.push(`<div${attributes({
"data-slot": "card-header",
class: clsx(cn("@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6", className)),
...restProps
})}>`);
children?.($$renderer2);
$$renderer2.push(`<!----></div>`);
bind_props($$props, { ref });
});
}
function Card_title($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let {
ref = null,
class: className,
children,
$$slots,
$$events,
...restProps
} = $$props;
$$renderer2.push(`<div${attributes({
"data-slot": "card-title",
class: clsx(cn("leading-none font-semibold", className)),
...restProps
})}>`);
children?.($$renderer2);
$$renderer2.push(`<!----></div>`);
bind_props($$props, { ref });
});
}
function _page($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let { data, formAction } = $$props;
const redirectTo = data.form?.redirectTo ?? data.redirectTo ?? "";
const error = data.form?.error;
$$renderer2.push(`<div class="app-shell max-w-sm mx-auto w-full">`);
$$renderer2.push("<!---->");
Card?.($$renderer2, {
children: ($$renderer3) => {
$$renderer3.push("<!---->");
Card_header?.($$renderer3, {
children: ($$renderer4) => {
$$renderer4.push("<!---->");
Card_title?.($$renderer4, {
children: ($$renderer5) => {
$$renderer5.push(`<!---->Sign in`);
},
$$slots: { default: true }
});
$$renderer4.push(`<!----> `);
$$renderer4.push("<!---->");
Card_description?.($$renderer4, {
children: ($$renderer5) => {
$$renderer5.push(`<!---->Enter your email and password.`);
},
$$slots: { default: true }
});
$$renderer4.push(`<!---->`);
},
$$slots: { default: true }
});
$$renderer3.push(`<!----> `);
$$renderer3.push("<!---->");
Card_content?.($$renderer3, {
children: ($$renderer4) => {
$$renderer4.push(`<form method="POST"${attr("action", formAction)} class="flex flex-col gap-4"><input type="hidden" name="redirectTo"${attr("value", redirectTo)}/> <div class="grid gap-2">`);
Label($$renderer4, {
for: "email",
children: ($$renderer5) => {
$$renderer5.push(`<!---->Email`);
},
$$slots: { default: true }
});
$$renderer4.push(`<!----> `);
Input($$renderer4, {
id: "email",
name: "email",
type: "email",
placeholder: "you@example.com",
required: true,
autocomplete: "email"
});
$$renderer4.push(`<!----></div> <div class="grid gap-2">`);
Label($$renderer4, {
for: "password",
children: ($$renderer5) => {
$$renderer5.push(`<!---->Password`);
},
$$slots: { default: true }
});
$$renderer4.push(`<!----> `);
Input($$renderer4, {
id: "password",
name: "password",
type: "password",
required: true,
autocomplete: "current-password"
});
$$renderer4.push(`<!----></div> `);
if (error) {
$$renderer4.push("<!--[-->");
$$renderer4.push(`<p class="text-sm text-destructive">${escape_html(error)}</p>`);
} else {
$$renderer4.push("<!--[!-->");
}
$$renderer4.push(`<!--]--> `);
Button($$renderer4, {
type: "submit",
class: "w-full",
children: ($$renderer5) => {
$$renderer5.push(`<!---->Sign in`);
},
$$slots: { default: true }
});
$$renderer4.push(`<!----></form>`);
},
$$slots: { default: true }
});
$$renderer3.push(`<!---->`);
},
$$slots: { default: true }
});
$$renderer2.push(`<!----></div>`);
});
}
export {
_page as default
};
@@ -0,0 +1,10 @@
import { redirect } from "@sveltejs/kit";
const actions = {
default: async ({ locals }) => {
locals.pb.authStore.clear();
throw redirect(303, "/login");
}
};
export {
actions
};
@@ -0,0 +1,23 @@
import { i as attr } from "../../../chunks/index2.js";
import "@sveltejs/kit/internal";
import "../../../chunks/exports.js";
import "../../../chunks/utils.js";
import "@sveltejs/kit/internal/server";
import "../../../chunks/root.js";
import "../../../chunks/state.svelte.js";
import { B as Button } from "../../../chunks/button.js";
function _page($$renderer, $$props) {
let { formAction } = $$props;
$$renderer.push(`<div class="app-shell flex items-center justify-center min-h-[200px]"><form method="POST"${attr("action", formAction)}>`);
Button($$renderer, {
type: "submit",
children: ($$renderer2) => {
$$renderer2.push(`<!---->Log out`);
},
$$slots: { default: true }
});
$$renderer.push(`<!----></form></div>`);
}
export {
_page as default
};