Skip to content

Latest commit

 

History

History
142 lines (113 loc) · 4.52 KB

File metadata and controls

142 lines (113 loc) · 4.52 KB

In-App Routing Implementation Summary

Overview

Successfully implemented URL-based routing for the YCode editor with a flexible and reusable abstraction that provides both convenience AND control.

Architecture

1. Core Hooks (hooks/use-editor-url.ts)

useEditorUrl() - Low-level URL management

const { routeType, resourceId, view, navigateToPage, navigateToCollection, updateView } = useEditorUrl();
  • Parses current URL state
  • Provides individual navigation functions
  • Used for edge cases (initial load, back/forward)

useEditorActions() - High-level convenience wrapper ✨

const { openPage, openCollection, openComponent } = useEditorActions();
  • Convenience methods - Update BOTH state + URL in one call
  • Individual methods - Still available for edge cases
  • Best of both worlds - DRY + Flexibility

URL Structure

/ycode                                  - Base editor (no selection)
/ycode/pages/[id]?view=details         - Page editing (general settings)
/ycode/pages/[id]?view=seo             - Page SEO settings
/ycode/pages/[id]?view=code            - Page custom code
/ycode/collections/[id]?view=items     - Collection items view
/ycode/collections/[id]?view=fields    - Collection fields management
/ycode/collections/[id]?view=settings  - Collection settings
/ycode/components/[id]                 - Component editing

Usage Patterns

✅ Normal User Interactions (Convenience Methods)

// In components - use convenience methods for user clicks
const { openPage, openCollection } = useEditorActions();

// Click a page → updates both state + URL
openPage(pageId);

// Click a collection → updates both state + URL
openCollection(collectionId, 'items');

✅ Edge Cases (Individual Methods)

// Initial load from URL - state only, don't re-navigate
const { setCurrentPageId } = useEditorActions();
setCurrentPageId(pageId); // Updates state without pushing to router

// Browser back/forward - state only
setCurrentPageId(previousPageId); // Sync state without re-navigating

✅ URL-only Updates (Query Params)

// Switch tabs in settings panel - URL only
const { updateView } = useEditorUrl();
updateView('seo'); // Changes ?view=seo

Component Updates

Updated Components:

  • LeftSidebarPages.tsx - Uses openPage() for clicks
  • LeftSidebar.tsx - Uses openCollection() for clicks
  • RightSidebar.tsx - Uses openComponent() for component edit
  • PageSettingsPanel.tsx - Uses updateView() for sub-tabs
  • app/ycode/page.tsx - Reads URL on mount, syncs state

Key Benefits:

  1. DRY Code - No duplicate navigation calls
  2. Flexibility - Can update state OR URL independently when needed
  3. Type Safety - TypeScript enforces correct view types
  4. Maintainable - Centralized routing logic
  5. Testable - Clear separation of concerns

Testing Checklist

✅ Click a page → URL changes to /ycode/pages/[id]
✅ Click a collection → URL changes to /ycode/collections/[id]?view=items
✅ Switch settings tab → Query param updates ?view=seo
✅ Refresh page → State restored from URL
✅ Browser back/forward → Navigation works correctly
✅ Delete page → Navigates to next page
✅ Create collection → Opens the new collection
✅ Component edit → URL changes to /ycode/components/[id]

Future Enhancements

Potential additions:

  • Deep linking to specific layers (e.g., ?layer=layer-123)
  • Query params for zoom level
  • History API for undo/redo URLs
  • Collection view query params (items/fields/settings)

Files Modified

New Files:

  • app/ycode/pages/[id]/page.tsx
  • app/ycode/collections/[id]/page.tsx
  • app/ycode/components/[id]/page.tsx
  • hooks/use-editor-url.ts (with useEditorActions)

Updated Files:

  • app/ycode/page.tsx
  • app/ycode/components/LeftSidebarPages.tsx
  • app/ycode/components/LeftSidebar.tsx
  • app/ycode/components/RightSidebar.tsx
  • app/ycode/components/PageSettingsPanel.tsx

Best Practices

Do ✅

// Use convenience methods for user interactions
const { openPage } = useEditorActions();
openPage(pageId);

Don't ❌

// Avoid manually calling both - use convenience method
setCurrentPageId(pageId);
navigateToPage(pageId); // Redundant!

Edge Cases ✅

// For URL sync without navigation (e.g., initial load)
const { setCurrentPageId } = useEditorActions();
setCurrentPageId(pageIdFromUrl); // State only