feat: add mobile video generator page with Remotion integration for rendering and publishing.

This commit is contained in:
Michael committed 2026-03-25 11:46:15 +01:00
1 parent 0f49218f62
commit 59caa19fbe
2 files changed
+41 -20

No files matched your search

+35 -18
View File
@@ -124,6 +124,7 @@ export default function MobileRemotionVideoPage() {
selectedLibraryImages.forEach(m => formData.append("existingImageUrls", m.originalUrl));
if (overlayText) formData.append("overlayText", overlayText);
if (ttsEnabled && overlayText) formData.append("ttsVoice", ttsVoice);
if (selectedPageIds[0]) formData.append("selectedPageId", selectedPageIds[0]);
if (musicFile) { formData.append("music", musicFile); formData.append("musicVolume", String(musicVolume)); }
else if (selectedTrack) { formData.append("musicTrackUrl", selectedTrack.url); formData.append("musicVolume", String(musicVolume)); }
const response = await fetch("/api/remotion/render", { method: "POST", body: formData });
@@ -330,6 +331,35 @@ export default function MobileRemotionVideoPage() {
</CardContent>
</Card>
{/* 4. Page Facebook */}
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-base flex items-center gap-2"><Send className="w-4 h-4" /> 4. Page Facebook</CardTitle>
</CardHeader>
<CardContent className="space-y-2">
{facebookPages.length === 0 ? (
<p className="text-xs text-muted-foreground">Aucune page Facebook connectée.</p>
) : (
facebookPages.map(page => (
<div key={page.id} className="flex items-center gap-3">
<Checkbox
id={`page-${page.id}`}
checked={selectedPageIds.includes(page.id)}
onCheckedChange={checked =>
setSelectedPageIds(prev =>
checked ? [...prev, page.id] : prev.filter(id => id !== page.id)
)
}
/>
<label htmlFor={`page-${page.id}`} className="text-sm font-medium cursor-pointer">
{page.pageName}
</label>
</div>
))
)}
</CardContent>
</Card>
{/* Générer */}
<Button onClick={handleGenerate} disabled={isRendering || totalSelected < 3} className="w-full h-12" size="lg">
{isRendering
@@ -351,25 +381,12 @@ export default function MobileRemotionVideoPage() {
<CardContent className="space-y-3">
{facebookPages.length === 0 ? (
<p className="text-xs text-muted-foreground">Aucune page Facebook connectée.</p>
) : selectedPageIds.length === 0 ? (
<p className="text-xs text-muted-foreground">Sélectionnez une page ci-dessus.</p>
) : (
<div className="space-y-2">
{facebookPages.map(page => (
<div key={page.id} className="flex items-center gap-3">
<Checkbox
id={`mpub-${page.id}`}
checked={selectedPageIds.includes(page.id)}
onCheckedChange={checked =>
setSelectedPageIds(prev =>
checked ? [...prev, page.id] : prev.filter(id => id !== page.id)
)
}
/>
<label htmlFor={`mpub-${page.id}`} className="text-sm font-medium cursor-pointer">
{page.pageName}
</label>
</div>
))}
</div>
<p className="text-xs text-primary font-medium">
Pages : {facebookPages.filter(p => selectedPageIds.includes(p.id)).map(p => p.pageName).join(', ')}
</p>
)}
<Textarea rows={2} placeholder="Description (optionnel)" value={publishDescription}
onChange={e => setPublishDescription(e.target.value)} />
+6 -2
View File
@@ -173,7 +173,10 @@ remotionRouter.post("/render", upload.fields([{ name: "images", maxCount: 4 }, {
if (user?.id) {
const pages = await dbStorage.getSocialPages(user.id);
if (pages.length > 0) {
storeName = pages[0].pageName;
// Use the page selected by the user, or fall back to first page
const selectedPageId = req.body.selectedPageId as string | undefined;
const page = selectedPageId ? pages.find(p => p.id === selectedPageId) : pages[0];
storeName = (page ?? pages[0]).pageName;
console.log("🏪 Store name:", storeName);
}
}
@@ -269,7 +272,8 @@ remotionRouter.post("/render", upload.fields([{ name: "images", maxCount: 4 }, {
});
console.log("✅ Render completed:", outputFilename);
res.json({ url: `${host}/uploads/temp/${outputFilename}` });
// Return relative URL so any client (mobile, desktop, Docker) can access it
res.json({ url: `/uploads/temp/${outputFilename}` });
} catch (err: any) {
console.error("❌ Remotion render error:", err);