diff --git a/architectural-grid (1)/.env.example b/architectural-grid (1)/.env.example deleted file mode 100644 index 7a550fe..0000000 --- a/architectural-grid (1)/.env.example +++ /dev/null @@ -1,9 +0,0 @@ -# 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 (1)/.gitignore b/architectural-grid (1)/.gitignore deleted file mode 100644 index 5a86d2a..0000000 --- a/architectural-grid (1)/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -node_modules/ -build/ -dist/ -coverage/ -.DS_Store -*.log -.env* -!.env.example diff --git a/architectural-grid (1)/README.md b/architectural-grid (1)/README.md deleted file mode 100644 index 0078184..0000000 --- a/architectural-grid (1)/README.md +++ /dev/null @@ -1,20 +0,0 @@ -
-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 (1)/index.html b/architectural-grid (1)/index.html deleted file mode 100644 index 21dfe69..0000000 --- a/architectural-grid (1)/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - My Google AI Studio App - - -
- - - - diff --git a/architectural-grid (1)/metadata.json b/architectural-grid (1)/metadata.json deleted file mode 100644 index 3e19746..0000000 --- a/architectural-grid (1)/metadata.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "Architectural Grid", - "description": "A minimalist notebook for architectural research and conceptual sketches.", - "requestFramePermissions": [], - "majorCapabilities": [] -} diff --git a/architectural-grid (1)/package.json b/architectural-grid (1)/package.json deleted file mode 100644 index 6b3f167..0000000 --- a/architectural-grid (1)/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "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 (1)/src/App.tsx b/architectural-grid (1)/src/App.tsx deleted file mode 100644 index 9c8bb0b..0000000 --- a/architectural-grid (1)/src/App.tsx +++ /dev/null @@ -1,386 +0,0 @@ -/** - * @license - * SPDX-License-Identifier: Apache-2.0 - */ - -import React, { useState, useMemo } from 'react'; -import { motion, AnimatePresence } from 'motion/react'; - -// Components -import { Sidebar } from './components/Sidebar'; -import { NotebooksView } from './components/NotebooksView'; -import { AgentsView } from './components/AgentsView'; -import { SettingsView } from './components/SettingsView'; -import { AISidebar } from './components/AISidebar'; -import { SlashMenu } from './components/SlashMenu'; - -// Data & Types -import { CARNETS, ALL_NOTES } from './constants'; -import { NavigationView, SettingsTab, AITab, AITone, Carnet, Note } from './types'; - -export default function App() { - const [activeView, setActiveView] = useState('notebooks'); - const [activeSettingsTab, setActiveSettingsTab] = useState('general'); - const [selectedAgentId, setSelectedAgentId] = useState(null); - const [isDarkMode, setIsDarkMode] = useState(false); - const [carnets, setCarnets] = useState(CARNETS); - const [notes, setNotes] = useState(ALL_NOTES); - const [activeCarnetId, setActiveCarnetId] = useState('4'); - const [activeNoteId, setActiveNoteId] = useState(null); - const [selectedTagIds, setSelectedTagIds] = useState([]); - const [isAISidebarOpen, setIsAISidebarOpen] = useState(false); - const [aiTab, setAiTab] = useState('discussion'); - const [selectedTone, setSelectedTone] = useState('Professional'); - - // Modal States - const [showNewCarnetModal, setShowNewCarnetModal] = useState<{ isOpen: boolean; parentId?: string; isRenaming?: boolean; carnetId?: string }>({ isOpen: false }); - const [showNewNoteModal, setShowNewNoteModal] = useState(false); - const [slashMenu, setSlashMenu] = useState<{ isOpen: boolean; top: number; left: number } | null>(null); - - // Form States - const [newCarnetName, setNewCarnetName] = useState(''); - const [newNoteTitle, setNewNoteTitle] = useState(''); - const [newNoteContent, setNewNoteContent] = useState(''); - - const handleEditorKeyDown = (e: React.KeyboardEvent) => { - if (e.key === '/') { - const selection = window.getSelection(); - if (selection && selection.rangeCount > 0) { - const range = selection.getRangeAt(0); - const rect = range.getBoundingClientRect(); - setSlashMenu({ - isOpen: true, - top: rect.bottom + window.scrollY, - left: rect.left + window.scrollX - }); - } - } - }; - - const togglePin = (noteId: string) => { - setNotes(notes.map(n => n.id === noteId ? { ...n, isPinned: !n.isPinned } : n)); - }; - - const filteredNotes = useMemo(() => { - let result = notes.filter(n => n.carnetId === activeCarnetId); - - if (selectedTagIds.length > 0) { - result = result.filter(note => - selectedTagIds.every(tagId => note.tags?.some(tag => tag.id === tagId)) - ); - } - - return [...result].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; - - if (showNewCarnetModal.isRenaming && showNewCarnetModal.carnetId) { - setCarnets(carnets.map(c => c.id === showNewCarnetModal.carnetId ? { ...c, name: newCarnetName, initial: newCarnetName.charAt(0).toUpperCase() } : c)); - setShowNewCarnetModal({ isOpen: false }); - setNewCarnetName(''); - return; - } - - const newCarnet: Carnet = { - id: Date.now().toString(), - name: newCarnetName, - initial: newCarnetName.charAt(0).toUpperCase(), - type: 'Project', - parentId: showNewCarnetModal.parentId - }; - - setCarnets([...carnets, newCarnet]); - setNewCarnetName(''); - setShowNewCarnetModal({ isOpen: false }); - setActiveCarnetId(newCarnet.id); - }; - - const handleDeleteCarnet = (id: string) => { - if (window.confirm('Êtes-vous sûr de vouloir supprimer ce carnet et tous ses sous-carnets ?')) { - const idsToDelete = new Set([id]); - - const addChildren = (parentId: string) => { - carnets.forEach(c => { - if (c.parentId === parentId) { - idsToDelete.add(c.id); - addChildren(c.id); - } - }); - }; - addChildren(id); - - setCarnets(carnets.filter(c => !idsToDelete.has(c.id))); - setNotes(notes.filter(n => !idsToDelete.has(n.carnetId))); - - if (idsToDelete.has(activeCarnetId)) { - setActiveCarnetId('1'); - } - } - }; - - 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', - tags: [] - }; - - setNotes([newNote, ...notes]); - setNewNoteTitle(''); - setNewNoteContent(''); - setShowNewNoteModal(false); - setActiveNoteId(newNote.id); - }; - - return ( -
- { - setShowNewCarnetModal({ isOpen: show, parentId, isRenaming, carnetId }); - if (isRenaming && carnetId) { - const carnet = carnets.find(c => c.id === carnetId); - if (carnet) setNewCarnetName(carnet.name); - } else { - setNewCarnetName(''); - } - }} - onDeleteCarnet={handleDeleteCarnet} - /> - -
- - {activeView === 'notebooks' && ( - - setShowNewCarnetModal({ isOpen: show, parentId })} - /> - - )} - - {activeView === 'agents' && ( - - - - )} - - {activeView === 'settings' && ( - - - - )} - - - -
- - {/* Modals */} - - {showNewCarnetModal.isOpen && ( -
- setShowNewCarnetModal({ isOpen: false })} - className="absolute inset-0 bg-ink/40 backdrop-blur-sm" - /> - -

- {showNewCarnetModal.isRenaming ? 'Rename Carnet' : (showNewCarnetModal.parentId ? 'Create Sub-Carnet' : 'Create New Carnet')} -

- {showNewCarnetModal.parentId && !showNewCarnetModal.isRenaming && ( -

- Inside: {carnets.find(c => c.id === showNewCarnetModal.parentId)?.name} -

- )} -
-
- - setNewCarnetName(e.target.value)} - placeholder="E.g., Sustainable Patterns" - className="w-full bg-white dark:bg-[#2A2A2A] border border-border rounded-lg px-4 py-3 outline-none focus:border-ink transition-colors font-serif italic text-lg text-ink dark:text-dark-ink" - /> -
-
- - -
-
-
-
- )} - - {showNewNoteModal && ( -
- setShowNewNoteModal(false)} - className="absolute inset-0 bg-ink/40 backdrop-blur-sm" - /> - - - {slashMenu?.isOpen && ( - { console.log(type); setSlashMenu(null); }} - onClose={() => setSlashMenu(null)} - /> - )} - -

Add Architectural Note

-
-
- - setNewNoteTitle(e.target.value)} - placeholder="Enter the title of your study..." - className="w-full bg-white dark:bg-[#2A2A2A] border border-border rounded-lg px-5 py-4 outline-none focus:border-ink transition-colors font-serif text-2xl text-ink dark:text-dark-ink" - /> -
-
- -