Your account can't create a new workspace right now.
{availableWorkspaces.length > 0 ? (
You can still create projects inside workspaces where you already have admin access.
) : (
You don't currently have a workspace where you can create projects. Ask a
workspace owner to invite you as an admin, or upgrade later to create your own
workspace.
)}
);
}
return (
Create your workspace
Workspaces organize your projects and team members.
{canCreateWorkspace
? 'You skipped workspace creation. Projects require a workspace — you can create both from the dashboard later.'
: availableWorkspaces.length === 0
? 'You do not currently have permission to create projects in any workspace.'
: 'Pick a workspace in the previous step to create a project here.'}
) : (
)}
);
}
// ─── Step 4: Add First Video (informational) ───────────────────────────────────
function StepVideo({ onNext }: { onNext: () => void }) {
return (
Adding videos
OpenFrame supports two ways to add video content to your projects.
YouTube link
Paste a link to any YouTube video. OpenFrame will pull in the title, thumbnail, and
duration automatically — no file upload needed.
Direct upload
Upload video files directly from your device. Files are processed and delivered via CDN
for fast, reliable playback worldwide.
Choose when you want to be notified. Email and Telegram are both supported — you can
configure Telegram anytime in Settings.
Channels
setEmailEnabled((v) => !v)}
label="Email notifications"
description="Receive emails to your account address"
/>
Events
setEvents((e) => ({ ...e, onNewVideo: !e.onNewVideo }))}
label="New Video Added"
description="When a new video is added to one of your projects"
/>
setEvents((e) => ({ ...e, onNewVersion: !e.onNewVersion }))}
label="New Version Added"
description="When a new version is added to an existing video"
/>
setEvents((e) => ({ ...e, onNewComment: !e.onNewComment }))}
label="New Comment"
description="When someone leaves a comment on your videos"
/>
setEvents((e) => ({ ...e, onNewReply: !e.onNewReply }))}
label="New Reply"
description="When someone replies to a comment thread"
/>
setEvents((e) => ({ ...e, onApprovalEvents: !e.onApprovalEvents }))}
label="Approval Workflow"
description="When approval requests are created, responded to, or finalized"
/>