style(studio): elevate GoLiveView to SaaS Premium
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
5159b9f34c
commit
007eba6157
8 changed files with 36 additions and 41 deletions
|
|
@ -8,7 +8,7 @@ const meta: Meta<typeof GoLiveView> = {
|
|||
tags: ['autodocs'],
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<div className="bg-kodo-background min-h-layout-main p-4">
|
||||
<div className="bg-background min-h-layout-main p-4">
|
||||
<Story />
|
||||
</div>
|
||||
),
|
||||
|
|
|
|||
|
|
@ -19,18 +19,18 @@ export function GoLiveViewEncoderSetup({
|
|||
}: GoLiveViewEncoderSetupProps) {
|
||||
return (
|
||||
<Card variant="glass">
|
||||
<h3 className="font-bold text-white mb-4 text-sm uppercase tracking-wider flex items-center gap-2">
|
||||
<Settings className="w-4 h-4 text-kodo-gold" /> Encoder Setup
|
||||
<h3 className="font-bold text-foreground mb-4 text-sm uppercase tracking-wider flex items-center gap-2">
|
||||
<Settings className="w-4 h-4 text-warning" /> Encoder Setup
|
||||
</h3>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<label className="block text-xs font-bold text-kodo-content-dim uppercase mb-2">
|
||||
<label className="block text-xs font-bold text-muted-foreground uppercase mb-2">
|
||||
Server URL
|
||||
</label>
|
||||
<div className="flex gap-2">
|
||||
<input
|
||||
className="flex-1 bg-kodo-ink border border-kodo-steel rounded px-4 py-2 text-sm text-kodo-text-main font-mono"
|
||||
className="flex-1 bg-muted border border-border rounded-xl px-4 py-2 text-sm text-foreground font-mono"
|
||||
value={serverUrl}
|
||||
readOnly
|
||||
aria-label="Server URL"
|
||||
|
|
@ -38,7 +38,7 @@ export function GoLiveViewEncoderSetup({
|
|||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="border border-kodo-steel"
|
||||
className="border border-border"
|
||||
onClick={() => onCopy(serverUrl, 'Server URL')}
|
||||
aria-label="Copy Server URL"
|
||||
>
|
||||
|
|
@ -48,12 +48,12 @@ export function GoLiveViewEncoderSetup({
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-xs font-bold text-kodo-content-dim uppercase mb-2">
|
||||
<label className="block text-xs font-bold text-muted-foreground uppercase mb-2">
|
||||
Stream Key
|
||||
</label>
|
||||
<div className="flex gap-2">
|
||||
<input
|
||||
className="flex-1 bg-kodo-ink border border-kodo-steel rounded px-4 py-2 text-sm text-kodo-text-main font-mono"
|
||||
className="flex-1 bg-muted border border-border rounded-xl px-4 py-2 text-sm text-foreground font-mono"
|
||||
value={streamKeyVisible ? streamKey : '•••••••••••••••••••••••••'}
|
||||
readOnly
|
||||
type={streamKeyVisible ? 'text' : 'password'}
|
||||
|
|
@ -62,7 +62,7 @@ export function GoLiveViewEncoderSetup({
|
|||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="border border-kodo-steel"
|
||||
className="border border-border"
|
||||
onClick={onToggleStreamKeyVisible}
|
||||
aria-label={streamKeyVisible ? 'Hide stream key' : 'Show stream key'}
|
||||
>
|
||||
|
|
@ -75,14 +75,14 @@ export function GoLiveViewEncoderSetup({
|
|||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="border border-kodo-steel"
|
||||
className="border border-border"
|
||||
onClick={() => onCopy(streamKey, 'Stream Key')}
|
||||
aria-label="Copy Stream Key"
|
||||
>
|
||||
<Copy className="w-4 h-4" />
|
||||
</Button>
|
||||
</div>
|
||||
<p className="text-xs text-kodo-red mt-2 flex items-center gap-1">
|
||||
<p className="text-xs text-destructive mt-2 flex items-center gap-1">
|
||||
<EyeOff className="w-3 h-3" /> Never share your stream key!
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -8,34 +8,29 @@ interface GoLiveViewHeaderProps {
|
|||
|
||||
export function GoLiveViewHeader({ isLive, onToggleStream }: GoLiveViewHeaderProps) {
|
||||
return (
|
||||
<div className="flex justify-between items-center mb-8 border-b border-kodo-steel/50 pb-6">
|
||||
<div className="flex justify-between items-center mb-8 border-b border-border pb-6">
|
||||
<div>
|
||||
<h1 className="text-3xl font-display font-bold text-white mb-2 flex items-center gap-4">
|
||||
<h1 className="text-3xl font-display font-bold text-foreground mb-2 flex items-center gap-4 tracking-tight">
|
||||
<Radio
|
||||
className={`w-8 h-8 ${isLive ? 'text-kodo-red animate-pulse' : 'text-kodo-content-dim'}`}
|
||||
className={`w-8 h-8 ${isLive ? 'text-destructive animate-pulse' : 'text-muted-foreground'}`}
|
||||
/>
|
||||
BROADCAST STUDIO
|
||||
</h1>
|
||||
<p className="text-kodo-content-dim font-mono text-sm">
|
||||
<p className="text-muted-foreground font-mono text-sm">
|
||||
Configure your stream and go live.
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex gap-4">
|
||||
<div
|
||||
className={`px-4 py-2 rounded-lg border flex items-center gap-2 font-bold ${isLive ? 'bg-kodo-red text-white border-kodo-red' : 'bg-kodo-ink text-kodo-content-dim border-kodo-steel'}`}
|
||||
className={`px-4 py-2 rounded-xl border flex items-center gap-2 font-bold ${isLive ? 'bg-destructive text-destructive-foreground border-destructive' : 'bg-card text-muted-foreground border-border'}`}
|
||||
>
|
||||
<div
|
||||
className={`w-3 h-3 rounded-full ${isLive ? 'bg-white animate-pulse' : 'bg-kodo-steel'}`}
|
||||
className={`w-3 h-3 rounded-full ${isLive ? 'bg-white animate-pulse' : 'bg-muted'}`}
|
||||
/>
|
||||
{isLive ? 'LIVE' : 'OFFLINE'}
|
||||
</div>
|
||||
<Button
|
||||
variant={isLive ? 'secondary' : 'primary'}
|
||||
className={
|
||||
isLive
|
||||
? 'border-kodo-red text-kodo-red hover:bg-kodo-red/10'
|
||||
: 'bg-kodo-lime text-black hover:bg-white'
|
||||
}
|
||||
variant={isLive ? 'destructive' : 'primary'}
|
||||
icon={
|
||||
isLive ? (
|
||||
<Square className="w-4 h-4 fill-current" />
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@ import { Mic } from 'lucide-react';
|
|||
|
||||
export function GoLiveViewMicLevel() {
|
||||
return (
|
||||
<div className="bg-kodo-ink p-4 rounded-xl border border-kodo-steel">
|
||||
<div className="bg-card p-4 rounded-xl border border-border">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<span className="text-sm text-kodo-text-main">Microphone</span>
|
||||
<Mic className="w-4 h-4 text-kodo-lime" />
|
||||
<span className="text-sm text-foreground">Microphone</span>
|
||||
<Mic className="w-4 h-4 text-success" />
|
||||
</div>
|
||||
<div className="w-full bg-kodo-graphite h-2 rounded-full overflow-hidden">
|
||||
<div className="h-full bg-kodo-lime w-3/5 animate-pulse" />
|
||||
<div className="w-full bg-muted h-2 rounded-full overflow-hidden">
|
||||
<div className="h-full bg-success w-3/5 animate-pulse" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -6,16 +6,16 @@ interface GoLiveViewPreviewProps {
|
|||
|
||||
export function GoLiveViewPreview({ isLive }: GoLiveViewPreviewProps) {
|
||||
return (
|
||||
<div className="aspect-video bg-black rounded-xl overflow-hidden border border-kodo-steel relative group">
|
||||
<div className="aspect-video bg-black rounded-xl overflow-hidden border border-border relative group">
|
||||
{isLive ? (
|
||||
<div className="w-full h-full flex items-center justify-center bg-kodo-ink">
|
||||
<div className="w-full h-full flex items-center justify-center bg-card">
|
||||
<div className="text-center animate-pulse">
|
||||
<Radio className="w-16 h-16 text-kodo-red mx-auto mb-4" />
|
||||
<p className="text-kodo-content-dim">Receiving Stream Data...</p>
|
||||
<Radio className="w-16 h-16 text-destructive mx-auto mb-4" />
|
||||
<p className="text-muted-foreground">Receiving Stream Data...</p>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="w-full h-full flex flex-col items-center justify-center bg-kodo-ink/50 text-kodo-content-dim">
|
||||
<div className="w-full h-full flex flex-col items-center justify-center bg-card/50 text-muted-foreground">
|
||||
<div className="text-center">
|
||||
<Monitor className="w-16 h-16 mx-auto mb-4 opacity-50" />
|
||||
<p>Stream Offline</p>
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@ import { Card } from '@/components/ui/card';
|
|||
export function GoLiveViewQuickInstructions() {
|
||||
return (
|
||||
<Card variant="default">
|
||||
<h3 className="font-bold text-white mb-4 text-sm uppercase tracking-wider">
|
||||
<h3 className="font-bold text-foreground mb-4 text-sm uppercase tracking-wider">
|
||||
Quick Instructions
|
||||
</h3>
|
||||
<ol className="text-sm text-kodo-content-dim space-y-2 list-decimal pl-4">
|
||||
<ol className="text-sm text-muted-foreground space-y-2 list-decimal pl-4">
|
||||
<li>Open OBS or Streamlabs.</li>
|
||||
<li>Go to Settings {'>'} Stream.</li>
|
||||
<li>Select "Custom" service.</li>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
export function GoLiveViewSkeleton() {
|
||||
return (
|
||||
<div className="animate-fadeIn pb-20 max-w-6xl mx-auto">
|
||||
<div className="flex justify-between items-center mb-8 border-b border-kodo-steel/50 pb-6">
|
||||
<div className="flex justify-between items-center mb-8 border-b border-border pb-6">
|
||||
<div className="space-y-2">
|
||||
<div className="h-9 w-64 rounded bg-muted animate-pulse" />
|
||||
<div className="h-4 w-56 rounded bg-muted animate-pulse" />
|
||||
|
|
@ -18,7 +18,7 @@ export function GoLiveViewSkeleton() {
|
|||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
||||
<div className="lg:col-span-2 space-y-6">
|
||||
<div className="aspect-video rounded-xl bg-muted animate-pulse" />
|
||||
<div className="rounded-xl border border-kodo-steel p-6 space-y-4">
|
||||
<div className="rounded-xl border border-border p-6 space-y-4">
|
||||
<div className="h-5 w-40 rounded bg-muted animate-pulse" />
|
||||
<div className="h-11 w-full rounded-lg bg-muted animate-pulse" />
|
||||
<div className="h-11 w-full rounded-lg bg-muted animate-pulse" />
|
||||
|
|
@ -41,7 +41,7 @@ export function GoLiveViewSkeleton() {
|
|||
<div className="h-4 w-full rounded bg-muted animate-pulse" />
|
||||
<div className="h-4 w-3/4 rounded bg-muted animate-pulse" />
|
||||
</div>
|
||||
<div className="p-4 rounded-xl border border-kodo-steel space-y-2">
|
||||
<div className="p-4 rounded-xl border border-border space-y-2">
|
||||
<div className="h-4 w-24 rounded bg-muted animate-pulse" />
|
||||
<div className="h-2 w-full rounded-full bg-muted animate-pulse" />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -21,15 +21,15 @@ export function GoLiveViewStreamInfo({
|
|||
}: GoLiveViewStreamInfoProps) {
|
||||
return (
|
||||
<Card variant="default">
|
||||
<h3 className="font-bold text-white mb-4">Stream Information</h3>
|
||||
<h3 className="font-bold text-foreground mb-4 tracking-tight">Stream Information</h3>
|
||||
<div className="space-y-4">
|
||||
<Input label="Title" value={title} onChange={(e) => onTitleChange(e.target.value)} />
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-kodo-content-dim mb-2">
|
||||
<label className="block text-sm font-medium text-muted-foreground mb-2">
|
||||
Category
|
||||
</label>
|
||||
<select
|
||||
className="w-full bg-kodo-graphite border border-kodo-steel rounded-lg px-4 py-4 text-white focus:border-kodo-steel outline-none"
|
||||
className="w-full bg-muted border border-border rounded-xl px-4 py-4 text-foreground focus:border-primary outline-none transition-colors duration-[var(--duration-normal)]"
|
||||
value={category}
|
||||
onChange={(e) => onCategoryChange(e.target.value as StreamCategory)}
|
||||
>
|
||||
|
|
|
|||
Loading…
Reference in a new issue