Commit Graph

12 Commits

Author SHA1 Message Date
David Montero Crespo fa4f3d6e80 feat(editor): translate Save / Share / LoginPrompt modals (Editor block 3)
The three modal dialogs that fire during the editor's routine save +
share + auth-required flows are now fully localised across all 9
locales.

LoginPromptModal
- Title, body, and the three buttons (Sign in / Create account /
  Cancel). Sign in / Sign up Links use localize() so a Spanish
  reader prompted to log in lands at /es/login rather than dropping
  back to English.

SaveProjectModal
- Title (toggles between Save / Update), name + description fields
  with placeholders, save button (toggles between Save / Update /
  Saving…), Cancel button.
- Visibility toggle: Public / Private label + hint copy under the
  icon.
- All four error paths now go through t() with a {{status}}
  interpolation for the generic HTTP failure message.

ShareModal
- Title, public/private label + hint pair, "Make private" /
  "Make public" toggle, Copy button, the warning shown when the
  project is private, and the Close button.

Hand-curated translations for all 8 non-English locales. Status
codes (403) and shortcut markers preserved.
2026-05-09 03:12:52 -03:00
David Montero Crespo 6a88375bc0 feat: persist multi-board projects + add auto-save
The project save/load pipeline only persisted a single `board_type`, so
multi-board workspaces silently lost every board except the active one
on save, and wires referencing the dropped boards' IDs orphaned to the
canvas corner on reload. An audit of the production backup found 74/306
projects (24%) with at least one orphaned wire and 174/301 non-trivial
projects whose code was still the default Blink template — strong signal
that users save once and never re-save.

Backend
- Add `boards_json` column on `projects` with idempotent ALTER TABLE in
  the lifespan migration list.
- New `FileGroup` schema + `file_groups` array on
  ProjectCreate/Update/Response. Legacy `files`/`code` kept for back-compat.
- `project_files.py` now uses `{pid}/{groupId}/{filename}` subdirs via
  `read_groups`/`write_groups`. Legacy flat layouts are auto-promoted on
  read; legacy single-list `files` only updates the active group, leaving
  other boards' files intact.
- `_persist_files_from_body` honors file_groups → files → code priority.

Frontend
- `useSimulatorStore.addBoard` accepts an optional `explicitId` so
  saved board IDs can be restored verbatim (wires reference IDs literally).
- New `loadProjectState({boards, fileGroups, components, wires,
  activeBoardId})` action: tears down current boards, recreates from the
  payload, restores file groups atomically, recalculates wire positions
  on the next frame, and refreshes the Interconnect.
- `useEditorStore.replaceFileGroups` for atomic multi-group restore.
- `SaveProjectModal` and `ProjectByIdPage`/`ProjectPage` now go through
  `buildSavePayload` / `buildLoadPayload` (handles pre-backfill projects
  by synthesising a default board from `board_type`).

Auto-save (#useAutoSaveProject hook)
- 2.5s debounced silent PUT triggered ONLY when an authenticated user
  has a `currentProject` with a UUID. State hash detects real changes
  vs. UI-only churn; baseline is reset on project load so the just-loaded
  state isn't immediately re-saved.
- `beforeunload` flush via `fetch keepalive: true` (supports PUT +
  credentials, survives unload).
- Compact status indicator in `AppHeader` (idle/dirty/saving/saved/error).

Backfill script (one-off, idempotent)
- `backend/scripts/backfill_boards_2026_05.py` populates `boards_json`
  for legacy projects. Heuristic per project, based on which board IDs
  the wires reference:
    Case A — wires only ref 'arduino-uno' but board_type ≠ uno:
             rename id→board_type and rewrite wire endpoints.
    Case B — single-board normal: keep verbatim.
    Case C — multi-board: recreate one board per distinct ref, infer
             kind by stripping trailing -N suffix.
  Also moves any flat files into the active board's group subdir.
  Stdlib-only, runs from host or `docker exec`.

Docker
- `Dockerfile.standalone` now copies `backend/scripts/` into the image
  so the backfill is callable via `docker exec velxio-app python
  /app/scripts/backfill_boards_2026_05.py --apply`.

Verified locally on the restored production backup (363 projects):
33 Case A, 316 Case B, 14 Case C, 135 wire endpoints renamed, 0 orphans.
Re-running the script after apply skips all 363 (idempotent).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 13:43:33 -03:00
David Montero Crespo 212ecd1bcb refactor: rename components and update prefixes to 'velxio-' for consistency
- Modified the index file to reflect the new naming convention for Velxio components.
- Changed JSX declarations to use 'velxio-' prefix for various components.
- Updated component overrides to replace 'wokwi-' with 'velxio-' for logic gates and other components.
- Adjusted SVG generation script to use 'velxio-' prefix for BMP280 and Raspberry Pi components.
- Marked submodules as dirty in QEMU and RP2040 libraries.
- Added .prettierignore and .prettierrc.json for consistent code formatting.
- Introduced InstrumentComponent with support for Voltmeter and Ammeter, including pin information handling.
2026-04-21 16:45:45 -03:00
David Montero 75c4ead6de Merge remote-tracking branch 'origin/master' 2026-04-09 02:36:06 +02:00
David Montero 6c95013f24 fix: prevent save to /api/projects/none when project ID is invalid
Two bugs causing "can't save project" reports:

1. SaveProjectModal: validate currentProject.id is a real UUID before
   calling updateProject. If id is "none" or any non-UUID string, fall
   through to createProject instead, avoiding PUT /api/projects/none.

2. ProjectByIdPage: call clearCurrentProject() when the project fetch
   fails (404/403/error). Prevents stale project IDs from a previous
   session polluting the store and triggering spurious update calls.
2026-04-09 02:34:43 +02:00
David Montero Crespo 71fa6eae4a Merge branch 'master' into feature/shareable-urls
# Conflicts:
#	.gitignore
2026-04-08 00:03:59 -03:00
David Montero 2a386f99b0 fix: SaveProjectModal uses active board files/kind and better error messages
Two bugs fixed:
1. SaveProjectModal was reading from the legacy global `files` array instead
   of the active board's file group, causing projects to be saved with the
   wrong board_type (e.g. 'arduino-uno' for ESP32 projects).
   Now reads from fileGroups[activeBoard.activeFileGroupId] and uses
   activeBoard.boardKind for board_type.

2. Error handling was always showing "Save failed." — now shows:
   - "Server unreachable. Check your connection and try again." for network errors
   - "Not authenticated. Please log in and try again." for 401 responses
   - The server's detail message (with status code) for other errors

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 22:27:17 +02:00
David Montero Crespo 8c68879ce7 feat: add share functionality for projects and examples
- Implemented ExampleLoaderPage to load examples by ID from the URL.
- Added ExampleLoaderPage route to App component.
- Created ShareModal for sharing project links with visibility toggle.
- Updated UserProfilePage to include share button for user projects.
- Enhanced ExamplesGallery with a copy link button for examples.
- Introduced utility function loadExample to streamline example loading and library installation.
- Updated project visibility management in useProjectStore.
- Added styles for new components and buttons.
- Updated .gitignore to include Arduino compilation byproducts.
2026-03-30 19:00:33 -03:00
David Montero Crespo f127ef6cbe Enhance analytics tracking across the application
- Added tracking for simulation events: start, stop, and reset.
- Implemented tracking for library manager interactions, including library installations.
- Enhanced project management tracking with save and create project events.
- Integrated tracking for user authentication events: sign-up and login.
- Added tracking for CTA clicks on landing and SEO pages.
- Updated analytics utility functions to support new tracking events.
- Improved GitHub and Discord link tracking in the app header.
- Refactored existing components to utilize new tracking functions for better user engagement insights.
2026-03-25 03:06:38 -03:00
copilot-swe-agent[bot] 13ee547ad7 feat: add GA4 key events tracking (run_simulation, open_example, create_project, compile_code, visit_github)
Co-authored-by: davidmonterocrespo24 <47928504+davidmonterocrespo24@users.noreply.github.com>
2026-03-12 22:02:24 +00:00
David Montero Crespo 7260c8d092 feat: /project/:id URL, per-project file volumes, and public/private access control
Backend:
- project_files.py: read/write sketch files to /app/data/projects/{id}/
- GET /api/projects/{id}: load project by ID (public = anyone, private = owner only)
- create/update write files to disk volume; delete removes them
- ProjectResponse includes files[] list loaded from disk

Frontend:
- /project/:id canonical route -> ProjectByIdPage
- ProjectPage (legacy /:username/:slug) redirects to /project/:id after load
- SaveProjectModal sends files[] and navigates to /project/{id} after save
- DATA_DIR env var in both compose files

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 20:38:06 -03:00
David Montero Crespo a5c6987aca feat: implement user authentication and project management features
- Add LoginPage and RegisterPage for user authentication.
- Create UserProfilePage to display user projects.
- Implement ProjectPage for viewing and editing individual projects.
- Introduce authService for handling user login, registration, and session management.
- Add projectService for managing project data retrieval and manipulation.
- Enhance EditorPage with file management capabilities and save prompts.
- Introduce Zustand stores for managing authentication, editor state, and project state.
- Add reserved usernames utility to prevent certain usernames during registration.
- Update compilation service to handle multiple files for Arduino sketches.
2026-03-06 10:14:50 -03:00