| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- import * as React from 'react';
- import { GreenPage } from '../types';
- import { Icon } from './ui/Icon';
- import { useTranslation } from '../hooks/useI18n';
- interface PageManagementModalProps {
- pages: GreenPage[];
- activePageId: string;
- onSelectPage: (id: string) => void;
- onCreatePage: (name: string) => void;
- onUpdatePage: (id: string, newName: string) => void;
- onClose: () => void;
- }
- const PageManagementModal: React.FC<PageManagementModalProps> = ({ pages, activePageId, onSelectPage, onCreatePage, onUpdatePage, onClose }) => {
- const { t } = useTranslation();
- const [isCreating, setIsCreating] = React.useState(false);
- const [newPageName, setNewPageName] = React.useState('');
- const [editingPageId, setEditingPageId] = React.useState<string | null>(null);
- const [editingPageName, setEditingPageName] = React.useState('');
- const handleCreate = () => {
- if (newPageName.trim()) {
- onCreatePage(newPageName.trim());
- setNewPageName('');
- setIsCreating(false);
- }
- };
-
- const handleEdit = (page: GreenPage) => {
- setEditingPageId(page.id);
- setEditingPageName(page.name);
- };
- const handleCancelEdit = () => {
- setEditingPageId(null);
- setEditingPageName('');
- };
- const handleSaveEdit = () => {
- if (editingPageId && editingPageName.trim()) {
- onUpdatePage(editingPageId, editingPageName.trim());
- handleCancelEdit();
- }
- };
- return (
- <div className="fixed inset-0 bg-black/70 z-50 flex items-center justify-center backdrop-blur-sm" onClick={onClose}>
- <div className="bg-white dark:bg-gray-800 rounded-2xl shadow-2xl w-full max-w-4xl p-8 border border-gray-200 dark:border-gray-700" onClick={e => e.stopPropagation()}>
- <div className="flex justify-between items-center mb-6">
- <h2 className="text-3xl font-bold text-gray-900 dark:text-white">{t('modal.pages.title')}</h2>
- <button onClick={onClose} className="text-gray-400 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white">
- <Icon className="h-8 w-8">
- <path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
- </Icon>
- </button>
- </div>
- <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
- {pages.map(page => {
- if (editingPageId === page.id) {
- return (
- <div key={page.id} className="p-4 rounded-xl bg-gray-100 dark:bg-gray-700 flex flex-col justify-center gap-3">
- <input
- type="text"
- autoFocus
- value={editingPageName}
- onChange={e => setEditingPageName(e.target.value)}
- onKeyPress={e => e.key === 'Enter' && handleSaveEdit()}
- className="w-full bg-white dark:bg-gray-800 p-2 rounded-md border border-gray-300 dark:border-gray-600 text-gray-900 dark:text-white"
- />
- <div className="flex gap-2">
- <button onClick={handleCancelEdit} className="flex-1 bg-gray-300 dark:bg-gray-600 hover:bg-gray-400 dark:hover:bg-gray-500 text-gray-800 dark:text-white font-semibold py-2 rounded-md text-sm">{t('cancel')}</button>
- <button onClick={handleSaveEdit} className="flex-1 bg-brand-primary hover:bg-brand-secondary text-white font-semibold py-2 rounded-md text-sm">{t('save')}</button>
- </div>
- </div>
- );
- }
- return (
- <div key={page.id} className={`relative group p-6 rounded-xl text-left bg-gradient-to-br ${page.themeColor} transition-all duration-300 transform hover:scale-105`}>
- <button
- onClick={() => onSelectPage(page.id)}
- className={`w-full h-full text-left focus:outline-none focus:ring-4 focus:ring-white/50 rounded-xl ${page.id === activePageId ? 'ring-4 ring-white' : 'ring-2 ring-transparent'}`}
- >
- <p className="text-2xl font-bold text-white break-words">{page.name}</p>
- <p className="text-white/70 text-sm mt-1">{`greenpage.ai/${page.slug}`}</p>
- </button>
- {page.id === activePageId && (
- <div className="absolute top-4 right-4 bg-white/20 rounded-full h-6 w-6 flex items-center justify-center">
- <Icon className="h-4 w-4 text-white">
- <path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
- </Icon>
- </div>
- )}
- <button onClick={() => handleEdit(page)} title={t('edit')} className="absolute bottom-3 right-3 bg-black/20 text-white/70 hover:bg-black/40 hover:text-white p-1 rounded-full opacity-0 group-hover:opacity-100 transition-opacity">
- <Icon className="h-4 w-4"><path d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.536L16.732 3.732z" /></Icon>
- </button>
- </div>
- )
- })}
- {!isCreating ? (
- <button
- onClick={() => setIsCreating(true)}
- className="p-6 rounded-xl flex flex-col items-center justify-center border-2 border-dashed border-gray-300 dark:border-gray-600 hover:border-brand-primary hover:bg-gray-100 dark:hover:bg-gray-700/50 transition-colors"
- >
- <Icon className="h-12 w-12 text-gray-400 dark:text-gray-500 mb-2"><path d="M12 4v16m8-8H4" /></Icon>
- <span className="font-semibold text-gray-500 dark:text-gray-300">{t('modal.pages.create_new')}</span>
- </button>
- ) : (
- <div className="p-6 rounded-xl bg-gray-100 dark:bg-gray-700 flex flex-col justify-center gap-4">
- <input
- type="text"
- autoFocus
- value={newPageName}
- onChange={e => setNewPageName(e.target.value)}
- onKeyPress={e => e.key === 'Enter' && handleCreate()}
- placeholder={`${t('name')}...`}
- className="w-full bg-white dark:bg-gray-800 p-3 rounded-md border border-gray-300 dark:border-gray-600 text-gray-900 dark:text-white"
- />
- <div className="flex gap-2">
- <button onClick={() => setIsCreating(false)} className="flex-1 bg-gray-300 dark:bg-gray-600 hover:bg-gray-400 dark:hover:bg-gray-500 text-gray-800 dark:text-white font-semibold py-2 rounded-md">{t('cancel')}</button>
- <button onClick={handleCreate} className="flex-1 bg-brand-primary hover:bg-brand-secondary text-white font-semibold py-2 rounded-md">{t('add')}</button>
- </div>
- </div>
- )}
- </div>
- </div>
- </div>
- );
- };
- export default PageManagementModal;
|