Skip to content

Commit 5f2d567

Browse files
committed
docs: landing gallery shows adapted plugins and core screens as HTML previews in the design system instead of old screenshots, two cards per row so they stay readable; adoption.md asks to redraw the card after adapting a plugin AdminForth/2005
1 parent b6df7dd commit 5f2d567

38 files changed

Lines changed: 2110 additions & 29 deletions

‎adminforth/design/adoption.md‎

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,35 @@ Which packages follow the [design concepts](./system-concepts.md): tokens instea
2525
| @adminforth/json-form | |
2626
| @adminforth/list-in-place-edit | ✓ |
2727
| @adminforth/login-captcha | |
28-
| @adminforth/many2many | |
29-
| @adminforth/markdown | |
28+
| @adminforth/many2many | ✓ |
29+
| @adminforth/markdown | ✓ |
3030
| @adminforth/mcp | ✓ |
3131
| @adminforth/oauth | ✓ |
3232
| @adminforth/open-signup | |
3333
| @adminforth/quick-filters | ✓ |
34-
| @adminforth/rich-editor | |
34+
| @adminforth/rich-editor | ✓ |
3535
| @adminforth/text-complete | ✓ |
3636
| @adminforth/two-factors-auth | ✓ |
3737
| @adminforth/universal-search | ✓ |
38-
| @adminforth/upload | |
38+
| @adminforth/upload | ✓ |
3939
| @adminforth/user-sessions | ✓ |
4040
| @adminforth/user-soft-delete | |
4141

4242
## Releasing an adapted plugin
4343

4444
- Moving a plugin to the design system makes it depend on adminforth 4 (AFCL components and Lucide icons ship with it), so apps on adminforth 3 must not get it with an update: set `peerDependencies.adminforth` to `^4.0.0` and commit with a `BREAKING CHANGE:` footer, semantic-release then publishes a new major (it ignores `feat!:`). Bump `devDependencies.adminforth` together with the lockfile once 4.0.0 is on npm, earlier `pnpm install --frozen-lockfile` fails on CI.
4545
- Roll the release out to the live demo right away: bump the plugin (and `adminforth`, when the plugin needs a newer core) in `live-demo/app/package.json` and push to `main`, the push rebuilds demo.adminforth.dev.
46+
- Redraw the card of the plugin on the landing page, if it has one, in the design system.
47+
48+
## Landing page previews
49+
50+
The cards of the landing gallery (`documentation/src/pages/index.tsx`) show either a PNG screenshot (`original`) or a static HTML page of `documentation/static/landing-previews` (`preview: '<file>'`) drawn in the design system. A plugin moves to `preview` once it is adapted.
51+
52+
- Draw the screen of the plugin's core feature, not the whole page: keep one key element (an open menu, a form field, a dialog) and drop the columns, fields and buttons which don't explain the feature. A card is about 440px wide, so a screen with every column of the real page is unreadable.
53+
- Copy the closest page (a list, an edit form, a settings tab) and take the markup, texts, Lucide icons and tokens from the components of the plugin, the shared classes are in `previews.css`.
54+
- The screen is drawn at a fixed size of 16:10 in `.screen`, 880×550 by default, a smaller one makes the text bigger. `previews.js` scales it to the card, follows the light/dark switch of the landing page and draws the sidebar (`<aside class="side" data-active="Apartments">`).
55+
- Icons come from the sprite `icons.svg` (`<svg class="i"><use href="icons.svg#pencil"/></svg>`), add a missing Lucide icon there as a `<symbol>`. Flags are the SVGs of `flag-icons`, small images are JPEGs in the folder.
56+
- Check the page in both themes at the size of the card before the commit.
4657

4758
## Left in core
4859

@@ -54,5 +65,5 @@ Which packages follow the [design concepts](./system-concepts.md): tokens instea
5465

5566
- If simple - get of flowbite, prefer pure AFCL + Tailwind, move features we luck to AFCL
5667
- Existing icon fonts apart lucide - try to get rid of them if not complex
57-
- Core uses only Lucide icons and `flag-icons` flags (`afcl/CountryFlag.vue`). `vue-flowbite` and `vue-heroicons` stay in `spa/package.json` while plugins import them (flowbite: bulk-ai-flow, clone-row, email-invite, email-password-reset, foreign-inline-list, inline-create, json-editor, markdown, open-signup, user-soft-delete, and dashboard only for `flowbite:chart-pie-solid`, the old default menu icon which stored dashboard configs may name; heroicons: markdown). After plugins rework it they should disappear.
68+
- Core uses only Lucide icons and `flag-icons` flags (`afcl/CountryFlag.vue`). `vue-flowbite` and `vue-heroicons` stay in `spa/package.json` while plugins import them (flowbite: bulk-ai-flow, clone-row, email-invite, email-password-reset, foreign-inline-list, inline-create, json-editor, open-signup, user-soft-delete, and dashboard only for `flowbite:chart-pie-solid`, the old default menu icon which stored dashboard configs may name; no plugin imports heroicons any more). After plugins rework it they should disappear.
5869
- i18n shows language flags with its own `flag-icon-css`, a 445 KB stylesheet loaded on every page: move `LanguageFlag.vue` to AFCL `CountryFlag`.

‎documentation/src/pages/index.module.css‎

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -657,9 +657,10 @@
657657

658658
/* --- gallery of what it can do -------------------------------------------- */
659659

660+
/* two columns at most: the screens in the cards stay big enough to read */
660661
.gallery {
661662
display: grid;
662-
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
663+
grid-template-columns: repeat(auto-fit, minmax(min(360px, 100%), 1fr));
663664
gap: 22px;
664665
}
665666

@@ -672,12 +673,22 @@
672673
flex-direction: column;
673674
}
674675

675-
.gcard img {
676+
.gcard img,
677+
.gcard iframe {
676678
display: block;
677679
width: 100%;
678680
border-bottom: 1px solid var(--line);
679681
}
680682

683+
/* a drawn screen is a picture: no focus, clicks and scroll stay with the page */
684+
.gcard iframe {
685+
aspect-ratio: 16 / 10;
686+
border-top: 0;
687+
border-right: 0;
688+
border-left: 0;
689+
pointer-events: none;
690+
}
691+
681692
.gcardBody {
682693
padding: 16px 18px 18px;
683694
display: flex;

‎documentation/src/pages/index.tsx‎

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Head from '@docusaurus/Head';
22
import Link from '@docusaurus/Link';
3+
import {useBaseUrlUtils} from '@docusaurus/useBaseUrl';
34
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
45
import Layout from '@theme/Layout';
56
import Heading from '@theme/Heading';
@@ -63,46 +64,48 @@ const FEATURED_ON = [
6364

6465
type PluginItem = {name: string; slug: string; description: string; standard?: string};
6566
type PluginGroup = {title: string; items: PluginItem[]};
67+
// a card shows a screenshot (original) or a page of static/landing-previews drawn in the design system (preview)
68+
type GalleryItem = {title: string; link: string; description: string; original?: string; preview?: string};
6669

67-
const images = [
70+
const images: GalleryItem[] = [
6871
{
69-
original: require('@site/static/img/previews/login_form.png').default,
72+
preview: 'login',
7073
title: 'Authentication and Authorization',
7174
link: '/docs/tutorial/gettingStarted',
7275
description: 'OWASP-Compliant Sign-In done for you'
7376
},
7477
{
75-
original: require('@site/static/img/previews/sso.png').default,
78+
preview: 'oauth',
7679
title: 'OAuth2/OpenID SSO Plugin - one click login',
7780
link: '/docs/tutorial/Plugins/oauth/',
7881
description: 'RFC 6749 SSO plugin with premade Google, Github, Facebook, Keycloak, Microsoft or any custom OAuth2 adapter'
7982
},
8083
{
81-
original: require('@site/static/img/previews/2fa_plugin.png').default,
84+
preview: 'two-factors-auth',
8285
title: '2FA Plugin - secure your admin panel',
8386
link: '/docs/tutorial/Plugins/two-factors-auth/',
8487
description: 'RFC 6238-Compliant TOTP-Based & WebAuthn PassKeys 2FA will add additional security layer (login and preferred actions)'
8588
},
8689
{
87-
original: require('@site/static/img/previews/user_sessions.png').default,
90+
preview: 'user-sessions',
8891
title: 'User Sessions Plugin - revoke access from any device',
8992
link: '/docs/tutorial/Plugins/user-sessions/',
9093
description: 'Every browser signed into the panel, with IP, country and last use, revocable in one click and really signed out on logout'
9194
},
9295
{
93-
original: require('@site/static/img/previews/branding.png').default,
96+
preview: 'branding',
9497
title: 'Branding and theming',
9598
link: '/docs/tutorial/Customization/branding/',
9699
description: 'Upload your logo, change colors, update titles, make the look to match your brand'
97100
},
98101
{
99-
original: require('@site/static/img/previews/dashboard.png').default,
102+
preview: 'custom-pages',
100103
title: 'Custom Pages and Dashboards',
101104
link: '/docs/tutorial/Customization/customPages/',
102105
description: 'Create your own pages and dashboards with Vue3 components. Add any additional npm packages and extend your admin panel as you like'
103106
},
104107
{
105-
original: require('@site/static/img/previews/users_management.png').default,
108+
preview: 'users',
106109
title: 'Users management',
107110
link: '/docs/tutorial/gettingStarted',
108111
description: 'Manage users and roles with ease, extend as you like'
@@ -114,44 +117,44 @@ const images = [
114117
description: 'Use LLMs to translate any external apps (Mobile, Nuxt, etc.) OR/AND admin panel with minimal effort. Any language supported'
115118
},
116119
{
117-
original: require('@site/static/img/previews/auditlog.png').default,
120+
preview: 'audit-log',
118121
title: 'Audit log Plugin - know who did what',
119122
link: '/docs/tutorial/Plugins/audit-log/',
120123
description: 'Attach Audit log plugin with couple of lines, create table for logs and track full history of any data changes'
121124
},
122125
{
123-
original: require('@site/static/img/previews/ai_complete.png').default,
126+
preview: 'text-complete',
124127
title: 'AI autocomplete Plugin - write with LLMs',
125128
link: '/docs/tutorial/Plugins/text-complete/',
126129
description: 'Provide your LLM API key to autocomplete plugin and AI will help you to write your content using record context'
127130
},
128131
{
129-
original: require('@site/static/img/previews/dark.png').default,
132+
preview: 'dark-mode',
130133
title: 'Dark mode out of the box',
131134
link: '/docs/tutorial/gettingStarted',
132135
description: 'Dark mode is enabled by default, create your own components in Tailwind-way and it will work with no additional friction'
133136
},
134137
{
135-
original: require('@site/static/img/previews/upload.png').default,
138+
preview: 'upload',
136139
title: 'Upload Plugin - upload files',
137140
link: '/docs/tutorial/Plugins/upload/',
138141
description: 'Upload files to Amazon S3 with instantiating plugin and providing your S3 credentials'
139142
},
140143

141144
{
142-
original: require('@site/static/img/previews/filters.png').default,
145+
preview: 'filters',
143146
title: 'Filters to query your data',
144147
link: '/docs/tutorial/Customization/virtualColumns/#virtual-columns-for-filtering',
145148
description: 'AdminForth provides basic filters out of the box and allows you to create your own'
146149
},
147150
{
148-
original: require('@site/static/img/previews/richeditor.png').default,
151+
preview: 'rich-editor',
149152
title: 'Rich Editor Plugin - WYSIWYG',
150153
link: '/docs/tutorial/Plugins/rich-editor/',
151154
description: 'Attach Rich Editor plugin to your text fields and get WYSIWYG editor for your content'
152155
},
153156
{
154-
original: require('@site/static/img/previews/inplace-edit.png').default,
157+
preview: 'list-in-place-edit',
155158
title: 'List in-place edit Plugin for quick edit',
156159
link: '/docs/tutorial/Plugins/list-in-place-edit/',
157160
description: 'Edit some oftenly used fields in list directly without opening edit page. Decide which fields to be editable in list view'
@@ -163,7 +166,7 @@ const images = [
163166
description: 'For tables with small fields number which should be created massively, use inline create plugin to create records directly in list view'
164167
},
165168
{
166-
original: require('@site/static/img/previews/importexport.png').default,
169+
preview: 'import-export',
167170
title: 'Import/Export CSV Plugin',
168171
link: '/docs/tutorial/Plugins/import-export/',
169172
description: 'Export tables to CSV and import from CSV with one click. Move data between environments easily'
@@ -175,31 +178,31 @@ const images = [
175178
description: 'Use LLMs to fill records with generated data or images. For example, generate product descriptions based on product name and image or generate products images'
176179
},
177180
{
178-
original: require('@site/static/img/previews/quick-filters.png').default,
181+
preview: 'quick-filters',
179182
title: 'Quick Filters Plugin - filter your data quickly',
180183
link: '/docs/tutorial/Plugins/quick-filters/',
181184
description: 'Use quick filters to filter your data efficiently. Create custom filters and apply them with a single click'
182185
},
183186
{
184-
original: require('@site/static/img/previews/background-jobs1.png').default,
187+
preview: 'background-jobs',
185188
title: 'Background Jobs Plugin - manage your background tasks',
186189
link: '/docs/tutorial/Plugins/background-jobs/',
187190
description: 'Use background jobs to handle long-running tasks efficiently. Schedule, monitor, and manage your background processes with ease even after server restarts'
188191
},
189192
{
190-
original: require('@site/static/img/previews/agent.png').default,
193+
preview: 'agent',
191194
title: 'Agent Plugin - give AI any task and let it handle it',
192195
link: '/docs/tutorial/Plugins/agent/',
193196
description: 'Provides an internal agent that can perform various tasks based on natural language instructions. Connect it to your data and let it help you with content generation, data management, or any custom use case you can think of'
194197
},
195198
{
196-
original: require('@site/static/img/previews/mcp.png').default,
199+
preview: 'mcp',
197200
title: 'MCP Server Plugin - plug your admin into coding agents',
198201
link: '/docs/tutorial/Plugins/mcp/',
199202
description: 'Expose AdminForth resources and actions as remote MCP tools for Claude Code, OpenAI Codex, Gemini CLI and any other MCP client. Every call runs as the AdminForth user who created the auth secret, so your resource permissions, validation and hooks still apply'
200203
},
201204
{
202-
original: require('@site/static/img/previews/dashboards-plugin.png').default,
205+
preview: 'dashboard',
203206
title: 'Dashboard Plugin - creare custom dashboards from web interface',
204207
link: '/docs/tutorial/Plugins/dashboard/',
205208
description: 'Provides a customizable dashboard plugin that allows you to create and manage dashboards for your data. Connect it to your resources and visualize your data in a meaningful way'
@@ -531,6 +534,7 @@ function Watch(): JSX.Element {
531534
}
532535

533536
function Gallery(): JSX.Element {
537+
const {withBaseUrl} = useBaseUrlUtils();
534538
return (
535539
<Section eyebrow="In the panel" note="What ships, and what a plugin adds on top.">
536540
<Heading as="h2" className={styles.h2}>What it can do for you.</Heading>
@@ -540,7 +544,16 @@ function Gallery(): JSX.Element {
540544
<div className={styles.gallery}>
541545
{images.map((item, index) => (
542546
<div className={styles.gcard} key={`feature${index}`}>
543-
<img src={item.original} alt={item.title} title={item.title} loading="lazy" />
547+
{item.preview ? (
548+
<iframe
549+
src={withBaseUrl(`/landing-previews/${item.preview}.html`)}
550+
title={item.title}
551+
loading="lazy"
552+
tabIndex={-1}
553+
/>
554+
) : (
555+
<img src={item.original} alt={item.title} title={item.title} loading="lazy" />
556+
)}
544557
<div className={styles.gcardBody}>
545558
<Heading as="h3" className={styles.gcardTitle}>{item.title}</Heading>
546559
<p>{item.description}</p>

0 commit comments

Comments
 (0)