2026-01-18 15:28:22 +00:00
|
|
|
import React, { useState, useEffect } from 'react';
|
|
|
|
|
import { createPortal } from 'react-dom';
|
2026-01-07 09:31:02 +00:00
|
|
|
import { Button } from '../../ui/button';
|
|
|
|
|
import { Input } from '../../ui/input';
|
2026-01-18 13:46:16 +00:00
|
|
|
import { X, Key, Copy, Check, Loader2 } from 'lucide-react';
|
2026-01-18 12:54:32 +00:00
|
|
|
import { useToast } from '@/hooks/useToast';
|
2026-01-18 15:28:22 +00:00
|
|
|
import { cn } from '@/lib/utils';
|
2026-01-07 09:31:02 +00:00
|
|
|
|
|
|
|
|
interface CreateAPIKeyModalProps {
|
|
|
|
|
onClose: () => void;
|
2026-01-18 13:46:16 +00:00
|
|
|
onCreate: (keyData: { name: string; scopes: string[] }) => Promise<{ key?: string; id: string; name: string; prefix: string }>;
|
2026-01-07 09:31:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const SCOPES = [
|
2026-01-13 18:47:57 +00:00
|
|
|
{ id: 'user.read', label: 'Read User Data' },
|
|
|
|
|
{ id: 'user.write', label: 'Update User Profile' },
|
|
|
|
|
{ id: 'tracks.read', label: 'Read Tracks' },
|
|
|
|
|
{ id: 'tracks.upload', label: 'Upload Tracks' },
|
|
|
|
|
{ id: 'sales.read', label: 'Read Sales Data' },
|
2026-01-07 09:31:02 +00:00
|
|
|
];
|
|
|
|
|
|
2026-01-13 18:47:57 +00:00
|
|
|
export const CreateAPIKeyModal: React.FC<CreateAPIKeyModalProps> = ({
|
|
|
|
|
onClose,
|
|
|
|
|
onCreate,
|
|
|
|
|
}) => {
|
2026-01-18 12:54:32 +00:00
|
|
|
const toast = useToast();
|
2026-01-07 09:31:02 +00:00
|
|
|
const [step, setStep] = useState(1);
|
|
|
|
|
const [name, setName] = useState('');
|
|
|
|
|
const [selectedScopes, setSelectedScopes] = useState<string[]>(['user.read']);
|
|
|
|
|
const [generatedKey, setGeneratedKey] = useState('');
|
2026-01-18 13:46:16 +00:00
|
|
|
const [isGenerating, setIsGenerating] = useState(false);
|
2026-01-18 15:28:22 +00:00
|
|
|
const [mounted, setMounted] = useState(false);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
setMounted(true);
|
|
|
|
|
return () => setMounted(false);
|
|
|
|
|
}, []);
|
2026-01-07 09:31:02 +00:00
|
|
|
|
|
|
|
|
const toggleScope = (id: string) => {
|
2026-01-13 18:47:57 +00:00
|
|
|
setSelectedScopes((prev) =>
|
|
|
|
|
prev.includes(id) ? prev.filter((s) => s !== id) : [...prev, id],
|
|
|
|
|
);
|
2026-01-07 09:31:02 +00:00
|
|
|
};
|
|
|
|
|
|
2026-01-18 13:49:59 +00:00
|
|
|
const handleGenerate = async (e?: React.MouseEvent) => {
|
|
|
|
|
// Prevent any default behavior
|
|
|
|
|
e?.preventDefault();
|
|
|
|
|
e?.stopPropagation();
|
|
|
|
|
|
2026-01-18 13:46:16 +00:00
|
|
|
// Validate form
|
|
|
|
|
if (!name.trim()) {
|
|
|
|
|
toast.error('Please enter a name for your API key');
|
2026-01-13 18:47:57 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2026-01-18 13:46:16 +00:00
|
|
|
|
|
|
|
|
if (selectedScopes.length === 0) {
|
|
|
|
|
toast.error('Please select at least one permission scope');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setIsGenerating(true);
|
|
|
|
|
try {
|
|
|
|
|
// Call the parent's onCreate handler which makes the API call
|
|
|
|
|
const result = await onCreate({ name: name.trim(), scopes: selectedScopes });
|
2026-01-18 15:28:22 +00:00
|
|
|
|
2026-01-18 13:46:16 +00:00
|
|
|
// If the API returns a full key, use it; otherwise generate a mock for display
|
|
|
|
|
if (result.key) {
|
|
|
|
|
setGeneratedKey(result.key);
|
|
|
|
|
} else {
|
|
|
|
|
// Fallback: generate a mock key for display (in case backend doesn't return full key)
|
|
|
|
|
const mockKey = `vz_${Math.random().toString(36).substr(2, 8)}_${Math.random().toString(36).substr(2, 16)}`;
|
|
|
|
|
setGeneratedKey(mockKey);
|
|
|
|
|
}
|
2026-01-18 15:28:22 +00:00
|
|
|
|
2026-01-18 13:46:16 +00:00
|
|
|
setStep(2);
|
2026-01-18 13:49:59 +00:00
|
|
|
setIsGenerating(false);
|
2026-01-18 13:46:16 +00:00
|
|
|
} catch (error) {
|
|
|
|
|
// Error is already handled by the parent component
|
|
|
|
|
// Just reset the loading state
|
|
|
|
|
setIsGenerating(false);
|
2026-01-18 13:49:59 +00:00
|
|
|
// Re-throw to ensure error is handled
|
|
|
|
|
throw error;
|
2026-01-18 13:46:16 +00:00
|
|
|
}
|
2026-01-07 09:31:02 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const copyKey = () => {
|
2026-01-13 18:47:57 +00:00
|
|
|
navigator.clipboard.writeText(generatedKey);
|
2026-01-18 12:54:32 +00:00
|
|
|
toast.success('API Key copied to clipboard');
|
2026-01-07 09:31:02 +00:00
|
|
|
};
|
|
|
|
|
|
2026-01-18 15:28:22 +00:00
|
|
|
if (!mounted) return null;
|
|
|
|
|
|
|
|
|
|
return createPortal(
|
|
|
|
|
<div className="fixed inset-0 z-[9999] flex items-center justify-center p-4" style={{ zIndex: 9999 }}>
|
2026-01-13 18:47:57 +00:00
|
|
|
<div
|
2026-01-18 15:28:22 +00:00
|
|
|
className="absolute inset-0 bg-kodo-void/90 backdrop-blur-md"
|
2026-01-18 13:46:55 +00:00
|
|
|
onClick={step === 1 ? onClose : undefined}
|
2026-01-13 18:47:57 +00:00
|
|
|
></div>
|
ui(tokens): migrate border-kodo-steel to border-border (86 files, 269 instances)
Replace legacy hardcoded border-kodo-steel (RGB 59,69,84, theme-unaware)
with semantic border-border token across 86 user-facing components.
Covers UI primitives (checkbox, badge, modal, table, textarea, alert,
radio-group, avatar), all modals, settings views, social features,
playlist views, inventory, chat, commerce, and cloud file browser.
Only story/test files retain the legacy token.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 23:07:00 +00:00
|
|
|
<div className="relative w-full max-w-2xl bg-kodo-graphite border border-border rounded-xl shadow-2xl animate-scaleIn overflow-hidden glass-hud flex flex-col max-h-layout-modal">
|
2026-01-18 15:28:22 +00:00
|
|
|
{/* Header - Fixed */}
|
ui(tokens): migrate border-kodo-steel to border-border (86 files, 269 instances)
Replace legacy hardcoded border-kodo-steel (RGB 59,69,84, theme-unaware)
with semantic border-border token across 86 user-facing components.
Covers UI primitives (checkbox, badge, modal, table, textarea, alert,
radio-group, avatar), all modals, settings views, social features,
playlist views, inventory, chat, commerce, and cloud file browser.
Only story/test files retain the legacy token.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 23:07:00 +00:00
|
|
|
<div className="p-6 border-b border-border/50 flex justify-between items-center bg-white/5 flex-none z-10">
|
2026-01-18 15:28:22 +00:00
|
|
|
<h3 className="text-xl font-bold text-white flex items-center gap-3 font-display">
|
2026-02-08 23:20:32 +00:00
|
|
|
<div className="w-8 h-8 rounded-lg bg-warning/20 flex items-center justify-center border border-warning/30">
|
|
|
|
|
<Key className="w-5 h-5 text-warning" />
|
2026-01-18 15:28:22 +00:00
|
|
|
</div>
|
2026-01-13 18:47:57 +00:00
|
|
|
{step === 1 ? 'Create API Key' : 'API Key Generated'}
|
2026-01-07 09:31:02 +00:00
|
|
|
</h3>
|
2026-01-18 15:28:22 +00:00
|
|
|
<button onClick={onClose} className="p-2 hover:bg-white/10 rounded-lg transition-colors">
|
ui(tokens): migrate text-kodo-content-dim to text-muted-foreground (35 files, 160 instances)
Replace legacy hardcoded `text-kodo-content-dim` (Gray-400, theme-unaware)
with semantic `text-muted-foreground` across 35 user-facing components.
This ensures all secondary/muted text adapts correctly to light/dark theme
changes instead of staying fixed at a single gray value.
Covers: SearchBar, PlaylistsView, NotificationBell, TrackAnalyticsView,
LiveStreamDetailView, LicenceCard, FilePreviewCard, PasswordStrengthIndicator,
NotificationItem, TrackList, CourseCard, GroupCard, AchievementCard, XPBar,
EquipmentCard, SellerDashboardView, APIPlaygroundView, DeveloperDashboardView,
CreatorModal, AddToPlaylistModal, LicenceDetailsModal, QuizModal,
CertificateModal, FlashSaleModal, CreateAPIKeyModal, LyricsEditorModal,
WatermarkSettingsModal, ProfileXPView, LeaderboardView, PostCard,
ExploreView, FeedView, MessageSearch, TypingIndicator, PlaylistTrackItem.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 23:03:33 +00:00
|
|
|
<X className="w-5 h-5 text-muted-foreground hover:text-white" />
|
2026-01-13 18:47:57 +00:00
|
|
|
</button>
|
2026-01-07 09:31:02 +00:00
|
|
|
</div>
|
|
|
|
|
|
2026-01-18 15:28:22 +00:00
|
|
|
{/* Content - Scrollable */}
|
|
|
|
|
<div className="p-8 overflow-y-auto custom-scrollbar flex-1 relative">
|
2026-01-13 18:47:57 +00:00
|
|
|
{step === 1 ? (
|
2026-01-18 15:28:22 +00:00
|
|
|
<div className="space-y-8">
|
2026-01-18 13:46:16 +00:00
|
|
|
<div>
|
2026-02-08 23:13:27 +00:00
|
|
|
<label className="block text-xs font-bold text-muted-foreground uppercase tracking-wider mb-3">
|
2026-01-18 13:46:16 +00:00
|
|
|
Key Name
|
|
|
|
|
</label>
|
|
|
|
|
<Input
|
|
|
|
|
placeholder="e.g. Production Server, Mobile App"
|
|
|
|
|
value={name}
|
|
|
|
|
onChange={(e) => setName(e.target.value)}
|
|
|
|
|
autoFocus
|
|
|
|
|
disabled={isGenerating}
|
ui(tokens): migrate kodo-cyan to primary (51 files, 88 instances)
Replace legacy text-kodo-cyan/border-kodo-cyan/bg-kodo-cyan with semantic
text-primary/border-primary/bg-primary across 51 components.
The brand primary color now uses the design system token, enabling proper
theme adaptation. Covers UI primitives, search, dashboard, chat, playlists,
settings, social, marketplace, and auth components.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 23:19:12 +00:00
|
|
|
className="bg-kodo-void/50 border-border focus:border-primary h-12 text-lg w-full"
|
2026-01-18 13:46:16 +00:00
|
|
|
/>
|
|
|
|
|
</div>
|
2026-01-13 18:47:57 +00:00
|
|
|
|
|
|
|
|
<div>
|
2026-02-08 23:13:27 +00:00
|
|
|
<label className="block text-xs font-bold text-muted-foreground uppercase tracking-wider mb-4">
|
2026-01-13 18:47:57 +00:00
|
|
|
Permissions (Scopes)
|
|
|
|
|
</label>
|
2026-01-18 15:28:22 +00:00
|
|
|
<div className="grid grid-cols-1 gap-3">
|
2026-01-13 18:47:57 +00:00
|
|
|
{SCOPES.map((scope) => (
|
|
|
|
|
<label
|
|
|
|
|
key={scope.id}
|
2026-01-18 15:28:22 +00:00
|
|
|
className={cn(
|
feat(web): UI premium Discord/Spotify-like — tokens, shadows, focus, layout
Plan UI premium 6–8 semaines (design system, shell, Storybook, a11y):
- Design system: DESIGN_TOKENS.md, APP_SHELL.md, FULL_LAYOUT_PAGE.md. Single source
for layout/shell (index.css), shadows (design-system.css), durations/easing.
- Tokens: shadow-cover-depth, shadow-gold-glow, shadow-fab-glow; layout max-height
(max-h-layout-drawer, max-h-layout-panel, max-h-layout-list). All duration-200/300/500
replaced by --duration-fast/normal/slow. Arbitrary shadows replaced by token classes.
- Shell & player: Sidebar, Header, GlobalPlayer, MiniPlayer, PlayerQueue, PlayerControls,
AudioPlayer use tokens; focus-visible on Sidebar, PlayerQueue, DropdownMenuTrigger/Item,
TabsTrigger. Typography: text-[10px]/[9px] → text-xs where applicable.
- ESLint: no-restricted-syntax (warn) for w-/h-/rounded-/shadow-/text-/spacing arbitrary.
- Scripts: report-arbitrary-values.mjs, capture/compare/generate visual; visual-complete.spec.ts.
- Stories full layout: Dashboard, Playlists, Library, Settings, Profile in DashboardLayout.stories.
- .cursorrules + README: DESIGN_TOKENS, APP_SHELL, visual commands, no arbitrary without justification.
- apps/web/.gitignore: e2e test artifacts (test-results-visual, playwright-report-visual).
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 16:15:58 +00:00
|
|
|
"flex items-center justify-between p-4 rounded-xl border cursor-pointer transition-all duration-[var(--duration-fast)] group relative overflow-hidden",
|
2026-01-18 15:28:22 +00:00
|
|
|
selectedScopes.includes(scope.id)
|
ui(tokens): migrate kodo-cyan to primary (51 files, 88 instances)
Replace legacy text-kodo-cyan/border-kodo-cyan/bg-kodo-cyan with semantic
text-primary/border-primary/bg-primary across 51 components.
The brand primary color now uses the design system token, enabling proper
theme adaptation. Covers UI primitives, search, dashboard, chat, playlists,
settings, social, marketplace, and auth components.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 23:19:12 +00:00
|
|
|
? "bg-primary/10 border-primary/50 shadow-card-glow-cyan"
|
ui(tokens): migrate border-kodo-steel to border-border (86 files, 269 instances)
Replace legacy hardcoded border-kodo-steel (RGB 59,69,84, theme-unaware)
with semantic border-border token across 86 user-facing components.
Covers UI primitives (checkbox, badge, modal, table, textarea, alert,
radio-group, avatar), all modals, settings views, social features,
playlist views, inventory, chat, commerce, and cloud file browser.
Only story/test files retain the legacy token.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 23:07:00 +00:00
|
|
|
: "bg-kodo-void/30 border-border/50 hover:border-border hover:bg-white/5"
|
2026-01-18 15:28:22 +00:00
|
|
|
)}
|
2026-01-13 18:47:57 +00:00
|
|
|
>
|
2026-01-18 15:28:22 +00:00
|
|
|
<div className="flex items-center gap-4 z-10 relative">
|
|
|
|
|
<div className={cn(
|
|
|
|
|
"w-5 h-5 rounded border flex items-center justify-center transition-colors flex-none",
|
|
|
|
|
selectedScopes.includes(scope.id)
|
ui(tokens): migrate kodo-cyan to primary (51 files, 88 instances)
Replace legacy text-kodo-cyan/border-kodo-cyan/bg-kodo-cyan with semantic
text-primary/border-primary/bg-primary across 51 components.
The brand primary color now uses the design system token, enabling proper
theme adaptation. Covers UI primitives, search, dashboard, chat, playlists,
settings, social, marketplace, and auth components.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 23:19:12 +00:00
|
|
|
? "bg-primary border-primary"
|
ui(tokens): migrate border-kodo-steel to border-border (86 files, 269 instances)
Replace legacy hardcoded border-kodo-steel (RGB 59,69,84, theme-unaware)
with semantic border-border token across 86 user-facing components.
Covers UI primitives (checkbox, badge, modal, table, textarea, alert,
radio-group, avatar), all modals, settings views, social features,
playlist views, inventory, chat, commerce, and cloud file browser.
Only story/test files retain the legacy token.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 23:07:00 +00:00
|
|
|
: "border-border group-hover:border-kodo-content-dim"
|
2026-01-18 15:28:22 +00:00
|
|
|
)}>
|
|
|
|
|
{selectedScopes.includes(scope.id) && <Check className="w-3 h-3 text-black" />}
|
|
|
|
|
</div>
|
|
|
|
|
<span className={cn(
|
|
|
|
|
"text-sm font-medium transition-colors",
|
ui(tokens): migrate text-kodo-content-dim to text-muted-foreground (35 files, 160 instances)
Replace legacy hardcoded `text-kodo-content-dim` (Gray-400, theme-unaware)
with semantic `text-muted-foreground` across 35 user-facing components.
This ensures all secondary/muted text adapts correctly to light/dark theme
changes instead of staying fixed at a single gray value.
Covers: SearchBar, PlaylistsView, NotificationBell, TrackAnalyticsView,
LiveStreamDetailView, LicenceCard, FilePreviewCard, PasswordStrengthIndicator,
NotificationItem, TrackList, CourseCard, GroupCard, AchievementCard, XPBar,
EquipmentCard, SellerDashboardView, APIPlaygroundView, DeveloperDashboardView,
CreatorModal, AddToPlaylistModal, LicenceDetailsModal, QuizModal,
CertificateModal, FlashSaleModal, CreateAPIKeyModal, LyricsEditorModal,
WatermarkSettingsModal, ProfileXPView, LeaderboardView, PostCard,
ExploreView, FeedView, MessageSearch, TypingIndicator, PlaylistTrackItem.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 23:03:33 +00:00
|
|
|
selectedScopes.includes(scope.id) ? "text-white" : "text-muted-foreground group-hover:text-kodo-text-main"
|
2026-01-18 15:28:22 +00:00
|
|
|
)}>
|
|
|
|
|
{scope.label}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="text-xs font-mono text-kodo-steel z-10 hidden sm:block opacity-60 relative">
|
|
|
|
|
{scope.id}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Hidden actual checkbox to keep logic working but relying on our custom UI */}
|
2026-01-13 18:47:57 +00:00
|
|
|
<input
|
|
|
|
|
type="checkbox"
|
2026-01-18 15:28:22 +00:00
|
|
|
className="hidden"
|
2026-01-13 18:47:57 +00:00
|
|
|
checked={selectedScopes.includes(scope.id)}
|
|
|
|
|
onChange={() => toggleScope(scope.id)}
|
|
|
|
|
/>
|
|
|
|
|
</label>
|
|
|
|
|
))}
|
2026-01-07 09:31:02 +00:00
|
|
|
</div>
|
2026-01-13 18:47:57 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
) : (
|
2026-01-18 15:28:22 +00:00
|
|
|
<div className="text-center space-y-8 py-4">
|
|
|
|
|
<div className="relative w-20 h-20 mx-auto">
|
|
|
|
|
<div className="absolute inset-0 bg-kodo-lime/20 rounded-full animate-ping opacity-50"></div>
|
feat(web): UI premium Discord/Spotify-like — tokens, shadows, focus, layout
Plan UI premium 6–8 semaines (design system, shell, Storybook, a11y):
- Design system: DESIGN_TOKENS.md, APP_SHELL.md, FULL_LAYOUT_PAGE.md. Single source
for layout/shell (index.css), shadows (design-system.css), durations/easing.
- Tokens: shadow-cover-depth, shadow-gold-glow, shadow-fab-glow; layout max-height
(max-h-layout-drawer, max-h-layout-panel, max-h-layout-list). All duration-200/300/500
replaced by --duration-fast/normal/slow. Arbitrary shadows replaced by token classes.
- Shell & player: Sidebar, Header, GlobalPlayer, MiniPlayer, PlayerQueue, PlayerControls,
AudioPlayer use tokens; focus-visible on Sidebar, PlayerQueue, DropdownMenuTrigger/Item,
TabsTrigger. Typography: text-[10px]/[9px] → text-xs where applicable.
- ESLint: no-restricted-syntax (warn) for w-/h-/rounded-/shadow-/text-/spacing arbitrary.
- Scripts: report-arbitrary-values.mjs, capture/compare/generate visual; visual-complete.spec.ts.
- Stories full layout: Dashboard, Playlists, Library, Settings, Profile in DashboardLayout.stories.
- .cursorrules + README: DESIGN_TOKENS, APP_SHELL, visual commands, no arbitrary without justification.
- apps/web/.gitignore: e2e test artifacts (test-results-visual, playwright-report-visual).
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 16:15:58 +00:00
|
|
|
<div className="relative w-full h-full bg-gradient-to-br from-kodo-lime/20 to-kodo-cyan/20 rounded-full flex items-center justify-center border border-kodo-lime/30 shadow-card-glow-cyan">
|
2026-02-08 23:14:40 +00:00
|
|
|
<Check className="w-10 h-10 text-success drop-shadow-lg" />
|
2026-01-18 15:28:22 +00:00
|
|
|
</div>
|
2026-01-13 18:47:57 +00:00
|
|
|
</div>
|
2026-01-18 15:28:22 +00:00
|
|
|
|
|
|
|
|
<div className="space-y-2">
|
|
|
|
|
<h4 className="text-2xl font-bold text-white font-display">
|
2026-01-13 18:47:57 +00:00
|
|
|
Key Created Successfully
|
|
|
|
|
</h4>
|
ui(tokens): migrate text-kodo-content-dim to text-muted-foreground (35 files, 160 instances)
Replace legacy hardcoded `text-kodo-content-dim` (Gray-400, theme-unaware)
with semantic `text-muted-foreground` across 35 user-facing components.
This ensures all secondary/muted text adapts correctly to light/dark theme
changes instead of staying fixed at a single gray value.
Covers: SearchBar, PlaylistsView, NotificationBell, TrackAnalyticsView,
LiveStreamDetailView, LicenceCard, FilePreviewCard, PasswordStrengthIndicator,
NotificationItem, TrackList, CourseCard, GroupCard, AchievementCard, XPBar,
EquipmentCard, SellerDashboardView, APIPlaygroundView, DeveloperDashboardView,
CreatorModal, AddToPlaylistModal, LicenceDetailsModal, QuizModal,
CertificateModal, FlashSaleModal, CreateAPIKeyModal, LyricsEditorModal,
WatermarkSettingsModal, ProfileXPView, LeaderboardView, PostCard,
ExploreView, FeedView, MessageSearch, TypingIndicator, PlaylistTrackItem.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 23:03:33 +00:00
|
|
|
<p className="text-sm text-muted-foreground max-w-xs mx-auto leading-relaxed">
|
2026-01-18 15:28:22 +00:00
|
|
|
Please copy your API key now. For security reasons, it cannot be displayed again properly.
|
2026-01-13 18:47:57 +00:00
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
ui(tokens): migrate border-kodo-steel to border-border (86 files, 269 instances)
Replace legacy hardcoded border-kodo-steel (RGB 59,69,84, theme-unaware)
with semantic border-border token across 86 user-facing components.
Covers UI primitives (checkbox, badge, modal, table, textarea, alert,
radio-group, avatar), all modals, settings views, social features,
playlist views, inventory, chat, commerce, and cloud file browser.
Only story/test files retain the legacy token.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 23:07:00 +00:00
|
|
|
<div className="bg-black/40 border border-border/50 rounded-xl p-1 flex items-center gap-2 relative group overflow-hidden">
|
2026-01-18 15:28:22 +00:00
|
|
|
<div className="absolute inset-0 bg-gradient-to-r from-transparent via-white/5 to-transparent skew-x-12 translate-x-[-200%] group-hover:animate-shimmer"></div>
|
2026-02-08 23:20:32 +00:00
|
|
|
<div className="flex-1 px-4 py-3 font-mono text-sm text-warning overflow-x-auto no-scrollbar whitespace-nowrap text-left">
|
2026-01-13 18:47:57 +00:00
|
|
|
{generatedKey}
|
2026-01-18 15:28:22 +00:00
|
|
|
</div>
|
2026-01-13 18:47:57 +00:00
|
|
|
<Button
|
|
|
|
|
variant="ghost"
|
|
|
|
|
size="icon"
|
|
|
|
|
onClick={copyKey}
|
ui(tokens): migrate text-kodo-content-dim to text-muted-foreground (35 files, 160 instances)
Replace legacy hardcoded `text-kodo-content-dim` (Gray-400, theme-unaware)
with semantic `text-muted-foreground` across 35 user-facing components.
This ensures all secondary/muted text adapts correctly to light/dark theme
changes instead of staying fixed at a single gray value.
Covers: SearchBar, PlaylistsView, NotificationBell, TrackAnalyticsView,
LiveStreamDetailView, LicenceCard, FilePreviewCard, PasswordStrengthIndicator,
NotificationItem, TrackList, CourseCard, GroupCard, AchievementCard, XPBar,
EquipmentCard, SellerDashboardView, APIPlaygroundView, DeveloperDashboardView,
CreatorModal, AddToPlaylistModal, LicenceDetailsModal, QuizModal,
CertificateModal, FlashSaleModal, CreateAPIKeyModal, LyricsEditorModal,
WatermarkSettingsModal, ProfileXPView, LeaderboardView, PostCard,
ExploreView, FeedView, MessageSearch, TypingIndicator, PlaylistTrackItem.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 23:03:33 +00:00
|
|
|
className="h-10 w-10 text-muted-foreground hover:text-white hover:bg-white/10 rounded-lg hover:scale-105 transition-all flex-none"
|
2026-01-18 15:28:22 +00:00
|
|
|
title="Copy to clipboard"
|
2026-01-13 18:47:57 +00:00
|
|
|
>
|
2026-01-18 15:28:22 +00:00
|
|
|
<Copy className="w-5 h-5" />
|
2026-01-13 18:47:57 +00:00
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
2026-01-07 09:31:02 +00:00
|
|
|
</div>
|
|
|
|
|
|
2026-01-18 15:28:22 +00:00
|
|
|
{/* Footer - Fixed */}
|
ui(tokens): migrate border-kodo-steel to border-border (86 files, 269 instances)
Replace legacy hardcoded border-kodo-steel (RGB 59,69,84, theme-unaware)
with semantic border-border token across 86 user-facing components.
Covers UI primitives (checkbox, badge, modal, table, textarea, alert,
radio-group, avatar), all modals, settings views, social features,
playlist views, inventory, chat, commerce, and cloud file browser.
Only story/test files retain the legacy token.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 23:07:00 +00:00
|
|
|
<div className="p-6 border-t border-border/50 bg-white/5 flex justify-end gap-3 backdrop-blur-sm flex-none z-10 transition-colors">
|
2026-01-13 18:47:57 +00:00
|
|
|
{step === 1 ? (
|
|
|
|
|
<>
|
2026-01-18 15:28:22 +00:00
|
|
|
<Button
|
|
|
|
|
variant="ghost"
|
2026-01-18 13:46:16 +00:00
|
|
|
onClick={onClose}
|
|
|
|
|
disabled={isGenerating}
|
ui(tokens): migrate text-kodo-content-dim to text-muted-foreground (35 files, 160 instances)
Replace legacy hardcoded `text-kodo-content-dim` (Gray-400, theme-unaware)
with semantic `text-muted-foreground` across 35 user-facing components.
This ensures all secondary/muted text adapts correctly to light/dark theme
changes instead of staying fixed at a single gray value.
Covers: SearchBar, PlaylistsView, NotificationBell, TrackAnalyticsView,
LiveStreamDetailView, LicenceCard, FilePreviewCard, PasswordStrengthIndicator,
NotificationItem, TrackList, CourseCard, GroupCard, AchievementCard, XPBar,
EquipmentCard, SellerDashboardView, APIPlaygroundView, DeveloperDashboardView,
CreatorModal, AddToPlaylistModal, LicenceDetailsModal, QuizModal,
CertificateModal, FlashSaleModal, CreateAPIKeyModal, LyricsEditorModal,
WatermarkSettingsModal, ProfileXPView, LeaderboardView, PostCard,
ExploreView, FeedView, MessageSearch, TypingIndicator, PlaylistTrackItem.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 23:03:33 +00:00
|
|
|
className="hover:bg-white/10 text-muted-foreground hover:text-white"
|
2026-01-18 13:46:16 +00:00
|
|
|
>
|
2026-01-13 18:47:57 +00:00
|
|
|
Cancel
|
|
|
|
|
</Button>
|
2026-01-18 15:28:22 +00:00
|
|
|
<Button
|
|
|
|
|
variant="default"
|
2026-01-18 13:49:59 +00:00
|
|
|
onClick={(e) => {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
handleGenerate(e);
|
|
|
|
|
}}
|
2026-01-18 13:46:16 +00:00
|
|
|
disabled={isGenerating || !name.trim() || selectedScopes.length === 0}
|
2026-01-18 13:49:59 +00:00
|
|
|
type="button"
|
ui(tokens): migrate kodo-cyan to primary (51 files, 88 instances)
Replace legacy text-kodo-cyan/border-kodo-cyan/bg-kodo-cyan with semantic
text-primary/border-primary/bg-primary across 51 components.
The brand primary color now uses the design system token, enabling proper
theme adaptation. Covers UI primitives, search, dashboard, chat, playlists,
settings, social, marketplace, and auth components.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 23:19:12 +00:00
|
|
|
className="bg-primary hover:bg-primary/80 text-black font-semibold shadow-button-primary-glow hover:shadow-button-primary-glow-hover transition-all duration-[var(--duration-normal)]"
|
2026-01-18 13:46:16 +00:00
|
|
|
>
|
|
|
|
|
{isGenerating ? (
|
|
|
|
|
<>
|
|
|
|
|
<Loader2 className="w-4 h-4 mr-2 animate-spin" />
|
|
|
|
|
Generating...
|
|
|
|
|
</>
|
|
|
|
|
) : (
|
|
|
|
|
'Generate Key'
|
|
|
|
|
)}
|
2026-01-13 18:47:57 +00:00
|
|
|
</Button>
|
|
|
|
|
</>
|
|
|
|
|
) : (
|
2026-01-18 15:28:22 +00:00
|
|
|
<Button
|
|
|
|
|
onClick={onClose}
|
ui(tokens): migrate kodo-cyan to primary (51 files, 88 instances)
Replace legacy text-kodo-cyan/border-kodo-cyan/bg-kodo-cyan with semantic
text-primary/border-primary/bg-primary across 51 components.
The brand primary color now uses the design system token, enabling proper
theme adaptation. Covers UI primitives, search, dashboard, chat, playlists,
settings, social, marketplace, and auth components.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 23:19:12 +00:00
|
|
|
className="bg-primary hover:bg-primary/80 text-black font-semibold min-w-24 shadow-button-primary-glow hover:shadow-button-primary-glow-hover transition-all duration-[var(--duration-normal)]"
|
2026-01-18 15:28:22 +00:00
|
|
|
>
|
2026-01-13 18:47:57 +00:00
|
|
|
Done
|
|
|
|
|
</Button>
|
|
|
|
|
)}
|
2026-01-07 09:31:02 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-01-18 15:28:22 +00:00
|
|
|
</div>,
|
|
|
|
|
document.body
|
2026-01-07 09:31:02 +00:00
|
|
|
);
|
|
|
|
|
};
|