fix: Create Page dialog improvements

- Add horizontal padding to dialog content (px-1)
- Show real site URL from WNW_CONFIG.siteUrl instead of 'yoursite.com'
- Improve error handling to extract message from response.data.message
- Better slug generation regex (removes special chars properly)
- Reset form when modal closes
- Use theme colors (text-muted-foreground, hover:bg-accent/50)
This commit is contained in:
Dwindi Ramadhana
2026-01-11 23:15:59 +07:00
parent 6c79e7cbac
commit fe243a42cb

View File

@@ -1,4 +1,4 @@
import React, { useState } from 'react'; import React, { useState, useEffect } from 'react';
import { useMutation } from '@tanstack/react-query'; import { useMutation } from '@tanstack/react-query';
import { api } from '@/lib/api'; import { api } from '@/lib/api';
import { __ } from '@/lib/i18n'; import { __ } from '@/lib/i18n';
@@ -36,6 +36,9 @@ export function CreatePageModal({ open, onOpenChange, onCreated }: CreatePageMod
const [title, setTitle] = useState(''); const [title, setTitle] = useState('');
const [slug, setSlug] = useState(''); const [slug, setSlug] = useState('');
// Get site URL from WordPress config
const siteUrl = window.WNW_CONFIG?.siteUrl?.replace(/\/$/, '') || window.location.origin;
// Create page mutation // Create page mutation
const createMutation = useMutation({ const createMutation = useMutation({
mutationFn: async () => { mutationFn: async () => {
@@ -61,21 +64,36 @@ export function CreatePageModal({ open, onOpenChange, onCreated }: CreatePageMod
} }
}, },
onError: (error: any) => { onError: (error: any) => {
toast.error(error?.message || __('Failed to create page')); // Extract error message from the response
const message = error?.response?.data?.message ||
error?.message ||
__('Failed to create page');
toast.error(message);
}, },
}); });
// Auto-generate slug from title // Auto-generate slug from title
const handleTitleChange = (value: string) => { const handleTitleChange = (value: string) => {
setTitle(value); setTitle(value);
if (!slug || slug === title.toLowerCase().replace(/\s+/g, '-')) { // Auto-generate slug only if slug matches the previously auto-generated value
setSlug(value.toLowerCase().replace(/\s+/g, '-')); const autoSlug = title.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');
if (!slug || slug === autoSlug) {
setSlug(value.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, ''));
} }
}; };
// Reset form when modal closes
useEffect(() => {
if (!open) {
setTitle('');
setSlug('');
setPageType('page');
}
}, [open]);
return ( return (
<Dialog open={open} onOpenChange={onOpenChange}> <Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="sm:max-w-[425px]"> <DialogContent className="sm:max-w-[500px]">
<DialogHeader> <DialogHeader>
<DialogTitle>{__('Create New Page')}</DialogTitle> <DialogTitle>{__('Create New Page')}</DialogTitle>
<DialogDescription> <DialogDescription>
@@ -83,30 +101,30 @@ export function CreatePageModal({ open, onOpenChange, onCreated }: CreatePageMod
</DialogDescription> </DialogDescription>
</DialogHeader> </DialogHeader>
<div className="space-y-6 py-4"> <div className="space-y-6 py-4 px-1">
{/* Page Type Selection */} {/* Page Type Selection */}
<RadioGroup value={pageType} onValueChange={(v) => setPageType(v as 'page' | 'template')}> <RadioGroup value={pageType} onValueChange={(v) => setPageType(v as 'page' | 'template')}>
<div className="flex items-start space-x-3 p-4 border rounded-lg cursor-pointer hover:bg-gray-50"> <div className="flex items-start space-x-3 p-4 border rounded-lg cursor-pointer hover:bg-accent/50 transition-colors">
<RadioGroupItem value="page" id="page" className="mt-1" /> <RadioGroupItem value="page" id="page" className="mt-1" />
<div className="flex-1"> <div className="flex-1">
<Label htmlFor="page" className="flex items-center gap-2 cursor-pointer font-medium"> <Label htmlFor="page" className="flex items-center gap-2 cursor-pointer font-medium">
<FileText className="w-4 h-4" /> <FileText className="w-4 h-4" />
{__('Structural Page')} {__('Structural Page')}
</Label> </Label>
<p className="text-sm text-gray-500 mt-1"> <p className="text-sm text-muted-foreground mt-1">
{__('Static content like About, Contact, Terms')} {__('Static content like About, Contact, Terms')}
</p> </p>
</div> </div>
</div> </div>
<div className="flex items-start space-x-3 p-4 border rounded-lg cursor-pointer hover:bg-gray-50 opacity-50"> <div className="flex items-start space-x-3 p-4 border rounded-lg cursor-pointer opacity-50">
<RadioGroupItem value="template" id="template" className="mt-1" disabled /> <RadioGroupItem value="template" id="template" className="mt-1" disabled />
<div className="flex-1"> <div className="flex-1">
<Label htmlFor="template" className="flex items-center gap-2 cursor-pointer font-medium"> <Label htmlFor="template" className="flex items-center gap-2 cursor-pointer font-medium">
<Layout className="w-4 h-4" /> <Layout className="w-4 h-4" />
{__('CPT Template')} {__('CPT Template')}
</Label> </Label>
<p className="text-sm text-gray-500 mt-1"> <p className="text-sm text-muted-foreground mt-1">
{__('Templates are auto-created for each post type')} {__('Templates are auto-created for each post type')}
</p> </p>
</div> </div>
@@ -131,11 +149,11 @@ export function CreatePageModal({ open, onOpenChange, onCreated }: CreatePageMod
<Input <Input
id="slug" id="slug"
value={slug} value={slug}
onChange={(e) => setSlug(e.target.value)} onChange={(e) => setSlug(e.target.value.toLowerCase().replace(/[^a-z0-9-]/g, ''))}
placeholder={__('e.g., about-us')} placeholder={__('e.g., about-us')}
/> />
<p className="text-xs text-gray-500"> <p className="text-xs text-muted-foreground">
{__('URL will be: ')}yoursite.com/{slug || 'page-slug'} {__('URL will be: ')}<span className="font-mono text-primary">{siteUrl}/{slug || 'page-slug'}</span>
</p> </p>
</div> </div>
</div> </div>