public commit

This commit is contained in:
dswbx
2024-11-16 12:01:47 +01:00
commit 90f80c4280
582 changed files with 49291 additions and 0 deletions
+130
View File
@@ -0,0 +1,130 @@
import {
Button,
type ComboboxProps,
Menu,
Modal,
NumberInput,
Radio,
SegmentedControl,
Select,
Switch,
TagsInput,
TextInput,
Textarea,
createTheme
} from "@mantine/core";
import { twMerge } from "tailwind-merge";
// default: https://github.com/mantinedev/mantine/blob/master/src/mantine-core/src/core/MantineProvider/default-theme.ts
export function createMantineTheme(scheme: "light" | "dark"): {
theme: ReturnType<typeof createTheme>;
forceColorScheme: "light" | "dark";
} {
const light = scheme === "light";
const dark = !light;
const baseComboboxProps: ComboboxProps = {
offset: 2,
transitionProps: { transition: "pop", duration: 75 }
};
const input =
"bg-muted/40 border-transparent disabled:bg-muted/50 disabled:text-primary/50 focus:border-zinc-500";
return {
theme: createTheme({
components: {
Button: Button.extend({
vars: (theme, props) => ({
// https://mantine.dev/styles/styles-api/
root: {
"--button-height": "auto"
}
}),
classNames: (theme, props) => ({
root: twMerge("px-3 py-2 rounded-md h-auto")
}),
defaultProps: {
size: "md",
variant: light ? "filled" : "white"
}
}),
Switch: Switch.extend({
defaultProps: {
size: "md",
color: light ? "dark" : "blue"
}
}),
Select: Select.extend({
classNames: (theme, props) => ({
//input: "focus:border-primary/50 bg-transparent disabled:text-primary",
input,
dropdown: `bknd-admin ${scheme} bg-background border-primary/20`
}),
defaultProps: {
checkIconPosition: "right",
comboboxProps: baseComboboxProps
}
}),
TagsInput: TagsInput.extend({
defaultProps: {
comboboxProps: baseComboboxProps
}
}),
Radio: Radio.extend({
defaultProps: {
classNames: {
body: "items-center"
}
}
}),
TextInput: TextInput.extend({
classNames: (theme, props) => ({
wrapper: "leading-none",
//input: "focus:border-primary/50 bg-transparent disabled:text-primary"
input
})
}),
NumberInput: NumberInput.extend({
classNames: (theme, props) => ({
wrapper: "leading-none",
input
})
}),
Textarea: Textarea.extend({
classNames: (theme, props) => ({
wrapper: "leading-none",
input
})
}),
Modal: Modal.extend({
classNames: (theme, props) => ({
...props.classNames,
root: `bknd-admin ${scheme} ${props.className ?? ""} `,
content: "bg-lightest border border-primary/10",
overlay: "backdrop-blur"
})
}),
Menu: Menu.extend({
defaultProps: {
offset: 2
},
classNames: (theme, props) => ({
dropdown: "!rounded-lg !px-1",
item: "!rounded-md !text-[14px]"
})
}),
SegmentedControl: SegmentedControl.extend({
classNames: (theme, props) => ({
root: light ? "bg-primary/5" : "bg-lightest/60",
indicator: light ? "bg-background" : "bg-primary/15"
})
})
},
primaryColor: "dark",
primaryShade: 9
}),
forceColorScheme: scheme
};
}
+128
View File
@@ -0,0 +1,128 @@
import type { PrimaryFieldType } from "core";
import { encodeSearch } from "core/utils";
import { atom, useSetAtom } from "jotai";
import { useEffect, useState } from "react";
import { useLocation } from "wouter";
import { useBaseUrl } from "../client";
import { useBknd } from "../client/BkndProvider";
export const routes = {
data: {
root: () => "/data",
entity: {
list: (entity: string) => `/entity/${entity}`,
create: (entity: string) => `/entity/${entity}/create`,
edit: (entity: string, id: PrimaryFieldType) => `/entity/${entity}/edit/${id}`
},
schema: {
root: () => "/schema",
entity: (entity: string) => `/schema/entity/${entity}`
}
},
auth: {
root: () => "/auth",
users: {
list: () => "/users",
edit: (id: PrimaryFieldType) => `/users/edit/${id}`
},
roles: {
list: () => "/roles",
edit: (role: string) => `/roles/edit/${role}`
},
settings: () => "/settings",
strategies: () => "/strategies"
},
flows: {
root: () => "/flows",
flows: {
list: () => "/",
edit: (id: PrimaryFieldType) => `/flow/${id}`
}
},
settings: {
root: () => "/settings",
path: (path: string[]) => `/settings/${path.join("/")}`
}
};
export function withQuery(url: string, query: object) {
const search = encodeSearch(query, { encode: false });
return `${url}?${search}`;
}
export function withAbsolute(url: string) {
const { app } = useBknd();
const basepath = app.getAdminConfig().basepath;
return `~/${basepath}/${url}`.replace(/\/+/g, "/");
}
export function useNavigate() {
const [location, navigate] = useLocation();
const { app } = useBknd();
const basepath = app.getAdminConfig().basepath;
return [
(
url: string,
options?: { query?: object; absolute?: boolean; replace?: boolean; state?: any }
) => {
const _url = options?.absolute ? `~/${basepath}${url}`.replace(/\/+/g, "/") : url;
navigate(options?.query ? withQuery(_url, options?.query) : _url, {
replace: options?.replace,
state: options?.state
});
},
location
] as const;
}
export function useGoBack(
fallback: string | (() => void) = "/",
options?: {
native?: boolean;
absolute?: boolean;
}
) {
const { app } = useBknd();
const basepath = app.getAdminConfig().basepath;
const [navigate] = useNavigate();
const referrer = document.referrer;
const history_length = window.history.length;
const same = referrer.length === 0;
const canGoBack = (same && history_length > 1) || !!same;
/*console.log("debug", {
referrer,
history_length,
same,
canGoBack
});*/
function goBack() {
if (same && history_length > 2) {
//console.log("used history");
window.history.back();
} else {
//console.log("used fallback");
if (typeof fallback === "string") {
const _fallback = options?.absolute
? `~/${basepath}${fallback}`.replace(/\/+/g, "/")
: fallback;
//console.log("fallback", _fallback);
if (options?.native) {
window.location.href = _fallback;
} else {
navigate(_fallback);
}
} else if (typeof fallback === "function") {
fallback();
}
}
}
return {
same,
canGoBack,
goBack
};
}
+5
View File
@@ -0,0 +1,5 @@
import { type ClassNameValue, twMerge } from "tailwind-merge";
export function cn(...inputs: ClassNameValue[]) {
return twMerge(inputs);
}