@morphika/andami 0.5.0 → 0.5.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.
- package/README.md +151 -36
- package/app/admin/assets/page.tsx +6 -6
- package/app/admin/database/page.tsx +302 -302
- package/app/admin/error.tsx +53 -53
- package/app/admin/layout.tsx +320 -327
- package/app/admin/navigation/page.tsx +255 -255
- package/app/admin/pages/[slug]/page.tsx +6 -6
- package/app/admin/pages/page.tsx +11 -11
- package/app/admin/projects/page.tsx +14 -14
- package/app/admin/setup/page.tsx +1 -1
- package/app/admin/styles/page.tsx +1 -1
- package/components/admin/MetadataEditor.tsx +6 -6
- package/components/admin/nav-builder/NavBuilder.tsx +1 -1
- package/components/admin/nav-builder/NavBuilderGrid.tsx +3 -3
- package/components/admin/nav-builder/NavGridCell.tsx +48 -48
- package/components/admin/nav-builder/NavGridItem.tsx +4 -4
- package/components/admin/nav-builder/NavItemSettings.tsx +331 -331
- package/components/admin/nav-builder/NavItemTypePicker.tsx +102 -102
- package/components/admin/nav-builder/NavLivePreview.tsx +1 -1
- package/components/admin/nav-builder/NavMobileLivePreview.tsx +226 -226
- package/components/admin/nav-builder/NavMobileSettings.tsx +242 -242
- package/components/admin/nav-builder/NavSettingsFields.tsx +514 -514
- package/components/admin/setup-wizard/BrandingStep.tsx +3 -3
- package/components/admin/setup-wizard/DatabaseStep.tsx +2 -2
- package/components/admin/setup-wizard/DoneStep.tsx +1 -1
- package/components/admin/setup-wizard/SetupWizard.tsx +4 -4
- package/components/admin/setup-wizard/StorageStep.tsx +2 -2
- package/components/admin/setup-wizard/WelcomeStep.tsx +2 -2
- package/components/admin/styles/ColorsEditor.tsx +2 -2
- package/components/admin/styles/FontsEditor.tsx +6 -6
- package/components/admin/styles/GridLayoutEditor.tsx +9 -9
- package/components/admin/styles/LinksButtonsEditor.tsx +5 -5
- package/components/admin/styles/TypographyEditor.tsx +6 -6
- package/components/admin/styles/shared.tsx +68 -68
- package/components/blocks/AudioBlockRenderer.tsx +286 -0
- package/components/blocks/BeforeAfterBlockRenderer.tsx +274 -0
- package/components/blocks/MarqueeBlockRenderer.tsx +316 -0
- package/components/blocks/ProjectCarouselBlockRenderer.tsx +1 -1
- package/components/builder/BlockCardIcons.tsx +316 -227
- package/components/builder/BlockTypePicker.tsx +3 -1
- package/components/builder/BubbleIcons.tsx +90 -0
- package/components/builder/BuilderCanvas.tsx +2 -0
- package/components/builder/CanvasMinimap.tsx +2 -2
- package/components/builder/CoverSectionCanvas.tsx +363 -275
- package/components/builder/DeviceFrame.tsx +1 -1
- package/components/builder/DndWrapper.tsx +3 -3
- package/components/builder/InsertionLines.tsx +1 -1
- package/components/builder/SectionCardIcons.tsx +421 -320
- package/components/builder/SectionEditorBar.tsx +1 -1
- package/components/builder/SectionTypePicker.tsx +4 -4
- package/components/builder/SectionV2Canvas.tsx +20 -4
- package/components/builder/SectionV2Column.tsx +74 -68
- package/components/builder/SortableBlock.tsx +93 -73
- package/components/builder/SortableRow.tsx +27 -26
- package/components/builder/VirtualAssetGrid.tsx +2 -2
- package/components/builder/asset-browser/R2BrowserContent.tsx +34 -17
- package/components/builder/asset-browser/helpers.ts +4 -0
- package/components/builder/asset-browser/types.ts +2 -1
- package/components/builder/blockStyles.tsx +192 -173
- package/components/builder/color-picker/AlphaSlider.tsx +141 -141
- package/components/builder/color-picker/ColorInputs.tsx +105 -105
- package/components/builder/color-picker/EyedropperButton.tsx +74 -74
- package/components/builder/color-picker/HueSlider.tsx +124 -124
- package/components/builder/color-picker/SaturationCanvas.tsx +142 -142
- package/components/builder/color-picker/SwatchBar.tsx +93 -93
- package/components/builder/editors/AudioBlockEditor.tsx +242 -0
- package/components/builder/editors/BeforeAfterBlockEditor.tsx +360 -0
- package/components/builder/editors/ButtonBlockEditor.tsx +4 -4
- package/components/builder/editors/EnterAnimationPicker.tsx +2 -2
- package/components/builder/editors/HoverEffectPicker.tsx +2 -2
- package/components/builder/editors/ImageBlockEditor.tsx +2 -2
- package/components/builder/editors/ImageGridBlockEditor.tsx +4 -4
- package/components/builder/editors/MarqueeBlockEditor.tsx +621 -0
- package/components/builder/editors/ProjectCarouselBlockEditor.tsx +443 -443
- package/components/builder/editors/ProjectGridEditor.tsx +9 -9
- package/components/builder/editors/SpacerBlockEditor.tsx +5 -5
- package/components/builder/editors/StaggerSettings.tsx +109 -109
- package/components/builder/editors/TextBlockEditor.tsx +3 -3
- package/components/builder/editors/TextStylePicker.tsx +1 -1
- package/components/builder/editors/VideoBlockEditor.tsx +2 -2
- package/components/builder/editors/index.ts +11 -10
- package/components/builder/editors/shared.tsx +7 -7
- package/components/builder/live-preview/LiveAudioPreview.tsx +120 -0
- package/components/builder/live-preview/LiveBeforeAfterPreview.tsx +176 -0
- package/components/builder/live-preview/LiveImageGridPreview.tsx +10 -2
- package/components/builder/live-preview/LiveImagePreview.tsx +1 -1
- package/components/builder/live-preview/LiveMarqueePreview.tsx +39 -0
- package/components/builder/live-preview/LiveProjectCarouselPreview.tsx +1 -1
- package/components/builder/live-preview/LiveVideoPreview.tsx +1 -1
- package/components/builder/live-preview/ProjectCardWrapper.tsx +291 -291
- package/components/builder/settings-panel/AnimationTab.tsx +138 -138
- package/components/builder/settings-panel/BlockLayoutTab.tsx +7 -7
- package/components/builder/settings-panel/CardEntranceSection.tsx +114 -114
- package/components/builder/settings-panel/ColumnV2Settings.tsx +5 -5
- package/components/builder/settings-panel/CoverSectionLayoutTab.tsx +71 -71
- package/components/builder/settings-panel/CoverSectionSettings.tsx +335 -335
- package/components/builder/settings-panel/PageSettings.tsx +3 -3
- package/components/builder/settings-panel/ParallaxSlideSettings.tsx +2 -2
- package/components/builder/settings-panel/SectionV2AnimationTab.tsx +4 -4
- package/components/builder/settings-panel/SectionV2LayoutTab.tsx +356 -356
- package/components/builder/settings-panel/SectionV2Settings.tsx +14 -14
- package/components/builder/settings-panel/TRBLInputs.tsx +1 -1
- package/lib/animation/enter-types.ts +3 -0
- package/lib/animation/hover-effect-presets.ts +210 -210
- package/lib/animation/hover-effect-types.ts +3 -0
- package/lib/builder/block-registrations.ts +468 -335
- package/lib/builder/constants.ts +111 -111
- package/lib/builder/store-sections.ts +2 -2
- package/lib/builder/types-slices.ts +414 -414
- package/lib/builder/types.ts +6 -1
- package/lib/config/index.ts +27 -27
- package/lib/sanity/types.ts +156 -1
- package/lib/version.ts +1 -1
- package/package.json +1 -1
- package/sanity/schemas/blocks/audioBlock.ts +69 -0
- package/sanity/schemas/blocks/beforeAfterBlock.ts +121 -0
- package/sanity/schemas/blocks/index.ts +12 -9
- package/sanity/schemas/blocks/marqueeBlock.ts +292 -0
- package/sanity/schemas/index.ts +120 -111
- package/styles/admin.css +85 -85
- package/styles/animations.css +237 -237
- package/styles/base.css +114 -114
package/README.md
CHANGED
|
@@ -1,26 +1,23 @@
|
|
|
1
1
|
# @morphika/andami
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
**A visual page builder framework for Next.js — the engine behind [morphika.tv](https://morphika.tv).**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Andami is a self-hosted, code-first alternative to Webflow / Framer / Semplice. You scaffold a new site in one command, write your branding in a single config file, and get a Sanity-backed CMS plus a drag-and-drop visual editor — all running on Vercel's free Hobby tier.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
> **Status — actively maintained, not actively promoted.**
|
|
8
|
+
> Built and used in production by [Morphika Studio](https://morphika.tv). Released as MIT for transparency and as a reference implementation. Issues and PRs are welcome but not guaranteed a response — this is a personal/studio tool first, an open-source project second.
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
- **6 Content Blocks** — Text, Image, Image Grid, Video, Spacer, Button (added via "+ Add Block" inside columns)
|
|
11
|
-
- **2 Section-level Blocks** — Project Grid (masonry) and Project Carousel (horizontal "keep browsing" at end of project pages). Added via "+ Add Section"
|
|
12
|
-
- **Cover Sections** — Full-viewport hero sections with proportional rows, background media, and drag-to-resize
|
|
13
|
-
- **V2 Grid System** — 12-column CSS grid with push cascade engine and responsive overrides
|
|
14
|
-
- **Custom Sections** — Create reusable sections with per-instance setting overrides
|
|
15
|
-
- **Navigation Builder** — Visual 12-column grid editor with drag & drop
|
|
16
|
-
- **Animation System** — Enter animations, hover effects (CSS + WebGL shaders), page transitions
|
|
17
|
-
- **Asset Management** — Cloudflare R2 storage with browser, thumbnails, and CDN serving
|
|
18
|
-
- **Full Site Backups** — Client-side ZIP export/restore. Browser talks directly to R2 (public CDN + presigned PUT URLs); Vercel only sees lightweight JSON, so backups never hit the 4.5 MB / 10s serverless limits
|
|
19
|
-
- **Setup Wizard** — Guided onboarding for new sites
|
|
20
|
-
- **Sanity v3 CMS** — Structured content with custom schemas, GROQ queries, and ISR
|
|
21
|
-
- **Vercel-Optimized** — Sanity CDN for public queries, 24h ISR, R2 direct CDN shortcut, bot guard middleware, aggressive robots.txt with crawl-delay — all tuned to minimize serverless CPU on Hobby tier
|
|
10
|
+
---
|
|
22
11
|
|
|
23
|
-
##
|
|
12
|
+
## Demo
|
|
13
|
+
|
|
14
|
+
🔗 **Live site:** [morphika.tv](https://morphika.tv)
|
|
15
|
+
🔗 **Admin preview:** _(add screenshot/GIF here — `docs/media/admin-preview.png`)_
|
|
16
|
+
🔗 **Builder canvas:** _(add screenshot here — `docs/media/builder-canvas.png`)_
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Quick start
|
|
24
21
|
|
|
25
22
|
```bash
|
|
26
23
|
npx create-andami-site my-site
|
|
@@ -29,32 +26,150 @@ npm install
|
|
|
29
26
|
npm run dev
|
|
30
27
|
```
|
|
31
28
|
|
|
32
|
-
|
|
29
|
+
Open `http://localhost:3000/admin` and follow the setup wizard. You'll need:
|
|
30
|
+
|
|
31
|
+
- A free [Sanity](https://www.sanity.io/) account (CMS backend)
|
|
32
|
+
- A [Cloudflare R2](https://www.cloudflare.com/developer-platform/products/r2/) bucket (asset storage — also free up to 10 GB)
|
|
33
|
+
- A Vercel account for deployment (optional — works anywhere Next.js runs)
|
|
34
|
+
|
|
35
|
+
Full guide → [docs/QUICK-START.md](docs/QUICK-START.md)
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Who this is for
|
|
40
|
+
|
|
41
|
+
✅ **Designers / studios** who want a polished portfolio site they fully own — no monthly subscription, no platform lock-in.
|
|
42
|
+
✅ **Developers** building bespoke sites for clients in the design / architecture / fashion / photography space.
|
|
43
|
+
✅ **Anyone** who has outgrown Webflow's pricing or wants a Next.js codebase they can extend.
|
|
44
|
+
|
|
45
|
+
## Who this is *not* for
|
|
46
|
+
|
|
47
|
+
❌ Non-technical users expecting a SaaS experience. You need to deploy it yourself.
|
|
48
|
+
❌ E-commerce, blogs at scale, or content-heavy sites. Andami is optimized for portfolio / brand / case-study sites.
|
|
49
|
+
❌ Teams looking for guaranteed support or SLAs. This is single-maintainer software.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## What's inside
|
|
54
|
+
|
|
55
|
+
### Visual page builder
|
|
56
|
+
- Infinite canvas with zoom, pan, minimap and device frames (desktop / tablet / phone)
|
|
57
|
+
- Cross-section drag-and-drop between V2 sections, Cover sections, and Parallax groups
|
|
58
|
+
- 12-column responsive grid with push-cascade overlap resolution
|
|
59
|
+
- Per-viewport overrides (desktop / tablet / mobile) for every block
|
|
60
|
+
|
|
61
|
+
### Content blocks (10)
|
|
62
|
+
- Text (Tiptap rich text with inline color, links, BubbleMenu)
|
|
63
|
+
- Image, Image Grid, Video, Audio, Spacer, Button, Before/After
|
|
64
|
+
- Project Grid (masonry with multi-aspect-ratio cards)
|
|
65
|
+
- Project Carousel (horizontal "keep browsing" at end of project pages)
|
|
66
|
+
|
|
67
|
+
### Section types
|
|
68
|
+
- **V2 Section** — flat columns, content-driven height
|
|
69
|
+
- **Cover Section** — full-viewport, proportional rows, background media, drag-to-resize
|
|
70
|
+
- **Parallax Group** — multi-slide parallax with crossfade / reveal transitions
|
|
71
|
+
- **Custom Section** — reusable sections with per-instance overrides
|
|
72
|
+
|
|
73
|
+
### Animation system
|
|
74
|
+
- 7 enter-animation presets + per-character typewriter
|
|
75
|
+
- 4-level cascade (block → column → section → page)
|
|
76
|
+
- Hover effects: 7 CSS presets + 3 WebGL shaders (ripple, RGB shift, pixelate)
|
|
77
|
+
- Page exit animations that replay enter animations in reverse
|
|
78
|
+
|
|
79
|
+
### CMS & assets
|
|
80
|
+
- Sanity v3 schemas (5 doc types, 10+ object types)
|
|
81
|
+
- Cloudflare R2 storage with presigned uploads, asset registry, thumbnail CLI
|
|
82
|
+
- Full-site backup & restore (client-side ZIP, bypasses serverless body limits)
|
|
83
|
+
- Custom font upload with magic-byte validation
|
|
84
|
+
|
|
85
|
+
### Vercel-Hobby-tier optimized
|
|
86
|
+
- Sanity CDN routing for public queries (~2ms vs ~200ms)
|
|
87
|
+
- 24h ISR with on-demand revalidation
|
|
88
|
+
- Edge-middleware bot guard (blocks 20+ aggressive crawlers before they hit serverless)
|
|
89
|
+
- Aggressive `robots.txt` with crawl-delay and AI-scraper blocks
|
|
90
|
+
- React `cache()` deduplication on SSR fetches
|
|
91
|
+
|
|
92
|
+
→ Designed to run a low-traffic portfolio site comfortably within 4h Fluid Active CPU/month.
|
|
93
|
+
|
|
94
|
+
---
|
|
33
95
|
|
|
34
96
|
## Stack
|
|
35
97
|
|
|
36
|
-
|
|
98
|
+
| Layer | Choice |
|
|
99
|
+
|---|---|
|
|
100
|
+
| Framework | Next.js 16 (App Router) |
|
|
101
|
+
| CMS backend | Sanity v3 |
|
|
102
|
+
| State | Zustand 5 |
|
|
103
|
+
| Drag & drop | @dnd-kit |
|
|
104
|
+
| Styling | Tailwind CSS v4 |
|
|
105
|
+
| Rich text | Tiptap 2 |
|
|
106
|
+
| Shaders | OGL (WebGL) |
|
|
107
|
+
| Storage | Cloudflare R2 (S3-compatible) |
|
|
108
|
+
| Tests | Vitest + React Testing Library (980+ assertions) |
|
|
109
|
+
|
|
110
|
+
### Why this stack
|
|
111
|
+
|
|
112
|
+
- **Next.js + Sanity** — most boring, well-documented stack for content-driven sites. ISR + GROQ scales to any portfolio.
|
|
113
|
+
- **Zustand instead of Redux** — the page-builder state is complex (drag, undo/redo, multi-viewport overrides, snapshots) but a single feature; Zustand's slice pattern keeps it readable.
|
|
114
|
+
- **Sanity for data, not for editing** — Sanity is excellent as a structured-content backend but its built-in studio doesn't fit a visual layout tool. Andami uses Sanity purely as a typed JSON store.
|
|
115
|
+
- **Cloudflare R2 over S3** — zero egress fees. For a portfolio site that's the difference between $0/mo and "depends on the month".
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Architecture
|
|
120
|
+
|
|
121
|
+
Andami ships as an npm package (`@morphika/andami`). Each deployed site is an **instance** — a thin Next.js app that imports framework code and provides its own `site.config.ts`:
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
my-site/ # Instance (your repo)
|
|
125
|
+
├── site.config.ts # Branding, fonts, palette, features
|
|
126
|
+
├── app/
|
|
127
|
+
│ ├── (site)/page.tsx # → re-exports @morphika/andami/site/page
|
|
128
|
+
│ ├── admin/ # → re-exports admin pages
|
|
129
|
+
│ └── api/ # → re-exports API routes
|
|
130
|
+
└── lib/config-init.ts # Registers config with the framework
|
|
131
|
+
|
|
132
|
+
@morphika/andami/ # Framework (this repo)
|
|
133
|
+
├── components/builder/ # Visual editor
|
|
134
|
+
├── components/blocks/ # Public-site renderers
|
|
135
|
+
├── lib/sanity/ # Schemas, queries, types
|
|
136
|
+
└── app/api/ # All API routes (auth, pages, assets, R2, backups)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
This split lets you upgrade the framework with `npm update` without touching the instance, and lets one studio run many sites from a single shared codebase.
|
|
140
|
+
|
|
141
|
+
→ Full breakdown in [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).
|
|
142
|
+
|
|
143
|
+
---
|
|
37
144
|
|
|
38
145
|
## Documentation
|
|
39
146
|
|
|
40
|
-
| Doc |
|
|
41
|
-
|
|
42
|
-
| [
|
|
43
|
-
| [
|
|
44
|
-
| [
|
|
45
|
-
| [
|
|
46
|
-
| [
|
|
47
|
-
| [
|
|
147
|
+
| Doc | What's in it |
|
|
148
|
+
|---|---|
|
|
149
|
+
| [QUICK-START](docs/QUICK-START.md) | 5-minute setup for a new instance |
|
|
150
|
+
| [CONFIGURATION](docs/CONFIGURATION.md) | Every field of `site.config.ts` |
|
|
151
|
+
| [ARCHITECTURE](docs/ARCHITECTURE.md) | Data flow, module boundaries, design decisions |
|
|
152
|
+
| [BUILDER](docs/BUILDER.md) | Visual editor — interactions, store, undo/redo |
|
|
153
|
+
| [CANVAS](docs/CANVAS.md) | Infinite canvas, zoom, pan, device frames |
|
|
154
|
+
| [BLOCKS](docs/BLOCKS.md) | All 10 block types with fields and options |
|
|
48
155
|
| [CMS](docs/CMS.md) | Sanity schemas and GROQ queries |
|
|
49
|
-
| [
|
|
50
|
-
| [
|
|
51
|
-
| [
|
|
52
|
-
| [
|
|
53
|
-
| [
|
|
54
|
-
| [
|
|
55
|
-
| [
|
|
56
|
-
|
|
156
|
+
| [NAVIGATION](docs/NAVIGATION.md) | Navigation builder spec |
|
|
157
|
+
| [ASSETS](docs/ASSETS.md) | Storage, providers, thumbnails |
|
|
158
|
+
| [BACKUPS](docs/BACKUPS.md) | Full-site backup & restore (V2 client-side) |
|
|
159
|
+
| [CUSTOMIZATION](docs/CUSTOMIZATION.md) | Custom blocks, fonts, schemas |
|
|
160
|
+
| [SECURITY](docs/SECURITY.md) | Auth, CSRF, encryption, sanitization |
|
|
161
|
+
| [DEPLOYMENT](docs/DEPLOYMENT.md) | Vercel, domains, R2 setup |
|
|
162
|
+
| [PACKAGE-DEV](docs/PACKAGE-DEV.md) | Local dev, npm link, publishing |
|
|
163
|
+
|
|
164
|
+
---
|
|
57
165
|
|
|
58
166
|
## License
|
|
59
167
|
|
|
60
|
-
MIT
|
|
168
|
+
[MIT](LICENSE) — use it, fork it, ship clients with it. Attribution appreciated but not required.
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Credits
|
|
173
|
+
|
|
174
|
+
Built by [Daniel Planas](https://morphika.tv) at Morphika Studio.
|
|
175
|
+
The name *Andami* (Catalan for "scaffold") refers to the temporary structures used to build something more permanent.
|
|
@@ -178,7 +178,7 @@ export default function AdminAssetsPage() {
|
|
|
178
178
|
<button
|
|
179
179
|
onClick={handleScan}
|
|
180
180
|
disabled={scanning}
|
|
181
|
-
className="font-mono text-[11px] px-3 py-1.5 rounded bg-[#
|
|
181
|
+
className="font-mono text-[11px] px-3 py-1.5 rounded bg-[#3580f9] text-white hover:bg-[#3580f9]/80 transition-colors disabled:opacity-50"
|
|
182
182
|
>
|
|
183
183
|
{scanning ? "Scanning..." : "🔄 Scan Storage"}
|
|
184
184
|
</button>
|
|
@@ -257,7 +257,7 @@ export default function AdminAssetsPage() {
|
|
|
257
257
|
setPage(0);
|
|
258
258
|
}}
|
|
259
259
|
placeholder="Search assets..."
|
|
260
|
-
className="flex-1 rounded border border-neutral-200 bg-white px-3 py-1.5 font-mono text-xs text-neutral-900 focus:border-[#
|
|
260
|
+
className="flex-1 rounded border border-neutral-200 bg-white px-3 py-1.5 font-mono text-xs text-neutral-900 focus:border-[#3580f9] focus:outline-none shadow-sm"
|
|
261
261
|
/>
|
|
262
262
|
<select
|
|
263
263
|
value={statusFilter}
|
|
@@ -265,7 +265,7 @@ export default function AdminAssetsPage() {
|
|
|
265
265
|
setStatusFilter(e.target.value);
|
|
266
266
|
setPage(0);
|
|
267
267
|
}}
|
|
268
|
-
className="rounded border border-neutral-200 bg-white px-2 py-1.5 font-mono text-xs text-neutral-900 focus:border-[#
|
|
268
|
+
className="rounded border border-neutral-200 bg-white px-2 py-1.5 font-mono text-xs text-neutral-900 focus:border-[#3580f9] focus:outline-none"
|
|
269
269
|
>
|
|
270
270
|
<option value="all">All statuses</option>
|
|
271
271
|
<option value="active">Active</option>
|
|
@@ -279,7 +279,7 @@ export default function AdminAssetsPage() {
|
|
|
279
279
|
setTypeFilter(e.target.value);
|
|
280
280
|
setPage(0);
|
|
281
281
|
}}
|
|
282
|
-
className="rounded border border-neutral-200 bg-white px-2 py-1.5 font-mono text-xs text-neutral-900 focus:border-[#
|
|
282
|
+
className="rounded border border-neutral-200 bg-white px-2 py-1.5 font-mono text-xs text-neutral-900 focus:border-[#3580f9] focus:outline-none"
|
|
283
283
|
>
|
|
284
284
|
<option value="all">All types</option>
|
|
285
285
|
<option value="image">Images</option>
|
|
@@ -329,7 +329,7 @@ export default function AdminAssetsPage() {
|
|
|
329
329
|
}
|
|
330
330
|
className={`w-full grid grid-cols-[1fr_80px_80px_60px_100px] gap-2 px-3 py-2 border-b border-neutral-100 text-left transition-colors ${
|
|
331
331
|
selectedAsset?._key === asset._key
|
|
332
|
-
? "bg-[#
|
|
332
|
+
? "bg-[#3580f9]/5"
|
|
333
333
|
: "hover:bg-neutral-50"
|
|
334
334
|
}`}
|
|
335
335
|
>
|
|
@@ -378,7 +378,7 @@ export default function AdminAssetsPage() {
|
|
|
378
378
|
onClick={() => setPage(i)}
|
|
379
379
|
className={`font-mono text-[10px] px-2 py-1 rounded border transition-colors ${
|
|
380
380
|
page === i
|
|
381
|
-
? "border-[#
|
|
381
|
+
? "border-[#3580f9] bg-[#3580f9]/10 text-[#3580f9]"
|
|
382
382
|
: "border-neutral-300 text-neutral-500 hover:text-neutral-900"
|
|
383
383
|
}`}
|
|
384
384
|
>
|