(fix): tauth blocking children
(feat): update ui components
This commit is contained in:
parent
fb742bd068
commit
fb7c9fa538
7 changed files with 92 additions and 9 deletions
|
|
@ -1,16 +1,43 @@
|
||||||
import { Label } from "@tensamin/ui";
|
import { Label } from "@tensamin/ui";
|
||||||
import { Switch as UISwitch } from "@tensamin/ui";
|
import { Switch as UISwitch, Input as UIInput } from "@tensamin/ui";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
import type { Storage } from "@tensamin/shared/data";
|
||||||
import { settingsStorageDefaults } from "@tensamin/shared/settings";
|
import { settingsStorageDefaults } from "@tensamin/shared/settings";
|
||||||
import { useStorage } from "@tensamin/storage/context";
|
import { useStorage } from "@tensamin/storage/context";
|
||||||
|
|
||||||
|
type BooleanStorageKey = {
|
||||||
|
[K in keyof Storage]: Storage[K] extends boolean ? K : never;
|
||||||
|
}[keyof Storage];
|
||||||
|
|
||||||
|
type StringStorageKey = {
|
||||||
|
[K in keyof Storage]: Storage[K] extends string ? K : never;
|
||||||
|
}[keyof Storage];
|
||||||
|
|
||||||
|
type NumberStorageKey = {
|
||||||
|
[K in keyof Storage]: Storage[K] extends number ? K : never;
|
||||||
|
}[keyof Storage];
|
||||||
|
|
||||||
|
type InputProps =
|
||||||
|
| {
|
||||||
|
label: string;
|
||||||
|
id: StringStorageKey;
|
||||||
|
placeholder?: string;
|
||||||
|
type?: "text";
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
label: string;
|
||||||
|
id: NumberStorageKey;
|
||||||
|
placeholder?: string;
|
||||||
|
type: "number";
|
||||||
|
};
|
||||||
|
|
||||||
export function Switch({
|
export function Switch({
|
||||||
label,
|
label,
|
||||||
id,
|
id,
|
||||||
}: {
|
}: {
|
||||||
label: string;
|
label: string;
|
||||||
id: keyof typeof settingsStorageDefaults;
|
id: keyof typeof settingsStorageDefaults & BooleanStorageKey;
|
||||||
}) {
|
}) {
|
||||||
const { save, load } = useStorage();
|
const { save, load } = useStorage();
|
||||||
const [value, setValue] = useState<boolean>(settingsStorageDefaults[id]);
|
const [value, setValue] = useState<boolean>(settingsStorageDefaults[id]);
|
||||||
|
|
@ -33,3 +60,49 @@ export function Switch({
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function Input({ label, id, placeholder, type }: InputProps) {
|
||||||
|
const { save, load } = useStorage();
|
||||||
|
const [value, setValue] = useState<string | number>(
|
||||||
|
type === "number" ? 0 : "",
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
load(id).then((loadedValue) => {
|
||||||
|
if (type === "number") {
|
||||||
|
if (typeof loadedValue === "number") {
|
||||||
|
setValue(loadedValue);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof loadedValue === "string") {
|
||||||
|
setValue(loadedValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, [id, load, type]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col gap-1">
|
||||||
|
<Label htmlFor={id}>{label}</Label>
|
||||||
|
<UIInput
|
||||||
|
id={id}
|
||||||
|
type={type || "text"}
|
||||||
|
placeholder={placeholder}
|
||||||
|
value={value}
|
||||||
|
onChange={(e) => {
|
||||||
|
if (type === "number") {
|
||||||
|
const nextValue = Number(e.target.value);
|
||||||
|
setValue(nextValue);
|
||||||
|
save(id, nextValue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextValue = e.target.value;
|
||||||
|
setValue(nextValue);
|
||||||
|
save(id, nextValue);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,14 +39,16 @@ export function SettingsSidebar() {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
isMobile ? "w-full" : "rounded-tl-2xl border-r bg-input/15 w-50",
|
isMobile
|
||||||
"flex flex-col gap-6 p-3",
|
? "w-full p-1"
|
||||||
|
: "p-3 rounded-tl-2xl border-r bg-input/15 w-50",
|
||||||
|
"flex flex-col gap-6",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{/* Settings */}
|
{/* Settings */}
|
||||||
{Object.keys(settingsOptions).map((category) => (
|
{Object.keys(settingsOptions).map((category) => (
|
||||||
// Category
|
// Category
|
||||||
<div key={category} className="flex flex-col gap-1">
|
<div key={category} className="flex flex-col gap-2">
|
||||||
<h2 className="font-bold text-xs uppercase">{category}</h2>
|
<h2 className="font-bold text-xs uppercase">{category}</h2>
|
||||||
{Object.keys(settingsOptions[category]).map((page) => (
|
{Object.keys(settingsOptions[category]).map((page) => (
|
||||||
// Page
|
// Page
|
||||||
|
|
|
||||||
3
apps/web/src/routes/settings/profile.tsx
Normal file
3
apps/web/src/routes/settings/profile.tsx
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
export default function Page() {
|
||||||
|
return <div></div>;
|
||||||
|
}
|
||||||
4
bun.lock
4
bun.lock
|
|
@ -240,7 +240,7 @@
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"@tensamin/ttp-core": "https://git.methanium.net/tensamin/ttp/archive/0.0.9.tar.gz",
|
"@tensamin/ttp-core": "https://git.methanium.net/tensamin/ttp/archive/0.0.9.tar.gz",
|
||||||
"@tensamin/ui": "https://git.methanium.net/tensamin/ui/archive/0.0.25.tar.gz",
|
"@tensamin/ui": "https://git.methanium.net/tensamin/ui/archive/0.0.26.tar.gz",
|
||||||
},
|
},
|
||||||
"packages": {
|
"packages": {
|
||||||
"@antfu/ni": ["@antfu/ni@25.0.0", "", { "dependencies": { "ansis": "^4.0.0", "fzf": "^0.5.2", "package-manager-detector": "^1.3.0", "tinyexec": "^1.0.1" }, "bin": { "na": "bin/na.mjs", "ni": "bin/ni.mjs", "nr": "bin/nr.mjs", "nci": "bin/nci.mjs", "nlx": "bin/nlx.mjs", "nun": "bin/nun.mjs", "nup": "bin/nup.mjs" } }, "sha512-9q/yCljni37pkMr4sPrI3G4jqdIk074+iukc5aFJl7kmDCCsiJrbZ6zKxnES1Gwg+i9RcDZwvktl23puGslmvA=="],
|
"@antfu/ni": ["@antfu/ni@25.0.0", "", { "dependencies": { "ansis": "^4.0.0", "fzf": "^0.5.2", "package-manager-detector": "^1.3.0", "tinyexec": "^1.0.1" }, "bin": { "na": "bin/na.mjs", "ni": "bin/ni.mjs", "nr": "bin/nr.mjs", "nci": "bin/nci.mjs", "nlx": "bin/nlx.mjs", "nun": "bin/nun.mjs", "nup": "bin/nup.mjs" } }, "sha512-9q/yCljni37pkMr4sPrI3G4jqdIk074+iukc5aFJl7kmDCCsiJrbZ6zKxnES1Gwg+i9RcDZwvktl23puGslmvA=="],
|
||||||
|
|
@ -693,7 +693,7 @@
|
||||||
|
|
||||||
"@tensamin/ttp-core": ["@tensamin/ttp-core@https://git.methanium.net/tensamin/ttp/archive/0.0.9.tar.gz", { "dependencies": { "@eslint/js": "^10.0.1", "@typescript-eslint/parser": "^8.58.1", "@webtransport-bun/webtransport": "^0.3.0", "globals": "^17.5.0", "typescript": "^6.0.2", "typescript-eslint": "^8.58.1", "zod": "^4.3.6" } }, "sha512-V9EK/t/tcBe1oNqzUMxtn41wc3UIS0mkLvGeR1mGfZaKn4d9bwwWQ2VmSmRSxodPYiQUJkziJV4fZvdzGjnzFw=="],
|
"@tensamin/ttp-core": ["@tensamin/ttp-core@https://git.methanium.net/tensamin/ttp/archive/0.0.9.tar.gz", { "dependencies": { "@eslint/js": "^10.0.1", "@typescript-eslint/parser": "^8.58.1", "@webtransport-bun/webtransport": "^0.3.0", "globals": "^17.5.0", "typescript": "^6.0.2", "typescript-eslint": "^8.58.1", "zod": "^4.3.6" } }, "sha512-V9EK/t/tcBe1oNqzUMxtn41wc3UIS0mkLvGeR1mGfZaKn4d9bwwWQ2VmSmRSxodPYiQUJkziJV4fZvdzGjnzFw=="],
|
||||||
|
|
||||||
"@tensamin/ui": ["@tensamin/ui@https://git.methanium.net/tensamin/ui/archive/0.0.25.tar.gz", { "dependencies": { "@base-ui/react": "^1.3.0", "@fontsource-variable/inter": "^5.2.6", "@tauri-apps/api": "^2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.1.1", "date-fns": "^4.1.0", "embla-carousel-react": "^8.6.0", "input-otp": "^1.4.2", "lucide-react": "^1.8.0", "next-themes": "^0.4.6", "react-day-picker": "^9.14.0", "react-resizable-panels": "^4.10.0", "recharts": "3.8.0", "shadcn": "^3.5.0", "sonner": "^2.0.7", "tailwind-merge": "^3.5.0", "tw-animate-css": "^1.3.0", "vaul": "^1.1.2" }, "peerDependencies": { "react": "^19.2.0", "react-dom": "^19.2.0" } }, "sha512-pYkl4quhAhV/l/j1Yy5m4DDV5fh42H4G8v+FE6qEMCcJIOeA1LU7brIG7X9zURe7F4gyn1LQxMf2yABuV/NsMQ=="],
|
"@tensamin/ui": ["@tensamin/ui@https://git.methanium.net/tensamin/ui/archive/0.0.26.tar.gz", { "dependencies": { "@base-ui/react": "^1.3.0", "@fontsource-variable/inter": "^5.2.6", "@tauri-apps/api": "^2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.1.1", "date-fns": "^4.1.0", "embla-carousel-react": "^8.6.0", "input-otp": "^1.4.2", "lucide-react": "^1.8.0", "next-themes": "^0.4.6", "react-day-picker": "^9.14.0", "react-resizable-panels": "^4.10.0", "recharts": "3.8.0", "shadcn": "^3.5.0", "sonner": "^2.0.7", "tailwind-merge": "^3.5.0", "tw-animate-css": "^1.3.0", "vaul": "^1.1.2" }, "peerDependencies": { "react": "^19.2.0", "react-dom": "^19.2.0" } }, "sha512-SH+voNvmg2TtTjZH561NZC4ekY0ypFQpPvC0u0s5Jt1nGG243TR3ybX3T3WI83Z59ayC+t7YPZOmQPHTHI9+Mw=="],
|
||||||
|
|
||||||
"@tensamin/user": ["@tensamin/user@workspace:packages/user"],
|
"@tensamin/user": ["@tensamin/user@workspace:packages/user"],
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@
|
||||||
"typescript-eslint": "^8.58.1"
|
"typescript-eslint": "^8.58.1"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"@tensamin/ui": "https://git.methanium.net/tensamin/ui/archive/0.0.25.tar.gz",
|
"@tensamin/ui": "https://git.methanium.net/tensamin/ui/archive/0.0.26.tar.gz",
|
||||||
"@tensamin/ttp-core": "https://git.methanium.net/tensamin/ttp/archive/0.0.9.tar.gz"
|
"@tensamin/ttp-core": "https://git.methanium.net/tensamin/ttp/archive/0.0.9.tar.gz"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ export type SettingsSchema = Record<
|
||||||
|
|
||||||
const settings = {
|
const settings = {
|
||||||
account: {
|
account: {
|
||||||
|
profile: {},
|
||||||
security: {
|
security: {
|
||||||
login_qr_code: {
|
login_qr_code: {
|
||||||
display: "Login QR Code",
|
display: "Login QR Code",
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,11 @@ export default function Wrapper({ children }: { children: ReactNode }) {
|
||||||
const identifier = params.get("identifier");
|
const identifier = params.get("identifier");
|
||||||
const redirect = params.get("redirect");
|
const redirect = params.get("redirect");
|
||||||
const challenge = params.get("challenge");
|
const challenge = params.get("challenge");
|
||||||
if (!identifier || !redirect) return;
|
if (!identifier || !redirect) {
|
||||||
|
// eslint-disable-next-line
|
||||||
|
setAllowChildern(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
load("user_id").then((userId) => {
|
load("user_id").then((userId) => {
|
||||||
if (!challenge) {
|
if (!challenge) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue