Sync layouts, typography, and watermark studio for self-hosted OSS.

Unlock features without credits/Stripe, point docs to docs.songs2vid.com, and drop leftover billing admin surfaces.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Songs2YT
2026-07-25 03:50:06 +02:00
co-authored by Cursor
parent bcca0a6e6f
commit d951ecb489
53 changed files with 3258 additions and 1977 deletions
+4 -12
View File
@@ -20,12 +20,7 @@ const STATUS_LABELS: Record<string, string> = {
export function JobProgress({ jobId }: Props) {
const [job, setJob] = useState<JobResponse | null>(null);
const [quota, setQuota] = useState<{
remaining: number;
limit: number;
plan: string;
resetsIn: string;
} | null>(null);
const [videosProcessed, setVideosProcessed] = useState<number | null>(null);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
@@ -44,7 +39,7 @@ export function JobProgress({ jobId }: Props) {
if (quotaRes.ok) {
const quotaData = await quotaRes.json();
if (active) setQuota({ remaining: quotaData.remaining, limit: quotaData.limit, plan: quotaData.plan, resetsIn: quotaData.resetsIn });
if (active) setVideosProcessed(quotaData.used ?? 0);
}
} catch (err) {
if (active) setError(err instanceof Error ? err.message : "Error loading job");
@@ -81,12 +76,9 @@ export function JobProgress({ jobId }: Props) {
Overall: <span className="text-white">{job.status}</span>
</p>
</div>
{quota && (
{videosProcessed !== null && (
<div className="rounded bg-surface-light px-4 py-2 text-sm text-gray-300">
{quota.remaining} / {quota.limit} videos remaining ·{" "}
{quota.plan === "FREE"
? `resets in ${quota.resetsIn}`
: `monthly quota resets on ${quota.resetsIn}`}
Self-hosted · {videosProcessed} videos processed
</div>
)}
</div>