From 97b08e5d0b698827f8676318654a6651b2336de6 Mon Sep 17 00:00:00 2001 From: Antigravity Date: Sat, 9 May 2026 07:28:03 +0000 Subject: [PATCH] feat: icon-only toolbar, versioning fixes, history modal, PanelRight repositioning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Toolbar: remove text labels from all icon buttons (AI, Save, Preview, Convert) all buttons now icon-only with title tooltip for accessibility - Toolbar: reposition PanelRight (info panel toggle) to far right after three-dot menu - Versioning: decouple getNoteHistory/restoreNoteVersion from global userAISettings.noteHistory now checks note.historyEnabled directly — unblocks manual per-note history - Versioning: add 'Sauvegarder cette version' button in Versions tab of info panel calls commitNoteHistory with visual feedback (spinner → success state) - note-document-info-panel: import commitNoteHistory, add isSavingVersion state - notes.ts: fix double guard that silently blocked all history operations --- .claude/settings.json | 10 + .claude/settings.local.json | 9 +- architectural-grid (5)/.env.example | 9 + architectural-grid (5)/.gitignore | 8 + architectural-grid (5)/README.md | 20 + architectural-grid (5)/index.html | 13 + architectural-grid (5)/metadata.json | 6 + architectural-grid (5)/package.json | 34 + architectural-grid (5)/src/App.tsx | 1352 ++++++++++++++ architectural-grid (5)/src/index.css | 58 + architectural-grid (5)/src/main.tsx | 10 + architectural-grid (5)/tsconfig.json | 26 + architectural-grid (5)/vite.config.ts | 24 + memento-note/.env.example | 18 +- memento-note/app/(admin)/admin/layout.tsx | 24 +- .../admin/settings/admin-settings-form.tsx | 90 +- .../appearance/appearance-settings-client.tsx | 16 +- memento-note/app/actions/ai-settings.ts | 4 +- memento-note/app/actions/note-illustration.ts | 100 + memento-note/app/actions/notes.ts | 44 +- memento-note/app/globals.css | 49 +- memento-note/app/layout.tsx | 10 +- memento-note/components/admin-header.tsx | 136 -- memento-note/components/admin-nav.tsx | 71 - memento-note/components/admin-sidebar.tsx | 219 +++ .../components/create-notebook-dialog.tsx | 240 +-- memento-note/components/home-client.tsx | 167 +- memento-note/components/lab/canvas-board.tsx | 1 - .../components/note-document-info-panel.tsx | 44 +- memento-note/components/note-editor.tsx | 1610 +---------------- memento-note/components/note-editor/index.tsx | 5 +- .../note-editor/note-editor-context.tsx | 71 +- .../note-editor/note-editor-toolbar.tsx | 126 +- .../note-editor/note-title-block.tsx | 16 +- .../components/note-type-selector.tsx | 2 + .../components/notes-editorial-view.tsx | 19 +- .../components/notification-panel.tsx | 15 +- memento-note/components/sidebar.tsx | 277 ++- memento-note/components/theme-initializer.tsx | 9 +- .../0468ebac-8852-4371-b954-7bcc6cecc659.png | Bin 0 -> 242537 bytes .../08dc3d12-f196-4e42-b3f0-31fd849894fb.png | Bin 0 -> 345818 bytes .../154fbdc0-d43d-4e3a-9b3a-2d603964744f.png | Bin 0 -> 2479483 bytes .../3d4a02ef-73dd-4276-b3ef-840f2049a9bc.png | Bin 0 -> 317321 bytes .../6527774e-2097-45d0-959a-e0bd5acd6822.png | Bin 0 -> 345818 bytes .../67febf8c-c13f-41ab-a31d-8454e9c35ea1.png | Bin 0 -> 345818 bytes .../74f35193-d7f4-40ec-abe0-9a7bc75748ff.png | Bin 0 -> 506839 bytes .../7a175798-c566-4266-b994-b1a4c75ef776.png | Bin 0 -> 242537 bytes .../a75f55bc-1291-4aa9-b531-9129e1a08310.png | Bin 0 -> 2479483 bytes .../adeef7ca-90d5-4329-85e5-663f1a0fd7f1.png | Bin 0 -> 95597 bytes .../af37c713-5095-4a7a-8c32-40ee45c0b6e8.png | Bin 0 -> 317321 bytes .../bddfcde9-e58c-456f-818f-997d15e5fe4e.png | Bin 0 -> 2479483 bytes .../d423d373-33f2-4619-87c8-7b57d245829f.png | Bin 0 -> 2479483 bytes .../d9c4f519-2eb0-4e1b-a3d4-d6568e024b09.png | Bin 0 -> 317321 bytes memento-note/lib/ai/factory.ts | 60 +- memento-note/lib/ai/providers/anthropic.ts | 122 ++ .../lib/ai/providers/custom-openai.ts | 24 +- memento-note/lib/ai/types.ts | 12 +- memento-note/lib/config.ts | 5 + memento-note/lib/i18n/load-translations.ts | 3 + memento-note/lib/types.ts | 2 + memento-note/locales/en.json | 10 + memento-note/locales/fr.json | 10 + memento-note/package-lock.json | 73 + .../migration.sql | 2 + memento-note/scripts/setup-env.js | 2 +- 65 files changed, 2991 insertions(+), 2296 deletions(-) create mode 100644 .claude/settings.json create mode 100644 architectural-grid (5)/.env.example create mode 100644 architectural-grid (5)/.gitignore create mode 100644 architectural-grid (5)/README.md create mode 100644 architectural-grid (5)/index.html create mode 100644 architectural-grid (5)/metadata.json create mode 100644 architectural-grid (5)/package.json create mode 100644 architectural-grid (5)/src/App.tsx create mode 100644 architectural-grid (5)/src/index.css create mode 100644 architectural-grid (5)/src/main.tsx create mode 100644 architectural-grid (5)/tsconfig.json create mode 100644 architectural-grid (5)/vite.config.ts create mode 100644 memento-note/app/actions/note-illustration.ts delete mode 100644 memento-note/components/admin-header.tsx delete mode 100644 memento-note/components/admin-nav.tsx create mode 100644 memento-note/components/admin-sidebar.tsx create mode 100644 memento-note/data/uploads/notes/0468ebac-8852-4371-b954-7bcc6cecc659.png create mode 100644 memento-note/data/uploads/notes/08dc3d12-f196-4e42-b3f0-31fd849894fb.png create mode 100644 memento-note/data/uploads/notes/154fbdc0-d43d-4e3a-9b3a-2d603964744f.png create mode 100644 memento-note/data/uploads/notes/3d4a02ef-73dd-4276-b3ef-840f2049a9bc.png create mode 100644 memento-note/data/uploads/notes/6527774e-2097-45d0-959a-e0bd5acd6822.png create mode 100644 memento-note/data/uploads/notes/67febf8c-c13f-41ab-a31d-8454e9c35ea1.png create mode 100644 memento-note/data/uploads/notes/74f35193-d7f4-40ec-abe0-9a7bc75748ff.png create mode 100644 memento-note/data/uploads/notes/7a175798-c566-4266-b994-b1a4c75ef776.png create mode 100644 memento-note/data/uploads/notes/a75f55bc-1291-4aa9-b531-9129e1a08310.png create mode 100644 memento-note/data/uploads/notes/adeef7ca-90d5-4329-85e5-663f1a0fd7f1.png create mode 100644 memento-note/data/uploads/notes/af37c713-5095-4a7a-8c32-40ee45c0b6e8.png create mode 100644 memento-note/data/uploads/notes/bddfcde9-e58c-456f-818f-997d15e5fe4e.png create mode 100644 memento-note/data/uploads/notes/d423d373-33f2-4619-87c8-7b57d245829f.png create mode 100644 memento-note/data/uploads/notes/d9c4f519-2eb0-4e1b-a3d4-d6568e024b09.png create mode 100644 memento-note/lib/ai/providers/anthropic.ts create mode 100644 memento-note/prisma/migrations/20260508120000_add_note_illustration_svg/migration.sql diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..91b5856 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,10 @@ +{ + "permissions": { + "allow": [ + "Bash(npm run *)", + "Bash(curl -s http://localhost:3000)", + "Bash(curl -s -o /dev/null -w \"%{http_code}\" http://localhost:3000/)", + "Bash(kill 3309513)" + ] + } +} diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 0b7c78b..9199eb7 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -24,7 +24,14 @@ "Bash(do python3 -c \"import json; json.load\\(open\\(''$f''\\)\\)\")", "Bash(done)", "Bash(npx prisma generate)", - "Bash(git add:*)" + "Bash(git add:*)", + "Bash(npm list *)", + "Bash(git commit -m ' *)", + "Bash(git push *)", + "mcp__zai-mcp-server__analyze_image", + "Bash(npx prisma *)", + "Bash(xargs -I{} ls {})", + "Bash(node_modules/.bin/tsc --noEmit)" ] } } diff --git a/architectural-grid (5)/.env.example b/architectural-grid (5)/.env.example new file mode 100644 index 0000000..7a550fe --- /dev/null +++ b/architectural-grid (5)/.env.example @@ -0,0 +1,9 @@ +# GEMINI_API_KEY: Required for Gemini AI API calls. +# AI Studio automatically injects this at runtime from user secrets. +# Users configure this via the Secrets panel in the AI Studio UI. +GEMINI_API_KEY="MY_GEMINI_API_KEY" + +# APP_URL: The URL where this applet is hosted. +# AI Studio automatically injects this at runtime with the Cloud Run service URL. +# Used for self-referential links, OAuth callbacks, and API endpoints. +APP_URL="MY_APP_URL" diff --git a/architectural-grid (5)/.gitignore b/architectural-grid (5)/.gitignore new file mode 100644 index 0000000..5a86d2a --- /dev/null +++ b/architectural-grid (5)/.gitignore @@ -0,0 +1,8 @@ +node_modules/ +build/ +dist/ +coverage/ +.DS_Store +*.log +.env* +!.env.example diff --git a/architectural-grid (5)/README.md b/architectural-grid (5)/README.md new file mode 100644 index 0000000..0078184 --- /dev/null +++ b/architectural-grid (5)/README.md @@ -0,0 +1,20 @@ +
+GHBanner +
+ +# Run and deploy your AI Studio app + +This contains everything you need to run your app locally. + +View your app in AI Studio: https://ai.studio/apps/b7b577c6-4d9f-44ac-8fe1-85bc3c6d6e66 + +## Run Locally + +**Prerequisites:** Node.js + + +1. Install dependencies: + `npm install` +2. Set the `GEMINI_API_KEY` in [.env.local](.env.local) to your Gemini API key +3. Run the app: + `npm run dev` diff --git a/architectural-grid (5)/index.html b/architectural-grid (5)/index.html new file mode 100644 index 0000000..21dfe69 --- /dev/null +++ b/architectural-grid (5)/index.html @@ -0,0 +1,13 @@ + + + + + + My Google AI Studio App + + +
+ + + + diff --git a/architectural-grid (5)/metadata.json b/architectural-grid (5)/metadata.json new file mode 100644 index 0000000..3e19746 --- /dev/null +++ b/architectural-grid (5)/metadata.json @@ -0,0 +1,6 @@ +{ + "name": "Architectural Grid", + "description": "A minimalist notebook for architectural research and conceptual sketches.", + "requestFramePermissions": [], + "majorCapabilities": [] +} diff --git a/architectural-grid (5)/package.json b/architectural-grid (5)/package.json new file mode 100644 index 0000000..6b3f167 --- /dev/null +++ b/architectural-grid (5)/package.json @@ -0,0 +1,34 @@ +{ + "name": "react-example", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite --port=3000 --host=0.0.0.0", + "build": "vite build", + "preview": "vite preview", + "clean": "rm -rf dist", + "lint": "tsc --noEmit" + }, + "dependencies": { + "@google/genai": "^1.29.0", + "@tailwindcss/vite": "^4.1.14", + "@vitejs/plugin-react": "^5.0.4", + "lucide-react": "^0.546.0", + "react": "^19.0.1", + "react-dom": "^19.0.1", + "vite": "^6.2.3", + "express": "^4.21.2", + "dotenv": "^17.2.3", + "motion": "^12.23.24" + }, + "devDependencies": { + "@types/node": "^22.14.0", + "autoprefixer": "^10.4.21", + "tailwindcss": "^4.1.14", + "tsx": "^4.21.0", + "typescript": "~5.8.2", + "vite": "^6.2.3", + "@types/express": "^4.17.21" + } +} diff --git a/architectural-grid (5)/src/App.tsx b/architectural-grid (5)/src/App.tsx new file mode 100644 index 0000000..c10fda6 --- /dev/null +++ b/architectural-grid (5)/src/App.tsx @@ -0,0 +1,1352 @@ +/** + * @license + * SPDX-License-Identifier: Apache-2.0 + */ + +import React, { useState, useMemo } from 'react'; +import { + Plus, + Search, + Share2, + Archive, + Settings, + Lock, + ChevronRight, + MoreVertical, + ArrowLeft, + Sparkles, + MessageSquare, + Wand2, + FileCode, + Globe, + Send, + RefreshCw, + Clock, + BookOpen, + Layout, + Scissors, + Zap, + Languages, + ArrowRightLeft, + History, + Bot, + Layers, + Eye, + Microscope, + User, + Activity, + Play, + Trash2, + Edit3, + Bell, + Pin +} from 'lucide-react'; +import { motion, AnimatePresence } from 'motion/react'; + +// --- Types --- + +type NavigationView = 'notebooks' | 'agents'; +type AITone = 'Professional' | 'Creative' | 'Academic' | 'Casual'; +type AITab = 'discussion' | 'actions' | 'resources'; + +interface Note { + id: string; + carnetId: string; + title: string; + content: string; + imageUrl: string; + date: string; + isPinned?: boolean; +} + +interface Carnet { + id: string; + name: string; + initial: string; + type: 'Private' | 'Project' | 'Shared'; + isPrivate?: boolean; +} + +// --- Mock Data --- + +const CARNETS: Carnet[] = [ + { id: '1', name: 'Daily Notes', initial: 'D', type: 'Private', isPrivate: true }, + { id: '2', name: 'Project: Neo', initial: 'P', type: 'Project' }, + { id: '3', name: 'Shared Docs', initial: 'S', type: 'Shared' }, + { id: '4', name: 'Architecture Research', initial: 'A', type: 'Project' }, +]; + +const ALL_NOTES: Note[] = [ + { + id: 'n1', + carnetId: '4', + title: 'Grid Systems', + date: 'Oct 26, 2024', + content: 'Grid Systems is streathen in ognitiacs clesign and simulhere desipmalt: complded structurer and manamateriai-s: ci arevenuatingly used, asiller straterty of insaee to the tmn and usaes of disrension, architecture of emiornabious tracious structures.', + imageUrl: 'https://images.unsplash.com/photo-1503387762-592dea58ef23?auto=format&fit=crop&q=80&w=800&h=600' + }, + { + id: 'n2', + carnetId: '4', + title: 'Materiality', + date: 'Oct 24, 2024', + content: 'Materiality is combinated by relliaitic structureirs measure of plastics, natural, materials and priotical structures. Materialed coasts erabiocera alann light spaces and octicm employed design on thodolen of materiality, and tohlite tersev/ used in the gridin structures en obain materials, coms pathetic structure.', + imageUrl: 'https://images.unsplash.com/photo-1486406146926-c627a92ad1ab?auto=format&fit=crop&q=80&w=800&h=600' + }, + { + id: 'n3', + carnetId: '4', + title: 'Light & Space', + date: 'Oct 22, 2024', + content: 'Light & Space is a creaivity of light & Space inralicated in sizazant or dark crotrcning and netrescenations of avant trurme sivonpaltures for in inncr-en allimativefiting is cerriadating and sityle.', + imageUrl: 'https://images.unsplash.com/photo-1497366216548-37526070297c?auto=format&fit=crop&q=80&w=800&h=600' + }, + { + id: 'n4', + carnetId: '2', + title: 'Neo-Brutalism study', + date: 'Sep 12, 2024', + content: 'Exploring the raw aesthetic of neo-brutalism in urban environments. Focus on concrete textures and massive forms.', + imageUrl: 'https://images.unsplash.com/photo-1518005020951-eccb494ad742?auto=format&fit=crop&q=80&w=800&h=600' + } +]; + +// --- Components --- + +interface NoteLinkProps { + note: Note; + isActive: boolean; + onClick: () => void; +} + +const NoteLink: React.FC = ({ note, isActive, onClick }) => ( + +
+
+ {note.title} +
+ {note.isPinned && } + +); + +interface SidebarItemProps { + carnet: Carnet; + isActive: boolean; + notes: Note[]; + activeNoteId: string | null; + onCarnetClick: () => void; + onNoteClick: (noteId: string) => void; +} + +const SidebarItem: React.FC = ({ + carnet, + isActive, + notes, + activeNoteId, + onCarnetClick, + onNoteClick +}) => { + return ( +
+ { + onCarnetClick(); + }} + className={`w-full flex items-center gap-3 px-4 py-3 rounded-xl transition-all duration-300 group + ${isActive ? 'active-nav-item' : 'hover:bg-white/40'}`} + > + + + +
+ {carnet.initial} +
+
+
+ + {carnet.name} + + {carnet.isPrivate && } +
+
+
+ + + {isActive && ( + + {notes.map(note => ( + onNoteClick(note.id)} + /> + ))} + {notes.length === 0 && ( +

No notes yet

+ )} +
+ )} +
+
+ ); +}; + +export default function App() { + const [activeView, setActiveView] = useState('notebooks'); + const [selectedAgentId, setSelectedAgentId] = useState(null); + const [carnets, setCarnets] = useState(CARNETS); + const [notes, setNotes] = useState(ALL_NOTES); + const [activeCarnetId, setActiveCarnetId] = useState('4'); + const [activeNoteId, setActiveNoteId] = useState(null); + const [isAISidebarOpen, setIsAISidebarOpen] = useState(false); + const [aiTab, setAiTab] = useState('discussion'); + const [selectedTone, setSelectedTone] = useState('Professional'); + + // Modal States + const [showNewCarnetModal, setShowNewCarnetModal] = useState(false); + const [showNewNoteModal, setShowNewNoteModal] = useState(false); + + // Form States + const [newCarnetName, setNewCarnetName] = useState(''); + const [newNoteTitle, setNewNoteTitle] = useState(''); + const [newNoteContent, setNewNoteContent] = useState(''); + + const togglePin = (noteId: string) => { + setNotes(notes.map(n => n.id === noteId ? { ...n, isPinned: !n.isPinned } : n)); + }; + + const filteredNotes = useMemo(() => { + const carnetNotes = notes.filter(n => n.carnetId === activeCarnetId); + return [...carnetNotes].sort((a, b) => { + if (a.isPinned && !b.isPinned) return -1; + if (!a.isPinned && b.isPinned) return 1; + return 0; + }); + }, [activeCarnetId, notes]); + + const activeNote = useMemo(() => + notes.find(n => n.id === activeNoteId), + [activeNoteId, notes]); + + const activeCarnet = useMemo(() => + carnets.find(c => c.id === activeCarnetId), + [activeCarnetId, carnets]); + + const handleAddCarnet = (e: React.FormEvent) => { + e.preventDefault(); + if (!newCarnetName.trim()) return; + + const newCarnet: Carnet = { + id: Date.now().toString(), + name: newCarnetName, + initial: newCarnetName.charAt(0).toUpperCase(), + type: 'Project' + }; + + setCarnets([...carnets, newCarnet]); + setNewCarnetName(''); + setShowNewCarnetModal(false); + setActiveCarnetId(newCarnet.id); + }; + + const handleAddNote = (e: React.FormEvent) => { + e.preventDefault(); + if (!newNoteTitle.trim() || !newNoteContent.trim()) return; + + const newNote: Note = { + id: `n-${Date.now()}`, + carnetId: activeCarnetId, + title: newNoteTitle, + date: new Intl.DateTimeFormat('en-US', { month: 'short', day: 'numeric', year: 'numeric' }).format(new Date()), + content: newNoteContent, + imageUrl: 'https://images.unsplash.com/photo-1487958449943-2429e8be8625?auto=format&fit=crop&q=80&w=800&h=600' + }; + + setNotes([newNote, ...notes]); + setNewNoteTitle(''); + setNewNoteContent(''); + setShowNewNoteModal(false); + setActiveNoteId(newNote.id); + }; + + return ( +
+
+ +
+
+
+ + + +
+ + {activeView === 'notebooks' ? ( + + {!activeNoteId ? ( +
+
+
+

+ {activeCarnet?.name} — {filteredNotes[0]?.date || 'Oct 26'} +

+
+ +
+
+ + +
+ +
+
+ +
+
+ {filteredNotes.map((note, index) => ( + setActiveNoteId(note.id)} + > +

+ + {note.isPinned && } + {note.title} + +
+ + +
+

+
+
+ {note.title} +
+
+

+ {note.content} +

+ Read more +
+
+
+ ))} + {filteredNotes.length === 0 && ( +
+

This notebook is waiting for its first vision.

+ +
+ )} +
+
+ +
+

+ © 2024 Architectural Grid. All rights reserved. +

+
+
+ ) : ( +
+
+
+ +
+ + + + +
+
+ +
+
+
+ {activeCarnet?.name} + + {activeNote?.date} +
+

+ {activeNote?.title} +

+
+ +
+ {activeNote?.title} +
+ +
+

+ {activeNote?.content.split('.')[0]}. +

+
+

+ {activeNote?.content} + {activeNote?.id.startsWith('n-') && ( + <> +

+ Architectural grids serve as the invisible scaffolding upon which spatial experiences are constructed. Beyond mere structural repetition, they facilitate a rhythmic dialogue between materiality and void. In this exploration, we examine how light fractures these rigid boundaries, creating a dynamic interplay that evolves with the passage of time. + + )} +

+
+
+
+ + + {isAISidebarOpen && ( + +
+
+

+ + IA Note +

+ +
+

+ "{activeNote?.title}" +

+
+ +
+ {(['discussion', 'actions', 'resources'] as AITab[]).map((tab) => ( + + ))} +
+ +
+ + {aiTab === 'discussion' && ( + +
+
+ +
+

Posez une question à l'Assistant pour commencer.

+
+ +
+
+ +
+
+ + Cette note +
+ +
+
+ +
+ +
+ {(['Professional', 'Creative', 'Academic', 'Casual'] as AITone[]).map((tone) => ( + + ))} +
+
+
+
+ )} + + {aiTab === 'actions' && ( + +
+
+
+
+

Transformations

+
+
+ +
+ {[ + { icon: , label: 'Clarifier' }, + { icon: , label: 'Raccourcir' }, + { icon: , label: 'Améliorer' }, + { icon: , label: 'Traduire' }, + ].map((action, i) => ( + + ))} + +
+
+ +
+
+
+

Generation Tools

+
+
+ +
+
+ +
+ +
+
+
+ +
+
+
Présentation
+

Convertir en slides interactives

+
+
+ +
+
+ Thème + +
+
+ Style + +
+
+ + +
+
+ +
+
+ +
+ +
+
+
+ +
+
+
Diagramme
+

Visualisation de structure

+
+
+ +
+
+ Type + +
+
+ Style + +
+
+ + +
+
+
+ +
+ + Auto-Save Enabled +
+
+ + )} + + {aiTab === 'resources' && ( + +
+
+ +
+ + +
+
+ +
+ +