@sqrzro/admin 4.0.0-alpha.0 → 4.0.0-alpha.2

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.
@@ -1,7 +1,8 @@
1
- import type { AdminConfig } from '../../utility/interfaces';
1
+ import type { AdminConfig, User } from '../../utility/interfaces';
2
2
  interface AdminAppLayoutProps {
3
3
  readonly children: React.ReactNode;
4
4
  readonly config?: AdminConfig;
5
+ readonly userFn?: () => Promise<User>;
5
6
  }
6
- declare function AdminAppLayout({ children, config }: AdminAppLayoutProps): React.ReactElement;
7
+ declare function AdminAppLayout({ children, config, userFn }: AdminAppLayoutProps): React.ReactElement;
7
8
  export default AdminAppLayout;
@@ -1,7 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Suspense } from 'react';
2
3
  import { Link } from '@sqrzro/ui/components';
3
4
  import { AppNavigation } from '@sqrzro/ui/navigation';
4
- function AdminAppLayout({ children, config }) {
5
- return (_jsxs("div", { className: "flex flex-1 flex-col", children: [_jsx("header", { className: "bg-slate-800", children: _jsxs("div", { className: "flex h-16 items-center border-b border-slate-700 px-4", children: [_jsx(Link, { className: "h-9 w-9", href: "/", children: _jsx("span", { className: "sr-only", children: config?.app.name }) }), _jsx(AppNavigation, { data: config?.navigation || [] })] }) }), _jsx("main", { className: "@container mb-10 block flex flex-1 flex-col", children: children })] }));
5
+ import MePanel from '../MePanel';
6
+ function AdminAppLayout({ children, config, userFn }) {
7
+ return (_jsxs("div", { className: "flex flex-1 flex-col", children: [_jsx("header", { className: "bg-slate-800", children: _jsxs("div", { className: "flex h-16 items-center border-b border-slate-700 px-4", children: [_jsx(Link, { className: "h-9 w-9", href: "/", children: _jsx("span", { className: "sr-only", children: config?.app.name }) }), _jsx(AppNavigation, { data: config?.navigation || [] }), _jsx(Suspense, { children: _jsx(MePanel, { userFn: userFn }) })] }) }), _jsx("main", { className: "@container mb-10 block flex flex-1 flex-col", children: children })] }));
6
8
  }
7
9
  export default AdminAppLayout;
@@ -0,0 +1,7 @@
1
+ import type { PageProps } from '@sqrzro/ui/components';
2
+ import { NextLayoutProps } from '@sqrzro/ui/utility';
3
+ export type AdminLayoutProps<T> = Omit<PageProps<T>, 'children' | 'pageProps' | 'template'> & {
4
+ readonly layoutProps: NextLayoutProps;
5
+ };
6
+ declare function AdminLayout<T>(props: Readonly<AdminLayoutProps<T>>): React.ReactElement;
7
+ export default AdminLayout;
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Page } from '@sqrzro/ui/components';
3
+ import AdminPageComponent from '../AdminPageComponent';
4
+ function AdminLayout(props) {
5
+ return (_jsx(Page, { ...props, children: props.layoutProps.children, pageProps: props.layoutProps, template: (templateProps) => _jsx(AdminPageComponent, { ...templateProps }) }));
6
+ }
7
+ export default AdminLayout;
@@ -1,6 +1,4 @@
1
- interface AdminPageProps {
2
- readonly children: React.ReactNode;
3
- readonly title: string;
4
- }
5
- declare function AdminPage({ children, title }: AdminPageProps): React.ReactElement;
1
+ import type { PageProps } from '@sqrzro/ui/components';
2
+ export type AdminPageProps<T> = Omit<PageProps<T>, 'template'>;
3
+ declare function AdminPage<T>(props: Readonly<AdminPageProps<T>>): React.ReactElement;
6
4
  export default AdminPage;
@@ -1,7 +1,7 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Fragment } from 'react';
3
- import { Container } from '@sqrzro/ui/components';
4
- function AdminPage({ children, title }) {
5
- return (_jsxs(Fragment, { children: [_jsx("header", { className: "bg-slate-800 pb-16 text-white", children: _jsx(Container, { children: _jsxs("div", { className: "flex items-center justify-between py-10", children: [_jsx("h1", { className: "flex min-h-10 items-center text-3xl font-semibold", children: title }), _jsx("div", { className: "flex gap-2", id: "page-actions" })] }) }) }), _jsx(Container, { children: _jsx("div", { className: "@container -mt-16 flex flex-col gap-8", children: children }) })] }));
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Page } from '@sqrzro/ui/components';
3
+ import AdminPageComponent from '../AdminPageComponent';
4
+ function AdminPage(props) {
5
+ return (_jsx(Page, { ...props, template: (templateProps) => _jsx(AdminPageComponent, { ...templateProps }) }));
6
6
  }
7
7
  export default AdminPage;
@@ -0,0 +1,8 @@
1
+ import { NavigationObject } from '@sqrzro/ui/navigation';
2
+ interface AdminPageComponentProps {
3
+ children: React.ReactNode;
4
+ tabs: NavigationObject[] | null;
5
+ title: React.ReactNode;
6
+ }
7
+ declare function AdminPageComponent({ children, tabs, title, }: Readonly<AdminPageComponentProps>): React.ReactElement;
8
+ export default AdminPageComponent;
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Fragment } from 'react';
3
+ import { Container } from '@sqrzro/ui/components';
4
+ import { Tabs } from '@sqrzro/ui/navigation';
5
+ function AdminPageComponent({ children, tabs, title, }) {
6
+ return (_jsxs(Fragment, { children: [_jsx("header", { className: "bg-slate-800 pb-16 text-white", children: _jsxs(Container, { children: [_jsxs("div", { className: "flex items-center justify-between py-10", children: [_jsx("h1", { className: "flex min-h-10 items-center text-3xl font-semibold", children: title }), _jsx("div", { className: "flex gap-2", id: "page-actions" })] }), tabs ? _jsx(Tabs, { data: tabs }) : null] }) }), _jsx(Container, { children: _jsx("div", { className: "@container -mt-16 flex flex-col gap-8", children: children }) })] }));
7
+ }
8
+ export default AdminPageComponent;
@@ -0,0 +1,6 @@
1
+ import type { User } from '../../utility/interfaces';
2
+ interface MePanelProps {
3
+ readonly userFn?: () => Promise<User>;
4
+ }
5
+ declare function MePanel({ userFn }: MePanelProps): Promise<React.ReactElement | null>;
6
+ export default MePanel;
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { LogoutButton } from '@sqrzro/auth';
3
+ async function MePanel({ userFn }) {
4
+ const user = await userFn?.();
5
+ 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("div", { className: "text-xs text-slate-300", children: _jsx(LogoutButton, {}) })] }), _jsx("div", { className: "h-9 w-9 flex-none rounded-full border-4 border-slate-500" })] }));
6
+ }
7
+ export default MePanel;
package/dist/config.js CHANGED
@@ -1,5 +1,10 @@
1
- import { twx } from '@sqrzro/ui/styles';
1
+ import { tw, twx } from '@sqrzro/ui/styles';
2
+ const showClosed = 'transition-discrete transition-all duration-100 invisible opacity-0 ease-in-out scale-90';
3
+ const showOpen = 'starting:opacity-0 starting:scale-90 visible opacity-100 scale-100';
2
4
  const classNames = twx({
5
+ actionList: {
6
+ root: tw('flex items-center gap-2 [&_li]:first:mr-auto'),
7
+ },
3
8
  appNavigation: {
4
9
  root: 'h-full pl-6',
5
10
  list: 'flex h-full items-center gap-4',
@@ -21,15 +26,41 @@ const classNames = twx({
21
26
  container: {
22
27
  root: 'mx-auto w-full max-w-6xl px-8',
23
28
  },
29
+ dropdown: {
30
+ item: {
31
+ default: 'block border-b border-slate-100 p-3 text-sm text-slate-700',
32
+ selected: 'bg-slate-100',
33
+ },
34
+ },
24
35
  editableForm: {
25
36
  root: 'grid grid-cols-[25%_1fr] gap-20 rounded bg-white p-8 shadow',
26
37
  title: 'mb-8 text-lg font-semibold leading-none text-slate-700',
27
38
  description: 'text-slate-600',
28
39
  actions: 'flex justify-end gap-2 border-t border-slate-200 pt-4',
29
40
  },
41
+ editableFormField: {
42
+ root: 'grid grid-cols-[30%_1fr] gap-x-4 border-t border-slate-200 py-4',
43
+ label: 'flex items-center font-semibold',
44
+ field: 'col-start-2 flex min-h-10 items-center overflow-hidden',
45
+ },
46
+ filterBar: {
47
+ root: 'bg-red-500',
48
+ },
49
+ form: {
50
+ root: 'flex flex-col gap-6',
51
+ },
52
+ formField: {
53
+ label: 'mb-2 flex justify-between font-semibold leading-none',
54
+ details: 'mb-2 text-xs font-normal text-slate-500',
55
+ optional: 'pl-2 text-xs font-normal leading-none text-slate-500',
56
+ error: 'text-error mt-2 flex items-start gap-1.5 before:mt-0.5 before:h-4 before:w-4 before:flex-none before:rounded-full before:bg-[url(/admin/images/danger.svg)] before:bg-contain',
57
+ },
58
+ listItem: {
59
+ root: { default: 'bg-red-500' },
60
+ },
30
61
  modal: {
31
62
  root: 'starting:open:backdrop:opacity-0 py-16 backdrop:bg-slate-700/50 backdrop:transition-all backdrop:duration-500 open:backdrop:opacity-100',
32
- panel: 'show row-start-2 mx-auto flex w-full max-w-lg flex-col gap-6 rounded bg-white p-6 shadow-xl',
63
+ panel: `${showOpen} row-start-2 mx-auto flex w-full max-w-lg flex-col gap-6 rounded bg-white p-6 shadow-xl`,
33
64
  content: 'flex flex-col gap-6 [&_p]:text-pretty',
34
65
  icon: 'text-slate-400',
35
66
  title: 'flex items-center gap-2 border-b border-slate-200 pb-6 text-lg font-semibold',
@@ -45,10 +76,54 @@ const classNames = twx({
45
76
  gap: 'flex h-9 w-9 items-center justify-center text-xs text-slate-400',
46
77
  navigation: 'inline-flex h-9 items-center justify-center gap-1 whitespace-nowrap rounded-md px-4 py-2 text-sm font-medium hover:bg-slate-100',
47
78
  },
79
+ popover: {
80
+ root: {
81
+ default: `${showClosed} z-20 my-1.5 w-full rounded border border-slate-300 bg-white text-slate-700 shadow-md`,
82
+ focused: `${showOpen}`,
83
+ },
84
+ },
48
85
  rootLayout: {
49
86
  root: 'overflow-x-hidden overflow-y-scroll bg-slate-50 font-sans text-sm text-slate-800 has-[[data-modal][open]]:overflow-hidden',
50
87
  content: 'flex min-h-screen flex-col',
51
88
  },
89
+ staticTextInput: {
90
+ root: {
91
+ default: 'text-md flex min-h-10 flex-col justify-center rounded border border-slate-300 bg-white p-3',
92
+ error: 'border-red-500',
93
+ },
94
+ label: 'block leading-none',
95
+ meta: 'mt-1.5 block text-xs leading-none text-slate-500',
96
+ placeholder: 'block leading-none text-slate-400',
97
+ },
98
+ switch: {
99
+ root: tw('flex', 'gap-4'),
100
+ control: tw('relative flex-none', 'h-6 w-10'),
101
+ input: {
102
+ default: tw('block h-full w-full cursor-pointer rounded-full transition-colors', 'bg-slate-300'),
103
+ checked: tw('bg-primary'),
104
+ },
105
+ icon: {
106
+ default: tw('pointer-events-none absolute top-1/2 -translate-y-1/2 translate-x-0 transform rounded-full transition-transform duration-100', 'left-1 h-4 w-4 bg-white shadow-md'),
107
+ checked: tw('translate-x-full'),
108
+ },
109
+ label: 'flex min-h-6 flex-col justify-center',
110
+ details: 'mt-1 block text-xs text-slate-500',
111
+ },
112
+ table: {
113
+ root: 'rounded bg-white p-8 shadow',
114
+ row: {
115
+ default: 'odd:bg-slate-100',
116
+ },
117
+ cell: 'p-4',
118
+ },
119
+ tabs: {
120
+ root: '-mt-4 mb-8 border-b border-slate-700',
121
+ list: 'flex gap-4',
122
+ link: {
123
+ default: 'block border-b-4 border-transparent px-1 pb-2 font-semibold opacity-80 hover:opacity-100',
124
+ highlighted: 'border-primary opacity-100',
125
+ },
126
+ },
52
127
  textInput: {
53
128
  root: {
54
129
  default: 'text-md focus:border-primary h-10 rounded border border-slate-300 px-3 placeholder-slate-400',
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from './utility/interfaces';
2
2
  export { default as classNames } from './config';
3
3
  export { default as AdminAppLayout } from './components/AdminAppLayout';
4
+ export { default as AdminLayout } from './components/AdminLayout';
4
5
  export { default as AdminPage } from './components/AdminPage';
5
6
  export { default as AdminPageActions } from './components/AdminPageActions';
6
7
  export { default as AdminRootLayout } from './components/AdminRootLayout';
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from './utility/interfaces';
2
2
  export { default as classNames } from './config';
3
3
  export { default as AdminAppLayout } from './components/AdminAppLayout';
4
+ export { default as AdminLayout } from './components/AdminLayout';
4
5
  export { default as AdminPage } from './components/AdminPage';
5
6
  export { default as AdminPageActions } from './components/AdminPageActions';
6
7
  export { default as AdminRootLayout } from './components/AdminRootLayout';
@@ -6,3 +6,7 @@ export interface AdminConfig {
6
6
  };
7
7
  navigation: NavigationObject[];
8
8
  }
9
+ export interface User {
10
+ id: string;
11
+ name: string;
12
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sqrzro/admin",
3
3
  "type": "module",
4
- "version": "4.0.0-alpha.0",
4
+ "version": "4.0.0-alpha.2",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "license": "ISC",
@@ -9,10 +9,11 @@
9
9
  "dist/**/*"
10
10
  ],
11
11
  "dependencies": {
12
- "next": "^16.0.8",
13
- "react": "^19.2.1",
12
+ "next": "^16.1.6",
13
+ "react": "^19.2.4",
14
14
  "react-dom": "^19.2.1",
15
- "@sqrzro/ui": "^4.0.0-alpha.0"
15
+ "@sqrzro/ui": "^4.0.0-alpha.5",
16
+ "@sqrzro/auth": "^4.0.0-alpha.5"
16
17
  },
17
18
  "devDependencies": {
18
19
  "@types/react": "^19.2.7",
@@ -22,7 +23,7 @@
22
23
  "rimraf": "^6.1.2",
23
24
  "tsc-alias": "^1.8.16",
24
25
  "typescript": "^5.9.3",
25
- "@sqrzro/prettier-config": "^4.0.0-alpha.0"
26
+ "@sqrzro/prettier-config": "^4.0.0-alpha.1"
26
27
  },
27
28
  "scripts": {
28
29
  "build": "pnpm clean && tsc -p tsconfig.build.json && tsc-alias",