- Browse dashboard at / with search, framework filter, tag pills, and pagination - Tags system with autocomplete datalist and per-fiddle tag management - Listed/unlisted toggle for visibility control (unlisted still accessible via direct URL) - Export standalone HTML with inlined CSS/JS and framework CDN tags - QR code modal for sharing fiddle URLs - Embed mode at /embed/:id for minimal preview-only rendering - Extract shared loadScript() utility from 4 files into utils.js - Database schema: listed column, tags and fiddle_tags tables with index
42 lines
1.1 KiB
JavaScript
42 lines
1.1 KiB
JavaScript
const BASE = '/api/fiddles';
|
|
|
|
async function request(url, opts = {}) {
|
|
const res = await fetch(url, {
|
|
headers: { 'Content-Type': 'application/json' },
|
|
...opts,
|
|
});
|
|
if (!res.ok) {
|
|
const err = await res.json().catch(() => ({ error: res.statusText }));
|
|
throw new Error(err.error || res.statusText);
|
|
}
|
|
return res.json();
|
|
}
|
|
|
|
export function createFiddle(data) {
|
|
return request(BASE, { method: 'POST', body: JSON.stringify(data) });
|
|
}
|
|
|
|
export function loadFiddle(id) {
|
|
return request(`${BASE}/${id}`);
|
|
}
|
|
|
|
export function updateFiddle(id, data) {
|
|
return request(`${BASE}/${id}`, { method: 'PUT', body: JSON.stringify(data) });
|
|
}
|
|
|
|
export function listFiddles({ q, js_type, tag, page, limit, sort } = {}) {
|
|
const params = new URLSearchParams();
|
|
if (q) params.set('q', q);
|
|
if (js_type) params.set('js_type', js_type);
|
|
if (tag) params.set('tag', tag);
|
|
if (page) params.set('page', String(page));
|
|
if (limit) params.set('limit', String(limit));
|
|
if (sort) params.set('sort', sort);
|
|
const qs = params.toString();
|
|
return request(`${BASE}${qs ? '?' + qs : ''}`);
|
|
}
|
|
|
|
export function listTags() {
|
|
return request('/api/tags');
|
|
}
|