@sqrzro/admin 2.1.0-bz.14 → 2.1.0-bz.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/AppLayout/index.d.ts +1 -1
- package/dist/components/AppLayout/index.js +6 -4
- package/dist/components/AppNavigation/index.d.ts +4 -1
- package/dist/components/AppNavigation/index.js +2 -2
- package/dist/components/Auth/index.js +5 -2
- package/dist/components/Badge/index.js +5 -5
- package/dist/components/Icon/index.d.ts +1 -1
- package/dist/components/Icon/index.js +1 -0
- package/dist/components/InfoPanel/index.js +17 -5
- package/dist/components/List/index.d.ts +2 -1
- package/dist/components/List/index.js +21 -5
- package/dist/components/ListItem/index.d.ts +3 -2
- package/dist/components/ListItem/index.js +2 -2
- package/dist/components/MePanel/index.js +1 -1
- package/dist/components/Page/index.d.ts +1 -1
- package/dist/components/Page/index.js +7 -3
- package/dist/components/SettingsForm/index.d.ts +8 -1
- package/dist/components/SettingsForm/index.js +9 -4
- package/dist/components/SettingsPage/index.d.ts +2 -1
- package/dist/components/SettingsPage/index.js +4 -2
- package/dist/components/Tabs/index.js +0 -13
- package/dist/components/index.d.ts +2 -1
- package/dist/components/index.js +1 -1
- package/dist/services/LayoutService.d.ts +7 -0
- package/dist/services/LayoutService.js +9 -0
- package/dist/styles/config.js +14 -10
- package/package.json +1 -1
|
@@ -5,5 +5,5 @@ export interface AppLayoutProps {
|
|
|
5
5
|
name: string;
|
|
6
6
|
} | null;
|
|
7
7
|
}
|
|
8
|
-
declare function AppLayout({ children, user }: Readonly<AppLayoutProps>):
|
|
8
|
+
declare function AppLayout({ children, user }: Readonly<AppLayoutProps>): Promise<JSX.Element>;
|
|
9
9
|
export default AppLayout;
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Container, Link, tw } from '@sqrzro/components';
|
|
3
|
-
import { cookies } from 'next/headers';
|
|
4
3
|
import { getConfig } from '../../services/ConfigService';
|
|
4
|
+
import { getLayout } from '../../services/LayoutService';
|
|
5
5
|
import AppNavigation from '../AppNavigation';
|
|
6
6
|
import MePanel from '../MePanel';
|
|
7
|
-
function AppLayout({ children, user }) {
|
|
7
|
+
async function AppLayout({ children, user }) {
|
|
8
8
|
const config = getConfig();
|
|
9
|
-
const layout =
|
|
10
|
-
return (_jsxs("div", { className: tw('', layout === 'sidebar' ? 'grid grid-cols-[12rem_1fr]' : null), children: [_jsx("header", { className: "bg-slate-800", children: _jsx(Container, { isFullWidth: true, children: _jsxs("div", { className: tw('flex
|
|
9
|
+
const layout = await getLayout();
|
|
10
|
+
return (_jsxs("div", { className: tw('', layout === 'sidebar' ? 'grid grid-cols-[12rem_1fr]' : null), children: [_jsx("header", { className: "bg-slate-800", children: _jsx(Container, { isFullWidth: true, children: _jsxs("div", { className: tw('flex items-center', layout === 'sidebar'
|
|
11
|
+
? 'h-screen flex-col py-4'
|
|
12
|
+
: 'h-16 border-b border-slate-700'), children: [_jsxs(Link, { className: tw(layout === 'sidebar' ? 'h-12 w-12' : 'h-9 w-9'), href: "/", children: [config.logo?.(), _jsx("span", { className: "sr-only", children: config.app.name })] }), _jsx(AppNavigation, { layout: layout }), _jsx(MePanel, { user: user })] }) }) }), _jsx("main", { className: "mb-10 block", children: children })] }));
|
|
11
13
|
}
|
|
12
14
|
export default AppLayout;
|
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
|
|
2
|
+
interface AppNavigationProps {
|
|
3
|
+
layout: string;
|
|
4
|
+
}
|
|
5
|
+
declare function AppNavigation({ layout }: Readonly<AppNavigationProps>): React.ReactElement;
|
|
3
6
|
export default AppNavigation;
|
|
@@ -7,9 +7,9 @@ function getNavigation() {
|
|
|
7
7
|
const { navigation } = getConfig();
|
|
8
8
|
return Object.entries(navigation).map(([href, label]) => ({ href, label }));
|
|
9
9
|
}
|
|
10
|
-
function AppNavigation() {
|
|
10
|
+
function AppNavigation({ layout }) {
|
|
11
11
|
const navigation = useNavigation(getNavigation());
|
|
12
|
-
return (_jsx("nav", { className: "h-full pl-6", children: _jsx("ul", { className:
|
|
12
|
+
return (_jsx("nav", { className: "h-full pl-6", children: _jsx("ul", { className: tw('flex h-full gap-2', layout === 'sidebar' ? 'flex-col items-start' : 'items-center'), children: navigation.map(({ href, isActive, label }) => (_jsx("li", { className: tw(layout === 'sidebar' ? null : 'h-full'), children: _jsx(Link, { className: tw('relative flex h-full items-center px-1 font-semibold', isActive
|
|
13
13
|
? 'before:bg-primary text-white before:absolute before:bottom-0 before:left-0 before:right-0 before:h-1'
|
|
14
14
|
: 'text-white/80 hover:text-white'), href: href, children: label }) }, href))) }) }));
|
|
15
15
|
}
|
|
@@ -3,8 +3,11 @@ import { Auth as AuthComponent } from '@sqrzro/components';
|
|
|
3
3
|
const classNames = {
|
|
4
4
|
root: 'bg-slate-800 gap-8',
|
|
5
5
|
logo: 'mx-auto flex h-12 w-32 items-end',
|
|
6
|
-
panel: 'rounded bg-white p-8 shadow-lg',
|
|
7
|
-
title: 'text-lg font-semibold mb-
|
|
6
|
+
panel: 'rounded bg-white p-8 shadow-lg pb-10',
|
|
7
|
+
title: 'text-lg font-semibold mb-6 leading-none',
|
|
8
|
+
link: 'font-semibold text-link',
|
|
9
|
+
actions: 'pt-2 w-full',
|
|
10
|
+
footer: '-mb-2',
|
|
8
11
|
};
|
|
9
12
|
function Auth(props) {
|
|
10
13
|
return _jsx(AuthComponent, { ...props, classNames: classNames });
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { tw } from '@sqrzro/components';
|
|
3
3
|
const variantMap = {
|
|
4
|
-
info: 'bg-sky-100
|
|
5
|
-
warning: 'bg-yellow-100
|
|
6
|
-
success: 'bg-emerald-100
|
|
4
|
+
info: 'bg-sky-100 text-sky-700',
|
|
5
|
+
warning: 'bg-yellow-100 text-yellow-700',
|
|
6
|
+
success: 'bg-emerald-100 text-emerald-600',
|
|
7
7
|
};
|
|
8
8
|
function Badge({ children, variant }) {
|
|
9
|
-
return (
|
|
9
|
+
return (_jsxs("strong", { className: tw('inline-flex items-center gap-1.5 rounded-full bg-red-100 px-2 py-1 text-xs font-medium text-red-700'), children: [_jsx("svg", { "aria-hidden": "true", className: "h-1.5 w-1.5 fill-red-500", viewBox: "0 0 6 6", children: _jsx("circle", { cx: "3", cy: "3", r: "3" }) }), children] }));
|
|
10
10
|
}
|
|
11
11
|
export default Badge;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
export type IconType = 'error' | 'info' | 'success' | 'warning';
|
|
2
|
+
export type IconType = 'danger' | 'error' | 'info' | 'success' | 'warning';
|
|
3
3
|
declare const icons: Record<IconType, () => React.ReactElement>;
|
|
4
4
|
export interface IconProps {
|
|
5
5
|
type?: keyof typeof icons;
|
|
@@ -1,10 +1,22 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { tw } from '@sqrzro/components';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import Icon from '../Icon';
|
|
4
|
+
const iconTypeMap = {
|
|
5
|
+
danger: 'danger',
|
|
6
|
+
info: 'info',
|
|
7
|
+
success: 'success',
|
|
8
|
+
warning: 'warning',
|
|
6
9
|
};
|
|
10
|
+
const classMap = {
|
|
11
|
+
danger: 'bg-red-50 text-red-700',
|
|
12
|
+
info: 'bg-sky-50 text-sky-700',
|
|
13
|
+
success: 'bg-green-50 text-green-700',
|
|
14
|
+
warning: 'bg-yellow-50 text-yellow-700',
|
|
15
|
+
};
|
|
16
|
+
function mapVariantToIconType(variant) {
|
|
17
|
+
return iconTypeMap[variant] || 'info';
|
|
18
|
+
}
|
|
7
19
|
function InfoPanel({ children, variant = 'info' }) {
|
|
8
|
-
return (
|
|
20
|
+
return (_jsxs("aside", { className: tw('grid grid-cols-[1rem_auto] gap-4 rounded p-4', classMap[variant]), children: [_jsx(Icon, { type: mapVariantToIconType(variant) }), _jsx("div", { children: children })] }));
|
|
9
21
|
}
|
|
10
22
|
export default InfoPanel;
|
|
@@ -16,9 +16,10 @@ export interface ListProps<Item> {
|
|
|
16
16
|
filters?: FilterObject[];
|
|
17
17
|
fn: (params: Record<string, string>, searchParams: URLSearchParams) => Promise<Errorable<Item[]>>;
|
|
18
18
|
hasSearch?: boolean;
|
|
19
|
+
isMinimal?: boolean;
|
|
19
20
|
renderItem?: (props: ListObject) => React.ReactElement;
|
|
20
21
|
params?: Record<string, string>;
|
|
21
22
|
transformer?: (item: Item) => ListObject;
|
|
22
23
|
}
|
|
23
|
-
declare function List<Item extends object>({ actions, columns, emptyMessageProps, filters, fn, hasSearch, params, renderItem, transformer, }: Readonly<ListProps<Item>>): Promise<React.ReactElement>;
|
|
24
|
+
declare function List<Item extends object>({ actions, columns, emptyMessageProps, filters, fn, hasSearch, isMinimal, params, renderItem, transformer, }: Readonly<ListProps<Item>>): Promise<React.ReactElement>;
|
|
24
25
|
export default List;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Fragment } from 'react';
|
|
3
3
|
import { EmptyMessage, tw } from '@sqrzro/components';
|
|
4
|
-
import { headers } from 'next/headers';
|
|
5
4
|
import FilterBar from '../FilterBar';
|
|
6
5
|
import ListItem from '../ListItem';
|
|
7
6
|
function defaultTransformer() {
|
|
@@ -10,14 +9,31 @@ function defaultTransformer() {
|
|
|
10
9
|
title: '',
|
|
11
10
|
};
|
|
12
11
|
}
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
const reservedSearchParams = ['action'];
|
|
13
|
+
function checkHasFilters(searchParams) {
|
|
14
|
+
return Array.from(searchParams.entries()).some(([key, value]) => !reservedSearchParams.includes(key) && Boolean(value));
|
|
15
|
+
}
|
|
16
|
+
async function List({ actions, columns, emptyMessageProps, filters, fn, hasSearch, isMinimal, params, renderItem = ListItem, transformer, }) {
|
|
17
|
+
let searchParams;
|
|
18
|
+
try {
|
|
19
|
+
const { headers } = await import('next/headers');
|
|
20
|
+
searchParams = new URLSearchParams(headers().get('x-search-params') || '');
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
searchParams = new URLSearchParams();
|
|
24
|
+
}
|
|
15
25
|
const [response, error] = await fn(params || {}, searchParams);
|
|
16
26
|
if (error) {
|
|
17
27
|
return _jsx("div", { children: "Error" });
|
|
18
28
|
}
|
|
19
29
|
const data = response.map(transformer || defaultTransformer);
|
|
20
|
-
const hasFilters =
|
|
21
|
-
|
|
30
|
+
const hasFilters = checkHasFilters(searchParams);
|
|
31
|
+
const componentEmptyMessageProps = hasFilters
|
|
32
|
+
? {
|
|
33
|
+
children: 'Try adjusting the filters above. If you think this is a mistake, please contact your site administrator.',
|
|
34
|
+
title: 'No results match the current filters',
|
|
35
|
+
}
|
|
36
|
+
: emptyMessageProps;
|
|
37
|
+
return (_jsxs(Fragment, { children: [(filters || hasSearch) && (data.length || hasFilters) ? (_jsx(FilterBar, { hasSearch: hasSearch, map: filters })) : null, data.length ? (_jsx("ul", { className: tw('relative', columns ? 'grid grid-cols-3 gap-6' : 'flex flex-col gap-4'), children: data.map((item) => renderItem({ actions, ...item })) })) : (_jsx(EmptyMessage, { ...componentEmptyMessageProps, classNameProps: { isMinimal } }))] }));
|
|
22
38
|
}
|
|
23
39
|
export default List;
|
|
@@ -3,15 +3,16 @@ export interface ListObject {
|
|
|
3
3
|
actions?: ({ id }: {
|
|
4
4
|
id: number | string;
|
|
5
5
|
}) => React.ReactElement;
|
|
6
|
+
description?: React.ReactNode | null;
|
|
6
7
|
href?: string;
|
|
7
8
|
id: number | string;
|
|
8
9
|
image?: string | null;
|
|
9
10
|
imageHref?: string | null;
|
|
10
11
|
meta?: React.ReactNode[] | Record<string, React.ReactNode>;
|
|
11
12
|
subtitle?: React.ReactNode | null;
|
|
12
|
-
title
|
|
13
|
+
title?: string;
|
|
13
14
|
}
|
|
14
15
|
export declare function renderMeta(meta: ListObject['meta']): React.ReactElement | null;
|
|
15
16
|
declare function ListItem({ actions: Actions, // eslint-disable-line @typescript-eslint/naming-convention
|
|
16
|
-
href, id, meta, title, }: Readonly<ListObject>): React.ReactElement;
|
|
17
|
+
description, href, id, meta, title, }: Readonly<ListObject>): React.ReactElement;
|
|
17
18
|
export default ListItem;
|
|
@@ -10,7 +10,7 @@ export function renderMeta(meta) {
|
|
|
10
10
|
return (_jsx("table", { className: "w-full text-xs", children: _jsx("tbody", { children: Object.entries(meta).map(([key, value]) => (_jsxs("tr", { className: "odd:bg-slate-100", children: [_jsx("th", { className: "p-2 font-semibold", children: key }), _jsx("td", { className: "p-2 text-right", children: value || '-' })] }, key))) }) }));
|
|
11
11
|
}
|
|
12
12
|
function ListItem({ actions: Actions, // eslint-disable-line @typescript-eslint/naming-convention
|
|
13
|
-
href, id, meta, title, }) {
|
|
14
|
-
return (_jsx("li", { children: _jsxs("article", { className: "bg-panel overflow-hidden rounded p-4 shadow-[0px_0px_0px_1px_rgba(9,9,11,0.07),0px_2px_2px_0px_rgba(9,9,11,0.05)]", children: [_jsx("h2", { className: "border-b border-slate-200 pb-3 text-lg font-semibold", children: href ? _jsx(Link, { href: href, children: title }) : title }), _jsxs("div", { className: "mt-4 flex items-center justify-between", children: [meta ? renderMeta(meta) : null, Actions ? _jsx(Actions, { id: id }) : null] })] }) }));
|
|
13
|
+
description, href, id, meta, title, }) {
|
|
14
|
+
return (_jsx("li", { children: _jsxs("article", { className: "bg-panel overflow-hidden rounded p-4 shadow-[0px_0px_0px_1px_rgba(9,9,11,0.07),0px_2px_2px_0px_rgba(9,9,11,0.05)]", children: [title ? (_jsx("h2", { className: "border-b border-slate-200 pb-3 text-lg font-semibold", children: href ? _jsx(Link, { href: href, children: title }) : title })) : null, description ? (_jsx("div", { className: "border-b border-slate-200 pb-3 ", children: description })) : null, _jsxs("div", { className: "mt-4 flex items-center justify-between", children: [meta ? renderMeta(meta) : null, Actions ? _jsx(Actions, { id: id }) : null] })] }) }));
|
|
15
15
|
}
|
|
16
16
|
export default ListItem;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import MeActions from '../MeActions';
|
|
3
3
|
function MePanel({ user }) {
|
|
4
|
-
return (_jsxs("div", { className: "ml-auto flex items-center gap-3", children: [_jsxs("div", { className: "flex flex-col gap-0.5
|
|
4
|
+
return (_jsxs("div", { className: "ml-auto flex items-center gap-3", children: [_jsxs("div", { className: "flex flex-col items-end gap-0.5 text-white", children: [_jsx("strong", { children: user?.name }), _jsx(MeActions, {})] }), _jsx("div", { className: "h-9 w-9 flex-none rounded-full border-4 border-slate-500" })] }));
|
|
5
5
|
}
|
|
6
6
|
export default MePanel;
|
|
@@ -8,5 +8,5 @@ export interface PageProps {
|
|
|
8
8
|
tabs?: LinkableAction[];
|
|
9
9
|
title: string;
|
|
10
10
|
}
|
|
11
|
-
declare function Page({ basePath, children, isFullWidth, tabs, title, }: Readonly<PageProps>): React.ReactElement
|
|
11
|
+
declare function Page({ basePath, children, isFullWidth, tabs, title, }: Readonly<PageProps>): Promise<React.ReactElement>;
|
|
12
12
|
export default Page;
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Fragment } from 'react';
|
|
3
|
-
import { Container } from '@sqrzro/components';
|
|
3
|
+
import { Container, tw } from '@sqrzro/components';
|
|
4
|
+
import { getLayout } from '../../services/LayoutService';
|
|
4
5
|
import Tabs from '../Tabs';
|
|
5
|
-
function Page({ basePath, children, isFullWidth, tabs, title, }) {
|
|
6
|
-
|
|
6
|
+
async function Page({ basePath, children, isFullWidth, tabs, title, }) {
|
|
7
|
+
const layout = await getLayout();
|
|
8
|
+
return (_jsxs(Fragment, { children: [_jsx("header", { className: tw('', layout === 'sidebar'
|
|
9
|
+
? 'border-b border-slate-200 bg-white'
|
|
10
|
+
: 'bg-slate-800 pb-16 text-white'), children: _jsxs(Container, { isFullWidth: layout === 'sidebar' || isFullWidth, children: [_jsxs("div", { className: "flex items-center justify-between py-10", children: [_jsx("h1", { className: "min-h-10 text-3xl font-semibold", children: title }), _jsx("div", { className: "flex gap-2", id: "page-actions" })] }), tabs ? (_jsx("div", { className: "-mt-4 mb-8", children: _jsx(Tabs, { basePath: basePath, data: tabs }) })) : null] }) }), _jsx(Container, { isFullWidth: layout === 'sidebar' || isFullWidth, children: _jsx("div", { className: tw('flex flex-col gap-8', layout === 'sidebar' ? 'mt-8' : '-mt-16'), children: children }) })] }));
|
|
7
11
|
}
|
|
8
12
|
export default Page;
|
|
@@ -1,2 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
interface SettingsFormFields {
|
|
3
|
+
layout: string;
|
|
4
|
+
}
|
|
5
|
+
interface SettingsFormProps {
|
|
6
|
+
defaults: Partial<SettingsFormFields>;
|
|
7
|
+
}
|
|
8
|
+
declare function SettingsForm({ defaults }: Readonly<SettingsFormProps>): JSX.Element;
|
|
2
9
|
export default SettingsForm;
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import { EditableForm } from '@sqrzro/components';
|
|
3
|
+
import { EditableForm, EditableRadioFormField } from '@sqrzro/components';
|
|
4
4
|
import { useEditableForm } from '@sqrzro/hooks';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
import { submitLayoutForm } from '../../services/LayoutService';
|
|
6
|
+
const options = { sidebar: 'Side bar', topbar: 'Top bar' };
|
|
7
|
+
function SettingsForm({ defaults }) {
|
|
8
|
+
const { fieldProps, formProps } = useEditableForm({
|
|
9
|
+
defaults,
|
|
10
|
+
onSubmit: submitLayoutForm,
|
|
11
|
+
});
|
|
12
|
+
return (_jsx(EditableForm, { title: "Appearance", ...formProps, children: _jsx(EditableRadioFormField, { ...fieldProps('layout'), options: options, renderValue: (value) => (value ? options[value] || '-' : '-') }) }));
|
|
8
13
|
}
|
|
9
14
|
export default SettingsForm;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { getLayout } from '../../services/LayoutService';
|
|
2
3
|
import Page from '../Page';
|
|
3
4
|
import SettingsForm from '../SettingsForm';
|
|
4
|
-
function SettingsPage() {
|
|
5
|
-
|
|
5
|
+
async function SettingsPage() {
|
|
6
|
+
const layout = await getLayout();
|
|
7
|
+
return (_jsx(Page, { title: "Settings", children: _jsx(SettingsForm, { defaults: { layout } }) }));
|
|
6
8
|
}
|
|
7
9
|
export default SettingsPage;
|
|
@@ -7,18 +7,5 @@ function Tabs({ basePath = '', data }) {
|
|
|
7
7
|
return (_jsx("nav", { className: "border-b border-slate-700", children: _jsx("ul", { className: "flex gap-4", children: navigation.map(({ href, isActive, label }) => (_jsx("li", { children: _jsx(Link, { className: tw('block px-1 pb-2 font-semibold', isActive
|
|
8
8
|
? 'border-primary border-b-4 text-white'
|
|
9
9
|
: 'text-white/80 hover:text-white'), href: href, children: label }) }, href))) }) }));
|
|
10
|
-
// return (
|
|
11
|
-
// <nav className="border-y border-slate-700">
|
|
12
|
-
// <ul className="flex gap-4 font-semibold">
|
|
13
|
-
// {data.map(({ href, label }) => (
|
|
14
|
-
// <li key={href}>
|
|
15
|
-
// <Link className="block py-2 text-white" href={`${basePath}${href || ''}`}>
|
|
16
|
-
// {label}
|
|
17
|
-
// </Link>
|
|
18
|
-
// </li>
|
|
19
|
-
// ))}
|
|
20
|
-
// </ul>
|
|
21
|
-
// </nav>
|
|
22
|
-
// );
|
|
23
10
|
}
|
|
24
11
|
export default Tabs;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export { Button, CalendarInput, ConnectedDropdown, DateFormField, DateInput, Dropdown, DropdownFormField, EditableDateFormField, EditableDropdownFormField, EditableForm, EditableFormField, EditableMultiFormField, EditableNumberFormField, EditableSwitchFormField, EditableTextFormField, Fieldset, Form, FormField, FormSubmit, ImageInput, ImageFormField, Link, ModalForm, MultiFormField, NumberFormField, NumberInput, Switch, SwitchFormField, TextFormField, TextInput, Toaster, } from '@sqrzro/components';
|
|
1
|
+
export { Autocomplete, Button, CalendarInput, ConnectedDropdown, ConfirmableButton, DateFormField, DateInput, Dropdown, DropdownFormField, EditableDateFormField, EditableDropdownFormField, EditableForm, EditableFormField, EditableMultiFormField, EditableNumberFormField, EditableSwitchFormField, EditableTextAreaFormField, EditableTextFormField, EmptyMessage, Fieldset, Form, FormField, FormSubmit, ImageInput, ImageFormField, Link, ModalForm, MultiFormField, NumberFormField, NumberInput, RadioInput, Switch, SwitchFormField, TextArea, TextAreaFormField, TextFormField, TextInput, Toaster, } from '@sqrzro/components';
|
|
2
|
+
export type { DropdownItem } from '@sqrzro/components';
|
|
2
3
|
export type { AppLayoutProps } from './AppLayout';
|
|
3
4
|
export { default as AppLayout } from './AppLayout';
|
|
4
5
|
export type { AuthProps } from './Auth';
|
package/dist/components/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Exported from @sqrzro/components
|
|
2
|
-
export { Button, CalendarInput, ConnectedDropdown, DateFormField, DateInput, Dropdown, DropdownFormField, EditableDateFormField, EditableDropdownFormField, EditableForm, EditableFormField, EditableMultiFormField, EditableNumberFormField, EditableSwitchFormField, EditableTextFormField, Fieldset, Form, FormField, FormSubmit, ImageInput, ImageFormField, Link, ModalForm, MultiFormField, NumberFormField, NumberInput, Switch, SwitchFormField, TextFormField, TextInput, Toaster, } from '@sqrzro/components';
|
|
2
|
+
export { Autocomplete, Button, CalendarInput, ConnectedDropdown, ConfirmableButton, DateFormField, DateInput, Dropdown, DropdownFormField, EditableDateFormField, EditableDropdownFormField, EditableForm, EditableFormField, EditableMultiFormField, EditableNumberFormField, EditableSwitchFormField, EditableTextAreaFormField, EditableTextFormField, EmptyMessage, Fieldset, Form, FormField, FormSubmit, ImageInput, ImageFormField, Link, ModalForm, MultiFormField, NumberFormField, NumberInput, RadioInput, Switch, SwitchFormField, TextArea, TextAreaFormField, TextFormField, TextInput, Toaster, } from '@sqrzro/components';
|
|
3
3
|
export { default as AppLayout } from './AppLayout';
|
|
4
4
|
export { default as Auth } from './Auth';
|
|
5
5
|
export { default as Badge } from './Badge';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SerializedErrorable } from '@sqrzro/interfaces';
|
|
2
|
+
type Layout = 'sidebar' | 'topbar';
|
|
3
|
+
export declare function getLayout(): Promise<string>;
|
|
4
|
+
export declare function submitLayoutForm(formData: {
|
|
5
|
+
layout: Layout;
|
|
6
|
+
}): Promise<SerializedErrorable<boolean>>;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use server';
|
|
2
|
+
import { cookies } from 'next/headers';
|
|
3
|
+
export async function getLayout() {
|
|
4
|
+
return Promise.resolve(cookies().get('layout')?.value || 'topbar');
|
|
5
|
+
}
|
|
6
|
+
export async function submitLayoutForm(formData) {
|
|
7
|
+
cookies().set('layout', formData.layout);
|
|
8
|
+
return Promise.resolve([true, null]);
|
|
9
|
+
}
|
package/dist/styles/config.js
CHANGED
|
@@ -8,7 +8,7 @@ const classNames = twx({
|
|
|
8
8
|
root: {
|
|
9
9
|
danger: 'border-red-500 bg-red-500 text-white',
|
|
10
10
|
default: tw('text-md h-10 rounded border border-slate-300 bg-white px-5 text-slate-600', props?.isFullWidth ? 'w-full' : null),
|
|
11
|
-
primary: 'bg-button-bg text-button-text border-none font-semibold',
|
|
11
|
+
primary: 'bg-button-bg text-button-text border-none font-semibold',
|
|
12
12
|
},
|
|
13
13
|
}),
|
|
14
14
|
calendar: () => ({
|
|
@@ -30,12 +30,13 @@ const classNames = twx({
|
|
|
30
30
|
codeInput: () => ({
|
|
31
31
|
input: {
|
|
32
32
|
default: 'focus:border-primary h-10 rounded border border-slate-300 text-center',
|
|
33
|
-
error: 'border-red-
|
|
33
|
+
error: 'border-red-500',
|
|
34
34
|
},
|
|
35
35
|
}),
|
|
36
36
|
editableFieldset: () => ({
|
|
37
|
-
root: 'bg-panel grid grid-cols-[30%_1fr] rounded p-8 shadow',
|
|
37
|
+
root: 'bg-panel grid grid-cols-[30%_1fr] gap-8 rounded p-8 shadow',
|
|
38
38
|
title: 'mb-8 text-lg font-semibold leading-none text-slate-700',
|
|
39
|
+
description: 'text-slate-600',
|
|
39
40
|
actions: 'flex justify-end gap-2 border-t border-slate-200 pt-4',
|
|
40
41
|
}),
|
|
41
42
|
editableFormField: () => ({
|
|
@@ -43,9 +44,12 @@ const classNames = twx({
|
|
|
43
44
|
label: 'flex items-center font-semibold leading-none',
|
|
44
45
|
field: 'flex min-h-10 items-center',
|
|
45
46
|
}),
|
|
46
|
-
emptyMessage: () => ({
|
|
47
|
-
root: 'relative mx-auto mt-4 w-full max-w-
|
|
48
|
-
|
|
47
|
+
emptyMessage: (props) => ({
|
|
48
|
+
root: tw('relative mx-auto mt-4 w-full max-w-2xl p-16 text-center text-slate-500', props?.isMinimal
|
|
49
|
+
? null
|
|
50
|
+
: 'rounded bg-white shadow before:pointer-events-none before:absolute before:inset-2 before:border-2 before:border-dashed'),
|
|
51
|
+
title: 'mb-2 text-pretty text-xl font-semibold leading-tight',
|
|
52
|
+
description: 'text-pretty',
|
|
49
53
|
action: 'mt-6 flex justify-center',
|
|
50
54
|
}),
|
|
51
55
|
dropdown: () => ({
|
|
@@ -69,7 +73,7 @@ const classNames = twx({
|
|
|
69
73
|
label: tw('flex font-semibold leading-none', props?.isEditable ? 'items-center' : 'mb-2 justify-between'),
|
|
70
74
|
details: 'mb-2 text-xs font-normal leading-none text-slate-500',
|
|
71
75
|
optional: 'pl-2 text-xs font-normal leading-none text-slate-500',
|
|
72
|
-
error: 'mt-2 flex items-center gap-2 text-red-700 before:h-4 before:w-4 before:rounded-full before:bg-[url(/images/
|
|
76
|
+
error: 'mt-2 flex items-center gap-2 text-red-700 before:h-4 before:w-4 before:rounded-full before:bg-[url(/admin/images/error.svg)]',
|
|
73
77
|
}),
|
|
74
78
|
imageInput: () => ({
|
|
75
79
|
root: 'h-64 rounded border border-slate-300 bg-slate-50 p-8',
|
|
@@ -99,7 +103,7 @@ const classNames = twx({
|
|
|
99
103
|
staticTextInput: () => ({
|
|
100
104
|
root: {
|
|
101
105
|
default: 'text-md h-10 rounded border border-slate-300 bg-white px-3',
|
|
102
|
-
error: 'border-red-
|
|
106
|
+
error: 'border-red-500',
|
|
103
107
|
},
|
|
104
108
|
}),
|
|
105
109
|
switch: () => ({
|
|
@@ -118,7 +122,7 @@ const classNames = twx({
|
|
|
118
122
|
textArea: () => ({
|
|
119
123
|
root: {
|
|
120
124
|
default: 'text-md focus:border-primary rounded border border-slate-300 px-3 py-2',
|
|
121
|
-
error: 'border-red-
|
|
125
|
+
error: 'border-red-500',
|
|
122
126
|
},
|
|
123
127
|
}),
|
|
124
128
|
textButton: () => ({
|
|
@@ -127,7 +131,7 @@ const classNames = twx({
|
|
|
127
131
|
textInput: () => ({
|
|
128
132
|
root: {
|
|
129
133
|
default: 'text-md focus:border-primary h-10 rounded border border-slate-300 px-3',
|
|
130
|
-
error: 'border-red-
|
|
134
|
+
error: 'border-red-500',
|
|
131
135
|
},
|
|
132
136
|
}),
|
|
133
137
|
toast: () => ({
|