chore: batch supporting UI, settings schema, templates, and docs updates
This commit is contained in:
@@ -7,7 +7,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@
|
||||
import { Checkbox } from '@/components/ui/checkbox';
|
||||
|
||||
export interface FieldSchema {
|
||||
type: 'text' | 'textarea' | 'email' | 'url' | 'number' | 'toggle' | 'checkbox' | 'select';
|
||||
type: 'text' | 'textarea' | 'email' | 'url' | 'number' | 'toggle' | 'checkbox' | 'select' | 'multiselect';
|
||||
label: string;
|
||||
description?: string;
|
||||
placeholder?: string;
|
||||
@@ -47,8 +47,8 @@ export function SchemaField({ name, schema, value, onChange, error }: SchemaFiel
|
||||
return (
|
||||
<Input
|
||||
type="number"
|
||||
value={value || ''}
|
||||
onChange={(e) => onChange(parseFloat(e.target.value))}
|
||||
value={value ?? ''}
|
||||
onChange={(e) => onChange(e.target.value === '' ? 0 : parseFloat(e.target.value))}
|
||||
placeholder={schema.placeholder}
|
||||
required={schema.required}
|
||||
min={schema.min}
|
||||
@@ -110,6 +110,35 @@ export function SchemaField({ name, schema, value, onChange, error }: SchemaFiel
|
||||
</Select>
|
||||
);
|
||||
|
||||
case 'multiselect':
|
||||
const selectedValues = Array.isArray(value) ? value : [];
|
||||
return (
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{schema.options && Object.entries(schema.options).map(([key, label]) => (
|
||||
<label
|
||||
key={key}
|
||||
className={`flex items-center gap-2 px-3 py-2 rounded-lg border cursor-pointer transition-colors ${
|
||||
selectedValues.includes(key)
|
||||
? 'bg-primary/10 border-primary text-primary'
|
||||
: 'bg-background border-input hover:bg-muted'
|
||||
}`}
|
||||
>
|
||||
<Checkbox
|
||||
checked={selectedValues.includes(key)}
|
||||
onCheckedChange={(checked) => {
|
||||
if (checked) {
|
||||
onChange([...selectedValues, key]);
|
||||
} else {
|
||||
onChange(selectedValues.filter((v: string) => v !== key));
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<span className="text-sm">{label}</span>
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
||||
default:
|
||||
return (
|
||||
<Input
|
||||
|
||||
@@ -164,9 +164,10 @@
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Hide WooNooW app shell - all nav, header, submenu elements */
|
||||
/* Hide WooNooW app shell - all nav, sidebar, header, submenu elements */
|
||||
#woonoow-admin-app header,
|
||||
#woonoow-admin-app nav,
|
||||
#woonoow-admin-app aside,
|
||||
#woonoow-admin-app [data-submenubar],
|
||||
#woonoow-admin-app [data-bottomnav],
|
||||
.woonoow-app-header,
|
||||
@@ -372,4 +373,4 @@ html #wpadminbar {
|
||||
.media-modal .attachments,
|
||||
.media-modal .attachment {
|
||||
pointer-events: auto !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,8 +74,8 @@ export default function CampaignsList() {
|
||||
const { data, isLoading } = useQuery({
|
||||
queryKey: ['campaigns'],
|
||||
queryFn: async () => {
|
||||
const response = await api.get('/campaigns');
|
||||
return response.data as Campaign[];
|
||||
const response: any = await api.get('/campaigns');
|
||||
return Array.isArray(response) ? (response as Campaign[]) : ((response?.data || []) as Campaign[]);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -73,8 +73,8 @@ export default function Campaigns() {
|
||||
const { data, isLoading } = useQuery({
|
||||
queryKey: ['campaigns'],
|
||||
queryFn: async () => {
|
||||
const response = await api.get('/campaigns');
|
||||
return response.data as Campaign[];
|
||||
const response: any = await api.get('/newsletter/campaigns');
|
||||
return Array.isArray(response) ? (response as Campaign[]) : ((response?.data || []) as Campaign[]);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -35,14 +35,16 @@ import {
|
||||
|
||||
export default function Subscribers() {
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [showDeleteDialog, setShowDeleteDialog] = useState(false);
|
||||
const [deleteTargetEmail, setDeleteTargetEmail] = useState<string | null>(null);
|
||||
const queryClient = useQueryClient();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { data: subscribersData, isLoading } = useQuery({
|
||||
queryKey: ['newsletter-subscribers'],
|
||||
queryFn: async () => {
|
||||
const response = await api.get('/newsletter/subscribers');
|
||||
return response.data;
|
||||
const response: any = await api.get('/admin/newsletter/subscribers');
|
||||
return Array.isArray(response) ? response : (response?.data || []);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -13,9 +13,7 @@
|
||||
"strict": true,
|
||||
"allowJs": false,
|
||||
"types": [],
|
||||
"baseUrl": ".",
|
||||
"paths": { "@/*": ["./src/*"] },
|
||||
"ignoreDeprecations": "6.0"
|
||||
"paths": { "@/*": ["./src/*"] }
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user