feat: implement onboarding wizard and fix help page navigation

Core Features:
- Add Quick Setup Wizard for new users with multi-step flow
- Implement distraction-free onboarding layout (no sidebar/header)
- Create OnboardingController API endpoint for saving settings
- Redirect new users to /setup automatically on first admin access

Onboarding Components:
- StepMode: Select between full/minimal store modes
- StepHomepage: Choose or auto-create homepage
- StepAppearance: Configure container width and primary color
- StepProgress: Visual progress indicator

Navigation & Routing:
- Fix Help page links to use react-router navigation (prevent full reload)
- Update onboarding completion redirect to /appearance/pages
- Add manual onboarding access via Settings > Store Details

UI/UX Improvements:
- Enable dark mode support for Page Editor
- Fix page title rendering in onboarding dropdown
- Improve title fallback logic (title.rendered, title, post_title)

Type Safety:
- Unify PageItem interface across all components
- Add 'default' to containerWidth type definition
- Add missing properties (permalink_base, has_template, icon)

Files Modified:
- includes/Api/OnboardingController.php
- includes/Api/Routes.php
- includes/Admin/Assets.php
- admin-spa/src/App.tsx
- admin-spa/src/routes/Onboarding/*
- admin-spa/src/routes/Help/DocContent.tsx
- admin-spa/src/routes/Settings/Store.tsx
- admin-spa/src/routes/Appearance/Pages/*
This commit is contained in:
Dwindi Ramadhana
2026-02-06 00:30:38 +07:00
parent 7da4f0a167
commit 687a2318b0
15 changed files with 755 additions and 124 deletions

View File

@@ -32,7 +32,7 @@ import {
import { InspectorField, SectionProp } from './InspectorField';
import { InspectorRepeater } from './InspectorRepeater';
import { MediaUploader } from '@/components/MediaUploader';
import { SectionStyles, ElementStyle } from '../store/usePageEditorStore';
import { SectionStyles, ElementStyle, PageItem } from '../store/usePageEditorStore';
interface Section {
id: string;
@@ -44,17 +44,6 @@ interface Section {
props: Record<string, SectionProp>;
}
interface PageItem {
id?: number;
type: 'page' | 'template';
cpt?: string;
slug?: string;
title: string;
url?: string;
isSpaLanding?: boolean;
containerWidth?: 'boxed' | 'fullwidth';
}
interface InspectorPanelProps {
page: PageItem | null;
selectedSection: Section | null;

View File

@@ -3,15 +3,7 @@ import { __ } from '@/lib/i18n';
import { cn } from '@/lib/utils';
import { FileText, Layout, Loader2, Home } from 'lucide-react';
interface PageItem {
id?: number;
type: 'page' | 'template';
cpt?: string;
slug?: string;
title: string;
has_template?: boolean;
permalink_base?: string;
}
import { PageItem } from '../store/usePageEditorStore';
interface PageSidebarProps {
pages: PageItem[];

View File

@@ -10,21 +10,7 @@ import { PageSidebar } from './components/PageSidebar';
import { CanvasRenderer } from './components/CanvasRenderer';
import { InspectorPanel } from './components/InspectorPanel';
import { CreatePageModal } from './components/CreatePageModal';
import { usePageEditorStore, Section } from './store/usePageEditorStore';
// Types
interface PageItem {
id?: number;
type: 'page' | 'template';
cpt?: string;
slug?: string;
title: string;
url?: string;
icon?: string;
has_template?: boolean;
permalink_base?: string;
isFrontPage?: boolean;
}
import { usePageEditorStore, Section, PageItem } from './store/usePageEditorStore';
export default function AppearancePages() {
const queryClient = useQueryClient();
@@ -229,12 +215,12 @@ export default function AppearancePages() {
return (
<div className={
cn(
"flex flex-col bg-white transition-all duration-300",
"flex flex-col bg-background transition-all duration-300",
isFullscreen ? "fixed inset-0 z-[100] h-screen" : "h-[calc(100vh-64px)]"
)
} >
{/* Header */}
< div className="flex items-center justify-between px-6 py-3 border-b bg-white" >
< div className="flex items-center justify-between px-6 py-3 border-b bg-background" >
<div>
<h1 className="text-xl font-semibold">{__('Page Editor')}</h1>
<p className="text-sm text-muted-foreground">
@@ -315,7 +301,7 @@ export default function AppearancePages() {
}
/>
) : (
<div className="flex-1 bg-gray-100 flex items-center justify-center text-gray-400">
<div className="flex-1 bg-muted/30 flex items-center justify-center text-muted-foreground">
<div className="text-center">
<Layout className="w-16 h-16 mx-auto mb-4 opacity-50" />
<p className="text-lg">{__('Select a page from the sidebar')}</p>

View File

@@ -60,9 +60,12 @@ export interface PageItem {
slug?: string;
title: string;
url?: string;
icon?: string;
has_template?: boolean;
permalink_base?: string;
isFrontPage?: boolean;
isSpaLanding?: boolean;
containerWidth?: 'boxed' | 'fullwidth';
containerWidth?: 'boxed' | 'fullwidth' | 'default';
}
interface PageEditorState {