consistency: fix remaining Tailwind default colors in auth and features components
This commit is contained in:
parent
00f5712230
commit
de79895e5d
82 changed files with 462 additions and 667 deletions
|
|
@ -1,7 +1,7 @@
|
|||
# Complete List of Remaining Tailwind Default Color Instances
|
||||
**Generated**: Automatically generated list
|
||||
**Total Files**: 17
|
||||
**Total Instances**: 31
|
||||
**Total Files**: 3
|
||||
**Total Instances**: 4
|
||||
**Status**: Action 9.1.1.3 - In Progress (294 instances migrated, ~19.7% complete)
|
||||
|
||||
## Usage
|
||||
|
|
@ -34,211 +34,6 @@ Refer to `TAILWIND_COLORS_AUDIT.md` for color mapping:
|
|||
|
||||
---
|
||||
|
||||
### apps/web/src/features/auth/components/EmailVerificationBadge.tsx
|
||||
**Total instances in file**: 2
|
||||
|
||||
- **Line 14**: `text-green-`, `bg-green-`, `text-green-`
|
||||
```tsx
|
||||
<span className="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-kodo-lime/20 text-green-800 dark:bg-green-900 dark:text-green-200">
|
||||
```
|
||||
|
||||
- **Line 21**: `bg-yellow-`, `text-yellow-`, `bg-yellow-`, `text-yellow-`
|
||||
```tsx
|
||||
<span className="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200">
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### apps/web/src/features/auth/components/PasswordStrengthIndicator.tsx
|
||||
**Total instances in file**: 3
|
||||
|
||||
- **Line 55**: `bg-orange-`
|
||||
```tsx
|
||||
color = 'bg-orange-500';
|
||||
```
|
||||
|
||||
- **Line 58**: `bg-yellow-`
|
||||
```tsx
|
||||
color = 'bg-yellow-500';
|
||||
```
|
||||
|
||||
- **Line 64**: `bg-green-`
|
||||
```tsx
|
||||
color = 'bg-green-600';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### apps/web/src/features/auth/pages/ForgotPasswordPage.tsx
|
||||
**Total instances in file**: 1
|
||||
|
||||
- **Line 102**: `bg-red-`
|
||||
```tsx
|
||||
className="bg-red-50 border border-kodo-red text-kodo-red px-4 py-3 rounded"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### apps/web/src/features/auth/pages/LoginPage.tsx
|
||||
**Total instances in file**: 1
|
||||
|
||||
- **Line 224**: `bg-red-`
|
||||
```tsx
|
||||
className="bg-red-50 border border-kodo-red text-kodo-red px-4 py-3 rounded"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### apps/web/src/features/auth/pages/RegisterPage.tsx
|
||||
**Total instances in file**: 1
|
||||
|
||||
- **Line 215**: `bg-red-`
|
||||
```tsx
|
||||
className="bg-red-50 border border-kodo-red text-kodo-red px-4 py-3 rounded"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### apps/web/src/features/auth/pages/ResetPasswordPage.tsx
|
||||
**Total instances in file**: 1
|
||||
|
||||
- **Line 124**: `bg-red-`
|
||||
```tsx
|
||||
<div className="bg-red-50 border border-kodo-red text-kodo-red px-4 py-3 rounded">
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### apps/web/src/features/auth/pages/VerifyEmailPage.tsx
|
||||
**Total instances in file**: 1
|
||||
|
||||
- **Line 196**: `bg-red-`
|
||||
```tsx
|
||||
className="bg-red-50 border border-kodo-red text-kodo-red px-4 py-3 rounded"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### apps/web/src/features/dashboard/pages/DashboardPage.tsx
|
||||
**Total instances in file**: 3
|
||||
|
||||
- **Line 56**: `text-purple-`
|
||||
```tsx
|
||||
color: 'text-purple-600',
|
||||
```
|
||||
|
||||
- **Line 114**: `bg-green-`
|
||||
```tsx
|
||||
<div className="w-2 h-2 bg-green-600 rounded-full"></div>
|
||||
```
|
||||
|
||||
- **Line 123**: `bg-purple-`
|
||||
```tsx
|
||||
<div className="w-2 h-2 bg-purple-600 rounded-full"></div>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### apps/web/src/features/error/pages/ServerErrorPage.tsx
|
||||
**Total instances in file**: 2
|
||||
|
||||
- **Line 44**: `bg-red-`, `bg-red-`
|
||||
```tsx
|
||||
<div className="mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-red-100 dark:bg-red-900">
|
||||
```
|
||||
|
||||
- **Line 63**: `border-blue-`
|
||||
```tsx
|
||||
<div className="bg-kodo-cyan/10 dark:bg-kodo-cyan/20 border border-kodo-cyan dark:border-blue-800 rounded-lg p-4">
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### apps/web/src/features/playlists/components/PlaylistBatchActions.tsx
|
||||
**Total instances in file**: 1
|
||||
|
||||
- **Line 200**: `border-blue-`
|
||||
```tsx
|
||||
'p-4 bg-kodo-cyan/10 dark:bg-kodo-cyan/20 border border-kodo-cyan dark:border-blue-800 rounded-lg',
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### apps/web/src/features/streaming/components/PlaybackSummary.tsx
|
||||
**Total instances in file**: 1
|
||||
|
||||
- **Line 181**: `text-purple-`
|
||||
```tsx
|
||||
<CheckCircle2 className="h-4 w-4 text-purple-600" />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### apps/web/src/features/tracks/components/TrackHistory.tsx
|
||||
**Total instances in file**: 3
|
||||
|
||||
- **Line 129**: `bg-red-`
|
||||
```tsx
|
||||
return 'text-kodo-red bg-red-50';
|
||||
```
|
||||
|
||||
- **Line 131**: `text-purple-`, `bg-purple-`
|
||||
```tsx
|
||||
return 'text-purple-600 bg-purple-50';
|
||||
```
|
||||
|
||||
- **Line 133**: `text-orange-`, `bg-orange-`
|
||||
```tsx
|
||||
return 'text-orange-600 bg-orange-50';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### apps/web/src/features/tracks/components/TrackListEmpty.tsx
|
||||
**Total instances in file**: 2
|
||||
|
||||
- **Line 106**: `text-red-`, `text-red-`
|
||||
```tsx
|
||||
? 'text-red-900 dark:text-red-100'
|
||||
```
|
||||
|
||||
- **Line 117**: `text-red-`
|
||||
```tsx
|
||||
? 'text-kodo-red dark:text-red-300'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### apps/web/src/features/tracks/components/UploadQuota.tsx
|
||||
**Total instances in file**: 5
|
||||
|
||||
- **Line 132**: `text-yellow-`
|
||||
```tsx
|
||||
isQuotaNearLimit && !isQuotaExceeded && 'text-yellow-600',
|
||||
```
|
||||
|
||||
- **Line 142**: `bg-yellow-`
|
||||
```tsx
|
||||
isQuotaNearLimit && !isQuotaExceeded && '[&>div]:bg-yellow-500',
|
||||
```
|
||||
|
||||
- **Line 163**: `text-yellow-`
|
||||
```tsx
|
||||
isQuotaNearLimit && !isQuotaExceeded && 'text-yellow-600',
|
||||
```
|
||||
|
||||
- **Line 174**: `bg-yellow-`
|
||||
```tsx
|
||||
isQuotaNearLimit && !isQuotaExceeded && '[&>div]:bg-yellow-500',
|
||||
```
|
||||
|
||||
- **Line 186**: `bg-yellow-`, `bg-yellow-`, `text-yellow-`, `text-yellow-`
|
||||
```tsx
|
||||
<div className="flex items-start gap-2 p-2 bg-yellow-50 dark:bg-yellow-900/20 rounded-md text-xs text-yellow-800 dark:text-yellow-200">
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### apps/web/src/features/upload/components/UploadModal.tsx
|
||||
**Total instances in file**: 1
|
||||
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ export class ErrorBoundary extends Component<Props, State> {
|
|||
|
||||
// Action 3.3.1.3: Use ErrorDisplay component for consistent error presentation
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center bg-gray-50 dark:bg-gray-900 p-4">
|
||||
<div className="min-h-screen flex items-center justify-center bg-kodo-void dark:bg-kodo-ink p-4">
|
||||
<div className="w-full max-w-md">
|
||||
<ErrorDisplay
|
||||
error={
|
||||
|
|
|
|||
|
|
@ -106,11 +106,11 @@ export const AdminDashboardView: React.FC = () => {
|
|||
<div className="flex justify-between items-center mb-6">
|
||||
<h3 className="font-bold text-white">Traffic & Server Load</h3>
|
||||
<div className="flex gap-2">
|
||||
<span className="text-xs text-gray-400 flex items-center gap-1">
|
||||
<span className="text-xs text-kodo-content-dim flex items-center gap-1">
|
||||
<div className="w-2 h-2 bg-kodo-cyan rounded-full"></div>{' '}
|
||||
Traffic
|
||||
</span>
|
||||
<span className="text-xs text-gray-400 flex items-center gap-1">
|
||||
<span className="text-xs text-kodo-content-dim flex items-center gap-1">
|
||||
<div className="w-2 h-2 bg-kodo-magenta rounded-full"></div> CPU
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -178,15 +178,15 @@ export const AdminDashboardView: React.FC = () => {
|
|||
</h3>
|
||||
<div className="space-y-3">
|
||||
<div className="flex justify-between text-sm">
|
||||
<span className="text-gray-400">Database</span>
|
||||
<span className="text-kodo-content-dim">Database</span>
|
||||
<span className="text-kodo-lime font-bold">Healthy</span>
|
||||
</div>
|
||||
<div className="flex justify-between text-sm">
|
||||
<span className="text-gray-400">Storage</span>
|
||||
<span className="text-kodo-content-dim">Storage</span>
|
||||
<span className="text-kodo-lime font-bold">65% Used</span>
|
||||
</div>
|
||||
<div className="flex justify-between text-sm">
|
||||
<span className="text-gray-400">API Latency</span>
|
||||
<span className="text-kodo-content-dim">API Latency</span>
|
||||
<span className="text-white font-mono">45ms</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -215,7 +215,7 @@ export const AdminDashboardView: React.FC = () => {
|
|||
<div className="text-sm font-bold text-white">
|
||||
{report.targetName}
|
||||
</div>
|
||||
<div className="text-xs text-gray-400">
|
||||
<div className="text-xs text-kodo-content-dim">
|
||||
{report.targetType} • {report.reason}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -240,7 +240,7 @@ export const AdminDashboardView: React.FC = () => {
|
|||
</div>
|
||||
))}
|
||||
{reports.length === 0 && (
|
||||
<div className="text-center text-gray-500 py-4">
|
||||
<div className="text-center text-kodo-content-dim py-4">
|
||||
No pending reports.
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -267,7 +267,7 @@ export const AdminDashboardView: React.FC = () => {
|
|||
<div className="text-sm font-bold text-white">
|
||||
{upload.name}
|
||||
</div>
|
||||
<div className="text-xs text-gray-400">
|
||||
<div className="text-xs text-kodo-content-dim">
|
||||
{upload.user} • {upload.size}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ export const AdminModerationView: React.FC = () => {
|
|||
<button
|
||||
key={tab}
|
||||
onClick={() => setActiveTab(tab as any)}
|
||||
className={`pb-3 text-sm font-bold uppercase tracking-wider border-b-2 transition-colors ${activeTab === tab ? 'border-kodo-red text-white' : 'border-transparent text-gray-500 hover:text-gray-300'}`}
|
||||
className={`pb-3 text-sm font-bold uppercase tracking-wider border-b-2 transition-colors ${activeTab === tab ? 'border-kodo-red text-white' : 'border-transparent text-kodo-content-dim hover:text-kodo-text-main'}`}
|
||||
>
|
||||
{tab} (
|
||||
{
|
||||
|
|
@ -104,7 +104,7 @@ export const AdminModerationView: React.FC = () => {
|
|||
)}
|
||||
|
||||
{!loading && filteredQueue.length === 0 && (
|
||||
<div className="text-center py-20 text-gray-500">
|
||||
<div className="text-center py-20 text-kodo-content-dim">
|
||||
<ShieldAlert className="w-12 h-12 mx-auto mb-4 opacity-30" />
|
||||
<p>All caught up! No reports in this queue.</p>
|
||||
</div>
|
||||
|
|
@ -124,7 +124,7 @@ export const AdminModerationView: React.FC = () => {
|
|||
<span className="font-bold text-white text-lg">
|
||||
{report.targetName}
|
||||
</span>
|
||||
<span className="text-xs text-gray-500 font-mono flex items-center gap-1">
|
||||
<span className="text-xs text-kodo-content-dim font-mono flex items-center gap-1">
|
||||
<Clock className="w-3 h-3" /> {report.timestamp}
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -132,11 +132,11 @@ export const AdminModerationView: React.FC = () => {
|
|||
<div className="text-xs font-bold text-kodo-red uppercase mb-1">
|
||||
Reason: {report.reason}
|
||||
</div>
|
||||
<p className="text-sm text-gray-300">
|
||||
<p className="text-sm text-kodo-text-main">
|
||||
{report.description}
|
||||
</p>
|
||||
</div>
|
||||
<div className="text-xs text-gray-500">
|
||||
<div className="text-xs text-kodo-content-dim">
|
||||
Reported by:{' '}
|
||||
<span className="text-white">{report.reportedBy}</span>
|
||||
</div>
|
||||
|
|
@ -146,7 +146,7 @@ export const AdminModerationView: React.FC = () => {
|
|||
<Button
|
||||
variant="primary"
|
||||
size="sm"
|
||||
className="bg-red-600 hover:bg-red-700 border-red-500 text-white"
|
||||
className="bg-kodo-red hover:bg-kodo-red border-kodo-red text-white"
|
||||
icon={<Ban className="w-4 h-4" />}
|
||||
onClick={() => handleAction(report.id, 'banned')}
|
||||
>
|
||||
|
|
@ -171,7 +171,7 @@ export const AdminModerationView: React.FC = () => {
|
|||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="text-gray-500 hover:text-white"
|
||||
className="text-kodo-content-dim hover:text-white"
|
||||
onClick={() => handleAction(report.id, 'dismissed')}
|
||||
>
|
||||
Dismiss
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ export const AdminSettingsView: React.FC = () => {
|
|||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<label className="block text-sm font-bold text-gray-400 mb-2">
|
||||
<label className="block text-sm font-bold text-kodo-content-dim mb-2">
|
||||
Upload Limit (MB)
|
||||
</label>
|
||||
<input
|
||||
|
|
@ -46,12 +46,12 @@ export const AdminSettingsView: React.FC = () => {
|
|||
value={uploadLimit}
|
||||
onChange={(e) => setUploadLimit(Number(e.target.value))}
|
||||
/>
|
||||
<p className="text-xs text-gray-500 mt-1">
|
||||
<p className="text-xs text-kodo-content-dim mt-1">
|
||||
Maximum file size for standard users.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-bold text-gray-400 mb-2">
|
||||
<label className="block text-sm font-bold text-kodo-content-dim mb-2">
|
||||
Default Storage Region
|
||||
</label>
|
||||
<select className="w-full bg-kodo-ink border border-kodo-steel rounded p-2 text-white outline-none focus:border-kodo-cyan">
|
||||
|
|
@ -99,13 +99,13 @@ export const AdminSettingsView: React.FC = () => {
|
|||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<div className="text-white font-bold">Maintenance Mode</div>
|
||||
<div className="text-xs text-gray-400">
|
||||
<div className="text-xs text-kodo-content-dim">
|
||||
Disable access for non-admin users
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
onClick={() => setMaintenance(!maintenance)}
|
||||
className={`w-12 h-6 rounded-full relative cursor-pointer transition-colors ${maintenance ? 'bg-kodo-red' : 'bg-gray-600'}`}
|
||||
className={`w-12 h-6 rounded-full relative cursor-pointer transition-colors ${maintenance ? 'bg-kodo-red' : 'bg-kodo-steel'}`}
|
||||
>
|
||||
<div
|
||||
className={`absolute top-1 w-4 h-4 bg-white rounded-full transition-all ${maintenance ? 'left-7' : 'left-1'}`}
|
||||
|
|
@ -114,7 +114,7 @@ export const AdminSettingsView: React.FC = () => {
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-bold text-gray-400 mb-2">
|
||||
<label className="block text-sm font-bold text-kodo-content-dim mb-2">
|
||||
Global Announcement
|
||||
</label>
|
||||
<textarea
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ export const AdminUsersView: React.FC = () => {
|
|||
<h2 className="text-2xl font-display font-bold text-white mb-2">
|
||||
USER MANAGEMENT
|
||||
</h2>
|
||||
<p className="text-gray-400 font-mono text-sm">
|
||||
<p className="text-kodo-content-dim font-mono text-sm">
|
||||
Manage accounts, roles, and permissions.
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -127,7 +127,7 @@ export const AdminUsersView: React.FC = () => {
|
|||
<div className="overflow-x-auto">
|
||||
<table className="w-full text-left border-collapse">
|
||||
<thead>
|
||||
<tr className="border-b border-kodo-steel bg-kodo-graphite text-xs font-bold text-gray-500 uppercase tracking-wider">
|
||||
<tr className="border-b border-kodo-steel bg-kodo-graphite text-xs font-bold text-kodo-content-dim uppercase tracking-wider">
|
||||
<th className="p-4">User</th>
|
||||
<th className="p-4">Email</th>
|
||||
<th className="p-4">Roles</th>
|
||||
|
|
@ -151,7 +151,7 @@ export const AdminUsersView: React.FC = () => {
|
|||
))}
|
||||
{filteredUsers.length === 0 && (
|
||||
<tr>
|
||||
<td colSpan={7} className="p-8 text-center text-gray-500">
|
||||
<td colSpan={7} className="p-8 text-center text-kodo-content-dim">
|
||||
No users found.
|
||||
</td>
|
||||
</tr>
|
||||
|
|
@ -161,7 +161,7 @@ export const AdminUsersView: React.FC = () => {
|
|||
</div>
|
||||
)}
|
||||
|
||||
<div className="p-4 border-t border-kodo-steel bg-kodo-ink/30 text-xs text-gray-500 flex justify-between items-center">
|
||||
<div className="p-4 border-t border-kodo-steel bg-kodo-ink/30 text-xs text-kodo-content-dim flex justify-between items-center">
|
||||
<span>
|
||||
Showing {filteredUsers.length} of {users.length} users
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ export const UserTableRow: React.FC<UserTableRowProps> = ({
|
|||
|
||||
const statusColor: Record<string, string> = {
|
||||
online: 'bg-kodo-lime',
|
||||
offline: 'bg-gray-500',
|
||||
offline: 'bg-kodo-steel',
|
||||
away: 'bg-kodo-gold',
|
||||
idle: 'bg-kodo-gold',
|
||||
busy: 'bg-kodo-red',
|
||||
|
|
@ -42,11 +42,11 @@ export const UserTableRow: React.FC<UserTableRowProps> = ({
|
|||
</div>
|
||||
<div>
|
||||
<div className="font-bold text-white text-sm">{user.username}</div>
|
||||
<div className="text-xs text-gray-500 font-mono">{user.id}</div>
|
||||
<div className="text-xs text-kodo-content-dim font-mono">{user.id}</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="p-4 text-sm text-gray-400">{user.email}</td>
|
||||
<td className="p-4 text-sm text-kodo-content-dim">{user.email}</td>
|
||||
<td className="p-4">
|
||||
<div className="flex gap-1">
|
||||
{(user.roles || [user.role]).map((role: string) => (
|
||||
|
|
@ -61,17 +61,17 @@ export const UserTableRow: React.FC<UserTableRowProps> = ({
|
|||
))}
|
||||
</div>
|
||||
</td>
|
||||
<td className="p-4 text-sm text-gray-400">{user.tier || 'Free'}</td>
|
||||
<td className="p-4 text-sm text-gray-400 font-mono">
|
||||
<td className="p-4 text-sm text-kodo-content-dim">{user.tier || 'Free'}</td>
|
||||
<td className="p-4 text-sm text-kodo-content-dim font-mono">
|
||||
{user.joinDate || user.created_at}
|
||||
</td>
|
||||
<td className="p-4 text-sm text-gray-400 font-mono">
|
||||
<td className="p-4 text-sm text-kodo-content-dim font-mono">
|
||||
{user.lastLogin || user.last_login_at || 'Never'}
|
||||
</td>
|
||||
<td className="p-4 text-right">
|
||||
<div className="relative">
|
||||
<button
|
||||
className="p-1.5 hover:bg-white/10 rounded text-gray-400 hover:text-white"
|
||||
className="p-1.5 hover:bg-white/10 rounded text-kodo-content-dim hover:text-white"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setShowMenu(!showMenu);
|
||||
|
|
@ -88,7 +88,7 @@ export const UserTableRow: React.FC<UserTableRowProps> = ({
|
|||
></div>
|
||||
<div className="absolute right-0 top-full mt-2 w-48 bg-kodo-graphite border border-kodo-steel rounded-lg shadow-xl z-20 overflow-hidden">
|
||||
<button
|
||||
className="w-full text-left px-4 py-2.5 text-xs text-gray-300 hover:bg-white/10 flex items-center gap-2"
|
||||
className="w-full text-left px-4 py-2.5 text-xs text-kodo-text-main hover:bg-white/10 flex items-center gap-2"
|
||||
onClick={() => {
|
||||
onEditRole(user);
|
||||
setShowMenu(false);
|
||||
|
|
@ -96,7 +96,7 @@ export const UserTableRow: React.FC<UserTableRowProps> = ({
|
|||
>
|
||||
<Shield className="w-3 h-3" /> Change Role
|
||||
</button>
|
||||
<button className="w-full text-left px-4 py-2.5 text-xs text-gray-300 hover:bg-white/10 flex items-center gap-2">
|
||||
<button className="w-full text-left px-4 py-2.5 text-xs text-kodo-text-main hover:bg-white/10 flex items-center gap-2">
|
||||
<Mail className="w-3 h-3" /> Send Email
|
||||
</button>
|
||||
<div className="h-px bg-kodo-steel/50 my-1"></div>
|
||||
|
|
|
|||
|
|
@ -30,19 +30,19 @@ export const BanUserModal: React.FC<BanUserModalProps> = ({
|
|||
<ShieldBan className="w-5 h-5 fill-current" /> Suspend User
|
||||
</h3>
|
||||
<button onClick={onClose}>
|
||||
<X className="w-5 h-5 text-gray-400 hover:text-white" />
|
||||
<X className="w-5 h-5 text-kodo-content-dim hover:text-white" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="p-6 space-y-4">
|
||||
<p className="text-gray-300 text-sm">
|
||||
<p className="text-kodo-text-main text-sm">
|
||||
You are about to suspend{' '}
|
||||
<span className="font-bold text-white">{username}</span>. This will
|
||||
restrict their access to the platform.
|
||||
</p>
|
||||
|
||||
<div>
|
||||
<label className="block text-xs font-bold text-gray-400 uppercase mb-2">
|
||||
<label className="block text-xs font-bold text-kodo-content-dim uppercase mb-2">
|
||||
Reason
|
||||
</label>
|
||||
<select
|
||||
|
|
@ -60,7 +60,7 @@ export const BanUserModal: React.FC<BanUserModalProps> = ({
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-xs font-bold text-gray-400 uppercase mb-2">
|
||||
<label className="block text-xs font-bold text-kodo-content-dim uppercase mb-2">
|
||||
Details (Internal Note)
|
||||
</label>
|
||||
<textarea
|
||||
|
|
@ -73,30 +73,30 @@ export const BanUserModal: React.FC<BanUserModalProps> = ({
|
|||
|
||||
<div className="flex items-center justify-between p-3 bg-kodo-ink rounded border border-kodo-steel">
|
||||
<div className="flex items-center gap-3">
|
||||
<Calendar className="w-5 h-5 text-gray-400" />
|
||||
<Calendar className="w-5 h-5 text-kodo-content-dim" />
|
||||
<div>
|
||||
<div className="text-sm font-bold text-white">Ban Duration</div>
|
||||
<div className="text-xs text-gray-400">
|
||||
<div className="text-xs text-kodo-content-dim">
|
||||
{isPermanent ? 'Permanent Ban' : `${duration} Days`}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span
|
||||
className={`text-xs ${!isPermanent ? 'text-white' : 'text-gray-500'}`}
|
||||
className={`text-xs ${!isPermanent ? 'text-white' : 'text-kodo-content-dim'}`}
|
||||
>
|
||||
Temp
|
||||
</span>
|
||||
<div
|
||||
onClick={() => setIsPermanent(!isPermanent)}
|
||||
className={`w-10 h-5 rounded-full relative cursor-pointer transition-colors ${isPermanent ? 'bg-kodo-red' : 'bg-gray-600'}`}
|
||||
className={`w-10 h-5 rounded-full relative cursor-pointer transition-colors ${isPermanent ? 'bg-kodo-red' : 'bg-kodo-steel'}`}
|
||||
>
|
||||
<div
|
||||
className={`absolute top-1 w-3 h-3 bg-white rounded-full transition-all ${isPermanent ? 'left-6' : 'left-1'}`}
|
||||
></div>
|
||||
</div>
|
||||
<span
|
||||
className={`text-xs ${isPermanent ? 'text-kodo-red font-bold' : 'text-gray-500'}`}
|
||||
className={`text-xs ${isPermanent ? 'text-kodo-red font-bold' : 'text-kodo-content-dim'}`}
|
||||
>
|
||||
Perm
|
||||
</span>
|
||||
|
|
@ -105,7 +105,7 @@ export const BanUserModal: React.FC<BanUserModalProps> = ({
|
|||
|
||||
{!isPermanent && (
|
||||
<div>
|
||||
<label className="block text-xs font-bold text-gray-400 uppercase mb-2">
|
||||
<label className="block text-xs font-bold text-kodo-content-dim uppercase mb-2">
|
||||
Days
|
||||
</label>
|
||||
<input
|
||||
|
|
@ -125,7 +125,7 @@ export const BanUserModal: React.FC<BanUserModalProps> = ({
|
|||
</Button>
|
||||
<Button
|
||||
variant="primary"
|
||||
className="bg-red-600 hover:bg-red-700 border-red-500 text-white"
|
||||
className="bg-kodo-red hover:bg-kodo-red border-kodo-red text-white"
|
||||
onClick={() =>
|
||||
onConfirm(
|
||||
reason,
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ export const TrackAnalyticsView: React.FC<TrackAnalyticsViewProps> = ({
|
|||
</Button>
|
||||
<div>
|
||||
<h2 className="text-2xl font-bold text-white">{trackData.title}</h2>
|
||||
<p className="text-gray-400 text-sm">Analytics Report</p>
|
||||
<p className="text-kodo-content-dim text-sm">Analytics Report</p>
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
|
|
@ -127,7 +127,7 @@ export const TrackAnalyticsView: React.FC<TrackAnalyticsViewProps> = ({
|
|||
<div className="space-y-3">
|
||||
{trackData.geo.map((g) => (
|
||||
<div key={g.country} className="flex items-center gap-4">
|
||||
<div className="w-16 text-sm text-gray-400">{g.country}</div>
|
||||
<div className="w-16 text-sm text-kodo-content-dim">{g.country}</div>
|
||||
<div className="flex-1 h-2 bg-kodo-steel rounded-full overflow-hidden">
|
||||
<div
|
||||
className="h-full bg-kodo-magenta"
|
||||
|
|
@ -167,7 +167,7 @@ export const TrackAnalyticsView: React.FC<TrackAnalyticsViewProps> = ({
|
|||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex justify-between text-xs text-gray-500 mt-2">
|
||||
<div className="flex justify-between text-xs text-kodo-content-dim mt-2">
|
||||
{Object.entries(trackData.demographics).map(([range, val]) => (
|
||||
<span key={range}>
|
||||
{range}: {val}%
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ export const CartItem: React.FC<CartItemProps> = ({ item, onRemove }) => {
|
|||
className="flex flex-col md:flex-row items-center gap-4 p-4 group hover:border-kodo-cyan/30 transition-all"
|
||||
>
|
||||
{/* Thumbnail */}
|
||||
<div className="w-full md:w-24 h-24 rounded-lg overflow-hidden flex-shrink-0 bg-gray-800">
|
||||
<div className="w-full md:w-24 h-24 rounded-lg overflow-hidden flex-shrink-0 bg-kodo-graphite">
|
||||
<img
|
||||
src={item.coverUrl}
|
||||
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"
|
||||
|
|
@ -32,12 +32,12 @@ export const CartItem: React.FC<CartItemProps> = ({ item, onRemove }) => {
|
|||
{/* Info */}
|
||||
<div className="flex-1 w-full text-center md:text-left">
|
||||
<h4 className="font-bold text-white text-lg">{item.title}</h4>
|
||||
<p className="text-gray-400 text-sm mb-2">{item.author}</p>
|
||||
<p className="text-kodo-content-dim text-sm mb-2">{item.author}</p>
|
||||
<div className="flex items-center justify-center md:justify-start gap-2 text-xs">
|
||||
<span className="px-2 py-1 bg-kodo-ink border border-kodo-steel rounded flex items-center gap-1">
|
||||
<Tag className="w-3 h-3 text-kodo-cyan" /> {licenseName} License
|
||||
</span>
|
||||
<span className="px-2 py-1 bg-kodo-ink border border-kodo-steel rounded uppercase font-bold text-gray-500">
|
||||
<span className="px-2 py-1 bg-kodo-ink border border-kodo-steel rounded uppercase font-bold text-kodo-content-dim">
|
||||
{item.type}
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -51,7 +51,7 @@ export const CartItem: React.FC<CartItemProps> = ({ item, onRemove }) => {
|
|||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="text-gray-500 hover:text-kodo-red hover:bg-kodo-red/10"
|
||||
className="text-kodo-content-dim hover:text-kodo-red hover:bg-kodo-red/10"
|
||||
onClick={() => onRemove(item.cartId)}
|
||||
>
|
||||
<Trash2 className="w-4 h-4" />
|
||||
|
|
|
|||
|
|
@ -39,12 +39,12 @@ export const OrderSummary: React.FC<OrderSummaryProps> = ({
|
|||
return (
|
||||
<div className="space-y-6">
|
||||
<Card variant="gaming" className="p-6">
|
||||
<h3 className="font-bold text-white mb-6 uppercase tracking-wider text-sm border-b border-gray-700 pb-2">
|
||||
<h3 className="font-bold text-white mb-6 uppercase tracking-wider text-sm border-b border-kodo-steel pb-2">
|
||||
Order Summary
|
||||
</h3>
|
||||
|
||||
<div className="space-y-3 text-sm mb-6">
|
||||
<div className="flex justify-between text-gray-400">
|
||||
<div className="flex justify-between text-kodo-content-dim">
|
||||
<span>Subtotal</span>
|
||||
<span className="text-white font-mono">
|
||||
{formatPrice(subtotal)}
|
||||
|
|
@ -60,7 +60,7 @@ export const OrderSummary: React.FC<OrderSummaryProps> = ({
|
|||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex justify-between text-gray-400">
|
||||
<div className="flex justify-between text-kodo-content-dim">
|
||||
<span>Estimated Tax ({(taxRate * 100).toFixed(0)}%)</span>
|
||||
<span className="text-white font-mono">
|
||||
{formatPrice(taxAmount)}
|
||||
|
|
@ -68,7 +68,7 @@ export const OrderSummary: React.FC<OrderSummaryProps> = ({
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div className="border-t border-gray-700 pt-4 mb-6">
|
||||
<div className="border-t border-kodo-steel pt-4 mb-6">
|
||||
<div className="flex justify-between items-end">
|
||||
<span className="font-bold text-white">Total</span>
|
||||
<span className="text-2xl font-mono font-bold text-kodo-cyan">
|
||||
|
|
@ -92,7 +92,7 @@ export const OrderSummary: React.FC<OrderSummaryProps> = ({
|
|||
<ShieldCheck className="w-5 h-5 text-kodo-gold flex-shrink-0" />
|
||||
<div>
|
||||
<h4 className="font-bold text-white text-sm mb-1">Secure Checkout</h4>
|
||||
<p className="text-xs text-gray-400 leading-relaxed">
|
||||
<p className="text-xs text-kodo-content-dim leading-relaxed">
|
||||
Transactions are encrypted. Downloads are available immediately
|
||||
after payment.
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -76,12 +76,12 @@ export const WishlistView: React.FC = () => {
|
|||
return (
|
||||
<div className="flex flex-col items-center justify-center min-h-[50vh] text-center animate-fadeIn">
|
||||
<div className="w-24 h-24 bg-kodo-ink rounded-full flex items-center justify-center mb-6 border-2 border-dashed border-kodo-steel">
|
||||
<Heart className="w-10 h-10 text-gray-600" />
|
||||
<Heart className="w-10 h-10 text-kodo-content-dim" />
|
||||
</div>
|
||||
<h2 className="text-2xl font-bold text-white mb-2">
|
||||
Your wishlist is empty
|
||||
</h2>
|
||||
<p className="text-gray-400 max-w-sm">
|
||||
<p className="text-kodo-content-dim max-w-sm">
|
||||
Save items you want to listen to later or purchase in the future.
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -95,7 +95,7 @@ export const WishlistView: React.FC = () => {
|
|||
<h1 className="text-3xl font-display font-bold text-white mb-2">
|
||||
WISHLIST
|
||||
</h1>
|
||||
<p className="text-gray-400 font-mono text-sm">
|
||||
<p className="text-kodo-content-dim font-mono text-sm">
|
||||
{wishlist.length} saved items
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -116,7 +116,7 @@ export const WishlistView: React.FC = () => {
|
|||
className="p-4 group hover:border-kodo-cyan/50 transition-all"
|
||||
>
|
||||
<div className="flex gap-4">
|
||||
<div className="relative w-24 h-24 bg-gray-800 rounded-lg overflow-hidden flex-shrink-0">
|
||||
<div className="relative w-24 h-24 bg-kodo-graphite rounded-lg overflow-hidden flex-shrink-0">
|
||||
<img
|
||||
src={product.coverUrl}
|
||||
className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-500"
|
||||
|
|
@ -147,10 +147,10 @@ export const WishlistView: React.FC = () => {
|
|||
<h3 className="font-bold text-white truncate">
|
||||
{product.title}
|
||||
</h3>
|
||||
<p className="text-xs text-gray-400 truncate">
|
||||
<p className="text-xs text-kodo-content-dim truncate">
|
||||
{product.author}
|
||||
</p>
|
||||
<p className="text-xs text-gray-500 mt-1 capitalize">
|
||||
<p className="text-xs text-kodo-content-dim mt-1 capitalize">
|
||||
{product.type}
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -172,7 +172,7 @@ export const WishlistView: React.FC = () => {
|
|||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="text-gray-500 hover:text-kodo-red"
|
||||
className="text-kodo-content-dim hover:text-kodo-red"
|
||||
onClick={() => handleRemove(product.id)}
|
||||
>
|
||||
<Trash2 className="w-4 h-4" />
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ export const PromoCodeModal: React.FC<PromoCodeModalProps> = ({
|
|||
<Tag className="w-4 h-4 text-kodo-cyan" /> Add Promo Code
|
||||
</h3>
|
||||
<button onClick={onClose}>
|
||||
<X className="w-5 h-5 text-gray-400 hover:text-white" />
|
||||
<X className="w-5 h-5 text-kodo-content-dim hover:text-white" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -33,19 +33,19 @@ export const RefundRequestModal: React.FC<RefundRequestModalProps> = ({
|
|||
<RefreshCcw className="w-4 h-4 text-kodo-orange" /> Request Refund
|
||||
</h3>
|
||||
<button onClick={onClose}>
|
||||
<X className="w-5 h-5 text-gray-400 hover:text-white" />
|
||||
<X className="w-5 h-5 text-kodo-content-dim hover:text-white" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="p-6 space-y-4">
|
||||
<p className="text-sm text-gray-400">
|
||||
<p className="text-sm text-kodo-content-dim">
|
||||
Refund requests are subject to approval. Please provide details
|
||||
below for Order{' '}
|
||||
<span className="font-mono text-white">#{orderId}</span>.
|
||||
</p>
|
||||
|
||||
<div>
|
||||
<label className="block text-xs font-bold text-gray-400 uppercase mb-2">
|
||||
<label className="block text-xs font-bold text-kodo-content-dim uppercase mb-2">
|
||||
Reason
|
||||
</label>
|
||||
<select
|
||||
|
|
@ -61,7 +61,7 @@ export const RefundRequestModal: React.FC<RefundRequestModalProps> = ({
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-xs font-bold text-gray-400 uppercase mb-2">
|
||||
<label className="block text-xs font-bold text-kodo-content-dim uppercase mb-2">
|
||||
Details
|
||||
</label>
|
||||
<textarea
|
||||
|
|
@ -72,7 +72,7 @@ export const RefundRequestModal: React.FC<RefundRequestModalProps> = ({
|
|||
/>
|
||||
</div>
|
||||
|
||||
<div className="border-2 border-dashed border-kodo-steel rounded-lg p-6 flex flex-col items-center justify-center text-gray-500 hover:text-white hover:border-gray-500 cursor-pointer transition-colors">
|
||||
<div className="border-2 border-dashed border-kodo-steel rounded-lg p-6 flex flex-col items-center justify-center text-kodo-content-dim hover:text-white hover:border-kodo-steel cursor-pointer transition-colors">
|
||||
<UploadCloud className="w-8 h-8 mb-2" />
|
||||
<span className="text-xs font-bold uppercase">
|
||||
Upload Evidence (Optional)
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ export const StatCard: React.FC<StatCardProps> = ({
|
|||
>
|
||||
<div className="flex justify-between items-start mb-2 relative z-10">
|
||||
<div>
|
||||
<p className="text-xs font-mono text-gray-400 uppercase tracking-widest mb-1">
|
||||
<p className="text-xs font-mono text-kodo-content-dim uppercase tracking-widest mb-1">
|
||||
{label}
|
||||
</p>
|
||||
<h3 className="text-2xl font-display font-bold text-white">
|
||||
|
|
@ -103,7 +103,7 @@ export const StatCard: React.FC<StatCardProps> = ({
|
|||
<ArrowDown className="w-3 h-3" />
|
||||
)}
|
||||
{trendValue}{' '}
|
||||
<span className="text-gray-500 font-normal">vs last period</span>
|
||||
<span className="text-kodo-content-dim font-normal">vs last period</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ export const TrackList: React.FC = () => {
|
|||
|
||||
if (tracks.length === 0) {
|
||||
return (
|
||||
<div className="text-gray-500 text-center py-10 bg-kodo-ink/30 rounded-xl border border-dashed border-kodo-steel">
|
||||
<div className="text-kodo-content-dim text-center py-10 bg-kodo-ink/30 rounded-xl border border-dashed border-kodo-steel">
|
||||
<BarChart3 className="w-8 h-8 mx-auto mb-2 opacity-50" />
|
||||
<p>No tracks trending right now.</p>
|
||||
</div>
|
||||
|
|
@ -119,7 +119,7 @@ export const TrackList: React.FC = () => {
|
|||
<div className="absolute left-0 top-0 bottom-0 w-1 bg-kodo-cyan"></div>
|
||||
)}
|
||||
|
||||
<div className="w-8 text-center text-gray-500 font-mono text-xs font-bold pl-2">
|
||||
<div className="w-8 text-center text-kodo-content-dim font-mono text-xs font-bold pl-2">
|
||||
{isCurrent && isPlaying ? (
|
||||
<div className="flex gap-0.5 justify-center items-end h-3">
|
||||
<div className="w-0.5 bg-kodo-cyan h-full animate-[bounce_1s_infinite]"></div>
|
||||
|
|
@ -127,7 +127,7 @@ export const TrackList: React.FC = () => {
|
|||
<div className="w-0.5 bg-kodo-cyan h-full animate-[bounce_0.8s_infinite]"></div>
|
||||
</div>
|
||||
) : (
|
||||
<span className="group-hover:hidden text-gray-600">
|
||||
<span className="group-hover:hidden text-kodo-content-dim">
|
||||
{i + 1}
|
||||
</span>
|
||||
)}
|
||||
|
|
@ -153,12 +153,12 @@ export const TrackList: React.FC = () => {
|
|||
>
|
||||
{track.title}
|
||||
</h4>
|
||||
<p className="text-xs text-gray-400 truncate hover:underline">
|
||||
<p className="text-xs text-kodo-content-dim truncate hover:underline">
|
||||
{track.artist}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="hidden md:flex items-center gap-6 text-gray-500 text-xs font-medium">
|
||||
<div className="hidden md:flex items-center gap-6 text-kodo-content-dim text-xs font-medium">
|
||||
<span className="flex items-center gap-1.5 w-16 justify-end">
|
||||
<Play className="w-3 h-3" />{' '}
|
||||
{(track.plays || track.play_count) > 1000
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ export const APIPlaygroundView: React.FC = () => {
|
|||
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<label className="block text-xs font-bold text-gray-400 uppercase mb-2">
|
||||
<label className="block text-xs font-bold text-kodo-content-dim uppercase mb-2">
|
||||
Endpoint
|
||||
</label>
|
||||
<select
|
||||
|
|
@ -75,13 +75,13 @@ export const APIPlaygroundView: React.FC = () => {
|
|||
</option>
|
||||
))}
|
||||
</select>
|
||||
<p className="text-xs text-gray-500 mt-1">
|
||||
<p className="text-xs text-kodo-content-dim mt-1">
|
||||
{selectedEndpoint.desc}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-xs font-bold text-gray-400 uppercase mb-2">
|
||||
<label className="block text-xs font-bold text-kodo-content-dim uppercase mb-2">
|
||||
Body (JSON)
|
||||
</label>
|
||||
<textarea
|
||||
|
|
@ -122,7 +122,7 @@ export const APIPlaygroundView: React.FC = () => {
|
|||
<span className="text-xs font-bold text-kodo-lime bg-kodo-lime/10 px-2 py-1 rounded">
|
||||
200 OK
|
||||
</span>
|
||||
<span className="text-xs font-bold text-gray-400 bg-white/10 px-2 py-1 rounded">
|
||||
<span className="text-xs font-bold text-kodo-content-dim bg-white/10 px-2 py-1 rounded">
|
||||
45ms
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -132,11 +132,11 @@ export const APIPlaygroundView: React.FC = () => {
|
|||
<div className="flex-1 bg-black/30 rounded border border-kodo-steel/50 p-4 relative group">
|
||||
{response ? (
|
||||
<>
|
||||
<pre className="text-xs text-green-400 font-mono whitespace-pre-wrap overflow-auto h-full max-h-[500px]">
|
||||
<pre className="text-xs text-kodo-lime font-mono whitespace-pre-wrap overflow-auto h-full max-h-[500px]">
|
||||
{response}
|
||||
</pre>
|
||||
<button
|
||||
className="absolute top-2 right-2 p-2 bg-gray-800 rounded text-gray-400 hover:text-white opacity-0 group-hover:opacity-100 transition-opacity"
|
||||
className="absolute top-2 right-2 p-2 bg-kodo-graphite rounded text-kodo-content-dim hover:text-white opacity-0 group-hover:opacity-100 transition-opacity"
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(response);
|
||||
addToast('Copied JSON');
|
||||
|
|
@ -146,7 +146,7 @@ export const APIPlaygroundView: React.FC = () => {
|
|||
</button>
|
||||
</>
|
||||
) : (
|
||||
<div className="flex flex-col items-center justify-center h-full text-gray-500">
|
||||
<div className="flex flex-col items-center justify-center h-full text-kodo-content-dim">
|
||||
<p className="text-sm">Waiting for request...</p>
|
||||
</div>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ export const DeveloperDashboardView: React.FC = () => {
|
|||
<h1 className="text-3xl font-display font-bold text-white mb-2">
|
||||
DEVELOPER PORTAL
|
||||
</h1>
|
||||
<p className="text-gray-400 font-mono text-sm">
|
||||
<p className="text-kodo-content-dim font-mono text-sm">
|
||||
Build on top of the Veza Platform.
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -140,7 +140,7 @@ export const DeveloperDashboardView: React.FC = () => {
|
|||
<div className="overflow-x-auto">
|
||||
<table className="w-full text-left">
|
||||
<thead>
|
||||
<tr className="text-xs text-gray-500 uppercase border-b border-kodo-steel/50">
|
||||
<tr className="text-xs text-kodo-content-dim uppercase border-b border-kodo-steel/50">
|
||||
<th className="pb-3 pl-4">Name</th>
|
||||
<th className="pb-3">Key Prefix</th>
|
||||
<th className="pb-3">Created</th>
|
||||
|
|
@ -158,13 +158,13 @@ export const DeveloperDashboardView: React.FC = () => {
|
|||
<td className="py-4 font-mono text-kodo-gold">
|
||||
{key.prefix}
|
||||
</td>
|
||||
<td className="py-4 text-gray-400">{key.created}</td>
|
||||
<td className="py-4 text-gray-300">{key.lastUsed}</td>
|
||||
<td className="py-4 text-kodo-content-dim">{key.created}</td>
|
||||
<td className="py-4 text-kodo-text-main">{key.lastUsed}</td>
|
||||
<td className="py-4 text-right pr-4 flex justify-end gap-2">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-8 w-8 text-gray-400 hover:text-white"
|
||||
className="h-8 w-8 text-kodo-content-dim hover:text-white"
|
||||
onClick={() => addToast('Full key hidden for security')}
|
||||
>
|
||||
<Eye className="w-4 h-4" />
|
||||
|
|
@ -182,7 +182,7 @@ export const DeveloperDashboardView: React.FC = () => {
|
|||
))}
|
||||
{keys.length === 0 && (
|
||||
<tr>
|
||||
<td colSpan={5} className="py-8 text-center text-gray-500">
|
||||
<td colSpan={5} className="py-8 text-center text-kodo-content-dim">
|
||||
No active API keys. Create one to get started.
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ export const WebhooksView: React.FC = () => {
|
|||
<div className="space-y-8 animate-fadeIn pb-20">
|
||||
<div>
|
||||
<h2 className="text-2xl font-bold text-white mb-2">WEBHOOKS</h2>
|
||||
<p className="text-gray-400 font-mono text-sm">
|
||||
<p className="text-kodo-content-dim font-mono text-sm">
|
||||
Subscribe to real-time events.
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -105,17 +105,17 @@ export const WebhooksView: React.FC = () => {
|
|||
<div className="font-bold text-white font-mono text-sm break-all">
|
||||
{hook.url}
|
||||
</div>
|
||||
<div className="text-xs text-gray-400 mt-1 flex flex-wrap gap-2">
|
||||
<span className="text-gray-500">Events:</span>
|
||||
<div className="text-xs text-kodo-content-dim mt-1 flex flex-wrap gap-2">
|
||||
<span className="text-kodo-content-dim">Events:</span>
|
||||
{hook.events.map((e) => (
|
||||
<span
|
||||
key={e}
|
||||
className="bg-white/5 px-1.5 rounded text-gray-300"
|
||||
className="bg-white/5 px-1.5 rounded text-kodo-text-main"
|
||||
>
|
||||
{e}
|
||||
</span>
|
||||
))}
|
||||
<span className="text-gray-500 ml-2">
|
||||
<span className="text-kodo-content-dim ml-2">
|
||||
Last Triggered: {hook.lastTriggered}
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ export const CreateAPIKeyModal: React.FC<CreateAPIKeyModalProps> = ({
|
|||
{step === 1 ? 'Create API Key' : 'API Key Generated'}
|
||||
</h3>
|
||||
<button onClick={onClose}>
|
||||
<X className="w-5 h-5 text-gray-400 hover:text-white" />
|
||||
<X className="w-5 h-5 text-kodo-content-dim hover:text-white" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
|
@ -79,22 +79,22 @@ export const CreateAPIKeyModal: React.FC<CreateAPIKeyModalProps> = ({
|
|||
/>
|
||||
|
||||
<div>
|
||||
<label className="block text-xs font-bold text-gray-400 uppercase mb-3">
|
||||
<label className="block text-xs font-bold text-kodo-content-dim uppercase mb-3">
|
||||
Permissions (Scopes)
|
||||
</label>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||||
{SCOPES.map((scope) => (
|
||||
<label
|
||||
key={scope.id}
|
||||
className="flex items-center gap-3 p-3 bg-kodo-ink rounded border border-kodo-steel cursor-pointer hover:border-gray-500 transition-colors"
|
||||
className="flex items-center gap-3 p-3 bg-kodo-ink rounded border border-kodo-steel cursor-pointer hover:border-kodo-steel transition-colors"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
className="rounded border-gray-600 bg-transparent text-kodo-gold focus:ring-0"
|
||||
className="rounded border-kodo-steel bg-transparent text-kodo-gold focus:ring-0"
|
||||
checked={selectedScopes.includes(scope.id)}
|
||||
onChange={() => toggleScope(scope.id)}
|
||||
/>
|
||||
<span className="text-sm text-gray-300">
|
||||
<span className="text-sm text-kodo-text-main">
|
||||
{scope.label}
|
||||
</span>
|
||||
</label>
|
||||
|
|
@ -111,7 +111,7 @@ export const CreateAPIKeyModal: React.FC<CreateAPIKeyModalProps> = ({
|
|||
<h4 className="text-xl font-bold text-white mb-2">
|
||||
Key Created Successfully
|
||||
</h4>
|
||||
<p className="text-sm text-gray-400 max-w-xs mx-auto">
|
||||
<p className="text-sm text-kodo-content-dim max-w-xs mx-auto">
|
||||
Please copy your API key now. For security reasons, you won't
|
||||
be able to see it again.
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ export const CourseCard: React.FC<CourseCardProps> = ({
|
|||
onClick={() => onClick(course)}
|
||||
>
|
||||
{/* Cover */}
|
||||
<div className="relative aspect-video bg-gray-900 overflow-hidden">
|
||||
<div className="relative aspect-video bg-kodo-ink overflow-hidden">
|
||||
<img
|
||||
src={course.thumbnailUrl}
|
||||
className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-110 opacity-90 group-hover:opacity-100"
|
||||
|
|
@ -65,12 +65,12 @@ export const CourseCard: React.FC<CourseCardProps> = ({
|
|||
<h3 className="font-bold text-white text-base mb-1 line-clamp-2 group-hover:text-kodo-cyan transition-colors">
|
||||
{course.title}
|
||||
</h3>
|
||||
<p className="text-gray-400 text-xs mb-3">by {course.instructor}</p>
|
||||
<p className="text-kodo-content-dim text-xs mb-3">by {course.instructor}</p>
|
||||
|
||||
<div className="mt-auto pt-2">
|
||||
{showProgress && course.progress !== undefined ? (
|
||||
<div className="space-y-2">
|
||||
<div className="flex justify-between text-xs text-gray-400">
|
||||
<div className="flex justify-between text-xs text-kodo-content-dim">
|
||||
<span>Progress</span>
|
||||
<span
|
||||
className={
|
||||
|
|
@ -92,7 +92,7 @@ export const CourseCard: React.FC<CourseCardProps> = ({
|
|||
</div>
|
||||
) : (
|
||||
<div className="flex justify-between items-center border-t border-white/5 pt-3">
|
||||
<div className="flex items-center gap-1 text-xs text-gray-500">
|
||||
<div className="flex items-center gap-1 text-xs text-kodo-content-dim">
|
||||
<Users className="w-3 h-3" />{' '}
|
||||
{(course.studentCount || 0).toLocaleString()} students
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ export const CourseDetailView: React.FC<CourseDetailViewProps> = ({
|
|||
<Button
|
||||
variant="ghost"
|
||||
onClick={onBack}
|
||||
className="pl-0 text-gray-400 hover:text-white"
|
||||
className="pl-0 text-kodo-content-dim hover:text-white"
|
||||
>
|
||||
← Back to Courses
|
||||
</Button>
|
||||
|
|
@ -62,11 +62,11 @@ export const CourseDetailView: React.FC<CourseDetailViewProps> = ({
|
|||
<h1 className="text-3xl md:text-4xl font-display font-bold text-white mb-4">
|
||||
{course.title}
|
||||
</h1>
|
||||
<p className="text-xl text-gray-300 mb-6 font-light">
|
||||
<p className="text-xl text-kodo-text-main mb-6 font-light">
|
||||
{course.description}
|
||||
</p>
|
||||
|
||||
<div className="flex flex-wrap items-center gap-6 text-sm text-gray-400 mb-6">
|
||||
<div className="flex flex-wrap items-center gap-6 text-sm text-kodo-content-dim mb-6">
|
||||
{course.rating && (
|
||||
<span className="flex items-center gap-1 text-kodo-gold font-bold">
|
||||
<Star className="w-4 h-4 fill-current" /> {course.rating}
|
||||
|
|
@ -90,7 +90,7 @@ export const CourseDetailView: React.FC<CourseDetailViewProps> = ({
|
|||
className="w-10 h-10 rounded-full"
|
||||
/>
|
||||
<div>
|
||||
<div className="text-xs text-gray-500 uppercase">
|
||||
<div className="text-xs text-kodo-content-dim uppercase">
|
||||
Created by
|
||||
</div>
|
||||
<div className="text-sm font-bold text-white text-kodo-cyan cursor-pointer hover:underline">
|
||||
|
|
@ -106,7 +106,7 @@ export const CourseDetailView: React.FC<CourseDetailViewProps> = ({
|
|||
<button
|
||||
key={tab}
|
||||
onClick={() => setActiveTab(tab as any)}
|
||||
className={`pb-3 text-sm font-bold uppercase tracking-wider border-b-2 transition-colors ${activeTab === tab ? 'border-kodo-cyan text-white' : 'border-transparent text-gray-500 hover:text-gray-300'}`}
|
||||
className={`pb-3 text-sm font-bold uppercase tracking-wider border-b-2 transition-colors ${activeTab === tab ? 'border-kodo-cyan text-white' : 'border-transparent text-kodo-content-dim hover:text-kodo-text-main'}`}
|
||||
>
|
||||
{tab}
|
||||
</button>
|
||||
|
|
@ -122,7 +122,7 @@ export const CourseDetailView: React.FC<CourseDetailViewProps> = ({
|
|||
</h3>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||||
{course.whatYouWillLearn?.map((item, i) => (
|
||||
<div key={i} className="flex gap-3 text-sm text-gray-300">
|
||||
<div key={i} className="flex gap-3 text-sm text-kodo-text-main">
|
||||
<CheckCircle className="w-4 h-4 text-kodo-lime flex-shrink-0 mt-0.5" />
|
||||
<span>{item}</span>
|
||||
</div>
|
||||
|
|
@ -134,7 +134,7 @@ export const CourseDetailView: React.FC<CourseDetailViewProps> = ({
|
|||
<h3 className="font-bold text-white text-lg mb-4">
|
||||
Requirements
|
||||
</h3>
|
||||
<ul className="list-disc pl-5 space-y-1 text-sm text-gray-400">
|
||||
<ul className="list-disc pl-5 space-y-1 text-sm text-kodo-content-dim">
|
||||
{course.requirements?.map((req, i) => (
|
||||
<li key={i}>{req}</li>
|
||||
))}
|
||||
|
|
@ -145,7 +145,7 @@ export const CourseDetailView: React.FC<CourseDetailViewProps> = ({
|
|||
|
||||
{activeTab === 'curriculum' && (
|
||||
<div className="space-y-4 animate-fadeIn">
|
||||
<div className="flex justify-between items-center text-sm text-gray-400 mb-2">
|
||||
<div className="flex justify-between items-center text-sm text-kodo-content-dim mb-2">
|
||||
<span>
|
||||
{course.modules?.length} Modules •{' '}
|
||||
{course.modules?.reduce(
|
||||
|
|
@ -182,7 +182,7 @@ export const CourseDetailView: React.FC<CourseDetailViewProps> = ({
|
|||
)}
|
||||
{module.title}
|
||||
</h4>
|
||||
<span className="text-xs text-gray-500">
|
||||
<span className="text-xs text-kodo-content-dim">
|
||||
{module.lessons.length} lectures
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -195,7 +195,7 @@ export const CourseDetailView: React.FC<CourseDetailViewProps> = ({
|
|||
key={lesson.id}
|
||||
className="p-3 pl-8 flex justify-between items-center hover:bg-white/5 border-b border-kodo-steel/30 last:border-0"
|
||||
>
|
||||
<div className="flex items-center gap-3 text-sm text-gray-300">
|
||||
<div className="flex items-center gap-3 text-sm text-kodo-text-main">
|
||||
{lesson.type === 'video' ? (
|
||||
<PlayCircle className="w-4 h-4" />
|
||||
) : (
|
||||
|
|
@ -205,9 +205,9 @@ export const CourseDetailView: React.FC<CourseDetailViewProps> = ({
|
|||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
{lesson.isLocked && !isEnrolled && (
|
||||
<Lock className="w-3 h-3 text-gray-500" />
|
||||
<Lock className="w-3 h-3 text-kodo-content-dim" />
|
||||
)}
|
||||
<span className="text-xs text-gray-500">
|
||||
<span className="text-xs text-kodo-content-dim">
|
||||
{lesson.duration}
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -240,16 +240,16 @@ export const CourseDetailView: React.FC<CourseDetailViewProps> = ({
|
|||
{[...Array(5)].map((_, i) => (
|
||||
<Star
|
||||
key={i}
|
||||
className={`w-3 h-3 ${i < review.rating ? 'fill-current' : 'text-gray-700'}`}
|
||||
className={`w-3 h-3 ${i < review.rating ? 'fill-current' : 'text-kodo-text-main'}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<span className="ml-auto text-xs text-gray-500">
|
||||
<span className="ml-auto text-xs text-kodo-content-dim">
|
||||
{review.date}
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-gray-300">{review.comment}</p>
|
||||
<p className="text-sm text-kodo-text-main">{review.comment}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
@ -288,7 +288,7 @@ export const CourseDetailView: React.FC<CourseDetailViewProps> = ({
|
|||
: 'Free'}
|
||||
</div>
|
||||
{course.price && course.price > 0 && !isEnrolled && (
|
||||
<p className="text-gray-400 text-xs mb-6 line-through">
|
||||
<p className="text-kodo-content-dim text-xs mb-6 line-through">
|
||||
$199.99 (85% off)
|
||||
</p>
|
||||
)}
|
||||
|
|
@ -310,7 +310,7 @@ export const CourseDetailView: React.FC<CourseDetailViewProps> = ({
|
|||
>
|
||||
ENROLL NOW
|
||||
</Button>
|
||||
<p className="text-center text-xs text-gray-500">
|
||||
<p className="text-center text-xs text-kodo-content-dim">
|
||||
30-Day Money-Back Guarantee
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -320,7 +320,7 @@ export const CourseDetailView: React.FC<CourseDetailViewProps> = ({
|
|||
<h4 className="font-bold text-white text-sm">
|
||||
This course includes:
|
||||
</h4>
|
||||
<ul className="text-sm text-gray-400 space-y-2">
|
||||
<ul className="text-sm text-kodo-content-dim space-y-2">
|
||||
<li className="flex items-center gap-3">
|
||||
<PlayCircle className="w-4 h-4" /> {course.duration}{' '}
|
||||
on-demand video
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ export const CourseLearningView: React.FC<CourseLearningViewProps> = ({
|
|||
<div className="hidden md:block w-32">
|
||||
<ProgressBar value={progress} color="lime" />
|
||||
</div>
|
||||
<div className="text-xs text-gray-400 font-mono hidden md:block">
|
||||
<div className="text-xs text-kodo-content-dim font-mono hidden md:block">
|
||||
{progress}% Complete
|
||||
</div>
|
||||
<Button
|
||||
|
|
@ -146,8 +146,8 @@ export const CourseLearningView: React.FC<CourseLearningViewProps> = ({
|
|||
{currentLesson?.type === 'video' ? (
|
||||
<div className="text-center">
|
||||
<PlayCircle className="w-16 h-16 text-white opacity-50 mx-auto mb-4" />
|
||||
<p className="text-gray-500">Video Player Placeholder</p>
|
||||
<p className="text-xs text-gray-600 mt-2">
|
||||
<p className="text-kodo-content-dim">Video Player Placeholder</p>
|
||||
<p className="text-xs text-kodo-content-dim mt-2">
|
||||
{currentLesson.title}
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -171,7 +171,7 @@ export const CourseLearningView: React.FC<CourseLearningViewProps> = ({
|
|||
<h2 className="text-2xl font-bold text-white mb-4">
|
||||
{currentLesson?.title}
|
||||
</h2>
|
||||
<p className="text-gray-300 leading-relaxed">
|
||||
<p className="text-kodo-text-main leading-relaxed">
|
||||
{currentLesson?.content ||
|
||||
'This is a text-based lesson. Content would be rendered here in Markdown.'}
|
||||
</p>
|
||||
|
|
@ -208,7 +208,7 @@ export const CourseLearningView: React.FC<CourseLearningViewProps> = ({
|
|||
<button
|
||||
key={tab}
|
||||
onClick={() => setActiveTab(tab as any)}
|
||||
className={`pb-3 text-sm font-bold uppercase tracking-wider border-b-2 transition-colors ${activeTab === tab ? 'border-kodo-cyan text-white' : 'border-transparent text-gray-500 hover:text-gray-300'}`}
|
||||
className={`pb-3 text-sm font-bold uppercase tracking-wider border-b-2 transition-colors ${activeTab === tab ? 'border-kodo-cyan text-white' : 'border-transparent text-kodo-content-dim hover:text-kodo-text-main'}`}
|
||||
>
|
||||
{tab}
|
||||
</button>
|
||||
|
|
@ -216,7 +216,7 @@ export const CourseLearningView: React.FC<CourseLearningViewProps> = ({
|
|||
</div>
|
||||
|
||||
{activeTab === 'overview' && (
|
||||
<div className="text-gray-300 space-y-4">
|
||||
<div className="text-kodo-text-main space-y-4">
|
||||
<p>
|
||||
In this lesson, we cover the fundamentals of the topic. Make
|
||||
sure to take notes.
|
||||
|
|
@ -280,7 +280,7 @@ export const CourseLearningView: React.FC<CourseLearningViewProps> = ({
|
|||
<div className="flex-1 overflow-y-auto custom-scrollbar">
|
||||
{course.modules?.map((module, i) => (
|
||||
<div key={module.id} className="border-b border-kodo-steel/30">
|
||||
<div className="p-4 bg-kodo-ink/50 text-xs font-bold text-gray-400 uppercase tracking-wider sticky top-0 backdrop-blur-sm z-10">
|
||||
<div className="p-4 bg-kodo-ink/50 text-xs font-bold text-kodo-content-dim uppercase tracking-wider sticky top-0 backdrop-blur-sm z-10">
|
||||
Section {i + 1}: {module.title}
|
||||
</div>
|
||||
<div>
|
||||
|
|
@ -298,19 +298,19 @@ export const CourseLearningView: React.FC<CourseLearningViewProps> = ({
|
|||
<CheckCircle className="w-4 h-4 text-kodo-lime" />
|
||||
) : lesson.type === 'video' ? (
|
||||
<PlayCircle
|
||||
className={`w-4 h-4 ${isActive ? 'text-kodo-cyan' : 'text-gray-500'}`}
|
||||
className={`w-4 h-4 ${isActive ? 'text-kodo-cyan' : 'text-kodo-content-dim'}`}
|
||||
/>
|
||||
) : (
|
||||
<HelpCircle className="w-4 h-4 text-gray-500" />
|
||||
<HelpCircle className="w-4 h-4 text-kodo-content-dim" />
|
||||
)}
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<div
|
||||
className={`text-sm font-medium leading-snug ${isActive ? 'text-white' : 'text-gray-300'}`}
|
||||
className={`text-sm font-medium leading-snug ${isActive ? 'text-white' : 'text-kodo-text-main'}`}
|
||||
>
|
||||
{lesson.title}
|
||||
</div>
|
||||
<div className="text-[10px] text-gray-500 mt-1 flex items-center gap-2">
|
||||
<div className="text-[10px] text-kodo-content-dim mt-1 flex items-center gap-2">
|
||||
<span>{lesson.duration}</span>
|
||||
{lesson.type === 'quiz' && (
|
||||
<span className="text-kodo-gold">Quiz</span>
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ export const MyCoursesView: React.FC<MyCoursesViewProps> = ({ onContinue }) => {
|
|||
<h2 className="text-2xl font-bold text-white mb-2">
|
||||
{lastActiveCourse.title}
|
||||
</h2>
|
||||
<div className="w-full bg-gray-700 h-2 rounded-full mb-4 max-w-md mx-auto md:mx-0">
|
||||
<div className="w-full bg-kodo-steel h-2 rounded-full mb-4 max-w-md mx-auto md:mx-0">
|
||||
<div
|
||||
className="bg-kodo-cyan h-full rounded-full"
|
||||
style={{ width: `${lastActiveCourse.progress}%` }}
|
||||
|
|
@ -110,13 +110,13 @@ export const MyCoursesView: React.FC<MyCoursesViewProps> = ({ onContinue }) => {
|
|||
<div className="border-b border-kodo-steel flex gap-6">
|
||||
<button
|
||||
onClick={() => setActiveTab('in_progress')}
|
||||
className={`pb-3 text-sm font-bold uppercase tracking-wider border-b-2 transition-colors ${activeTab === 'in_progress' ? 'border-kodo-cyan text-white' : 'border-transparent text-gray-500 hover:text-gray-300'}`}
|
||||
className={`pb-3 text-sm font-bold uppercase tracking-wider border-b-2 transition-colors ${activeTab === 'in_progress' ? 'border-kodo-cyan text-white' : 'border-transparent text-kodo-content-dim hover:text-kodo-text-main'}`}
|
||||
>
|
||||
In Progress
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab('completed')}
|
||||
className={`pb-3 text-sm font-bold uppercase tracking-wider border-b-2 transition-colors ${activeTab === 'completed' ? 'border-kodo-lime text-white' : 'border-transparent text-gray-500 hover:text-gray-300'}`}
|
||||
className={`pb-3 text-sm font-bold uppercase tracking-wider border-b-2 transition-colors ${activeTab === 'completed' ? 'border-kodo-lime text-white' : 'border-transparent text-kodo-content-dim hover:text-kodo-text-main'}`}
|
||||
>
|
||||
Completed
|
||||
</button>
|
||||
|
|
@ -133,7 +133,7 @@ export const MyCoursesView: React.FC<MyCoursesViewProps> = ({ onContinue }) => {
|
|||
/>
|
||||
))}
|
||||
{filteredCourses.length === 0 && (
|
||||
<div className="col-span-full text-center py-20 text-gray-500">
|
||||
<div className="col-span-full text-center py-20 text-kodo-content-dim">
|
||||
<p>No courses found in this category.</p>
|
||||
</div>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -38,48 +38,48 @@ export const CertificateModal: React.FC<CertificateModalProps> = ({
|
|||
<Award className="w-5 h-5 text-kodo-gold" /> Completion Certificate
|
||||
</h3>
|
||||
<button onClick={onClose}>
|
||||
<X className="w-5 h-5 text-gray-400 hover:text-white" />
|
||||
<X className="w-5 h-5 text-kodo-content-dim hover:text-white" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="p-8 bg-gray-900 flex justify-center">
|
||||
<div className="p-8 bg-kodo-ink flex justify-center">
|
||||
{/* Certificate Preview */}
|
||||
<div className="w-full aspect-[1.414] bg-white text-black p-8 relative shadow-2xl max-w-2xl border-8 border-double border-gray-300">
|
||||
<div className="w-full aspect-[1.414] bg-white text-black p-8 relative shadow-2xl max-w-2xl border-8 border-double border-kodo-steel">
|
||||
<div className="h-full border-4 border-kodo-gold/20 flex flex-col items-center justify-center text-center p-8 bg-[url('https://www.transparenttextures.com/patterns/cream-paper.png')]">
|
||||
<div className="mb-8">
|
||||
<h1 className="text-4xl font-display font-bold text-gray-900 mb-2 uppercase tracking-widest">
|
||||
<h1 className="text-4xl font-display font-bold text-kodo-text-main mb-2 uppercase tracking-widest">
|
||||
Certificate
|
||||
</h1>
|
||||
<p className="text-sm font-serif italic text-gray-500">
|
||||
<p className="text-sm font-serif italic text-kodo-content-dim">
|
||||
of Completion
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p className="text-sm text-gray-600 mb-2">
|
||||
<p className="text-sm text-kodo-content-dim mb-2">
|
||||
This is to certify that
|
||||
</p>
|
||||
<h2 className="text-3xl font-script font-bold text-kodo-cyan-dim mb-6 border-b-2 border-gray-200 pb-2 px-8">
|
||||
<h2 className="text-3xl font-script font-bold text-kodo-cyan-dim mb-6 border-b-2 border-kodo-steel pb-2 px-8">
|
||||
{studentName}
|
||||
</h2>
|
||||
|
||||
<p className="text-sm text-gray-600 mb-2">
|
||||
<p className="text-sm text-kodo-content-dim mb-2">
|
||||
has successfully completed the course
|
||||
</p>
|
||||
<h3 className="text-xl font-bold text-gray-800 mb-8 max-w-md leading-tight">
|
||||
<h3 className="text-xl font-bold text-kodo-text-main mb-8 max-w-md leading-tight">
|
||||
{courseName}
|
||||
</h3>
|
||||
|
||||
<div className="flex justify-between w-full mt-auto pt-8 border-t border-gray-300">
|
||||
<div className="flex justify-between w-full mt-auto pt-8 border-t border-kodo-steel">
|
||||
<div className="text-left">
|
||||
<p className="text-xs font-bold text-gray-900">
|
||||
<p className="text-xs font-bold text-kodo-text-main">
|
||||
{completionDate}
|
||||
</p>
|
||||
<p className="text-[10px] text-gray-500 uppercase">Date</p>
|
||||
<p className="text-[10px] text-kodo-content-dim uppercase">Date</p>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="h-8 w-24 bg-gray-200 mb-1 opacity-50"></div>{' '}
|
||||
<div className="h-8 w-24 bg-kodo-slate mb-1 opacity-50"></div>{' '}
|
||||
{/* Signature line */}
|
||||
<p className="text-[10px] text-gray-500 uppercase">
|
||||
<p className="text-[10px] text-kodo-content-dim uppercase">
|
||||
Veza Academy
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ export const QuizModal: React.FC<QuizModalProps> = ({
|
|||
<h2 className="text-2xl font-bold text-white mb-2">
|
||||
{passed ? 'Assessment Passed!' : 'Try Again'}
|
||||
</h2>
|
||||
<p className="text-gray-400 mb-6">
|
||||
<p className="text-kodo-content-dim mb-6">
|
||||
You scored{' '}
|
||||
<span
|
||||
className={`font-bold ${passed ? 'text-kodo-lime' : 'text-kodo-red'}`}
|
||||
|
|
@ -111,7 +111,7 @@ export const QuizModal: React.FC<QuizModalProps> = ({
|
|||
<HelpCircle className="w-5 h-5 text-kodo-cyan" /> {quiz.title}
|
||||
</h3>
|
||||
<button onClick={onClose}>
|
||||
<X className="w-5 h-5 text-gray-400 hover:text-white" />
|
||||
<X className="w-5 h-5 text-kodo-content-dim hover:text-white" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
|
@ -127,7 +127,7 @@ export const QuizModal: React.FC<QuizModalProps> = ({
|
|||
|
||||
{/* Question Area */}
|
||||
<div className="p-8 flex-1 overflow-y-auto">
|
||||
<span className="text-xs font-bold text-gray-500 uppercase mb-2 block">
|
||||
<span className="text-xs font-bold text-kodo-content-dim uppercase mb-2 block">
|
||||
Question {currentQuestionIndex + 1} of {quiz.questions.length}
|
||||
</span>
|
||||
<h2 className="text-xl font-bold text-white mb-6 leading-relaxed">
|
||||
|
|
@ -142,12 +142,12 @@ export const QuizModal: React.FC<QuizModalProps> = ({
|
|||
className={`w-full text-left p-4 rounded-lg border transition-all ${
|
||||
selectedAnswers[currentQuestionIndex] === idx
|
||||
? 'bg-kodo-cyan/10 border-kodo-cyan text-white'
|
||||
: 'bg-kodo-ink border-kodo-steel text-gray-300 hover:bg-white/5 hover:border-gray-500'
|
||||
: 'bg-kodo-ink border-kodo-steel text-kodo-text-main hover:bg-white/5 hover:border-kodo-steel'
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
<div
|
||||
className={`w-6 h-6 rounded-full border flex items-center justify-center text-xs font-bold ${selectedAnswers[currentQuestionIndex] === idx ? 'bg-kodo-cyan border-kodo-cyan text-black' : 'border-gray-500 text-gray-500'}`}
|
||||
className={`w-6 h-6 rounded-full border flex items-center justify-center text-xs font-bold ${selectedAnswers[currentQuestionIndex] === idx ? 'bg-kodo-cyan border-kodo-cyan text-black' : 'border-kodo-steel text-kodo-content-dim'}`}
|
||||
>
|
||||
{String.fromCharCode(65 + idx)}
|
||||
</div>
|
||||
|
|
@ -160,7 +160,7 @@ export const QuizModal: React.FC<QuizModalProps> = ({
|
|||
|
||||
{/* Footer */}
|
||||
<div className="p-4 border-t border-kodo-steel bg-kodo-ink flex justify-between items-center">
|
||||
<span className="text-xs text-gray-500">
|
||||
<span className="text-xs text-kodo-content-dim">
|
||||
Passing Score: {quiz.passingScore}%
|
||||
</span>
|
||||
<Button
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ export const AchievementCard: React.FC<AchievementCardProps> = ({
|
|||
</div>
|
||||
)}
|
||||
{!isUnlocked && (
|
||||
<div className="absolute top-2 right-2 text-gray-500">
|
||||
<div className="absolute top-2 right-2 text-kodo-content-dim">
|
||||
<Lock className="w-4 h-4" />
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -38,30 +38,30 @@ export const AchievementCard: React.FC<AchievementCardProps> = ({
|
|||
className={`flex ${compact ? 'flex-row items-center gap-4' : 'flex-col items-center text-center gap-3'}`}
|
||||
>
|
||||
<div
|
||||
className={`rounded-full bg-gradient-to-br from-gray-800 to-black flex items-center justify-center border-2 ${isUnlocked ? 'border-kodo-gold w-16 h-16 text-3xl shadow-[0_0_15px_rgba(234,179,8,0.3)]' : 'border-gray-700 w-12 h-12 text-xl text-gray-500'}`}
|
||||
className={`rounded-full bg-gradient-to-br from-kodo-graphite to-black flex items-center justify-center border-2 ${isUnlocked ? 'border-kodo-gold w-16 h-16 text-3xl shadow-[0_0_15px_rgba(234,179,8,0.3)]' : 'border-kodo-steel w-12 h-12 text-xl text-kodo-content-dim'}`}
|
||||
>
|
||||
{achievement.icon}
|
||||
</div>
|
||||
|
||||
<div className="flex-1 min-w-0">
|
||||
<h4
|
||||
className={`font-bold truncate ${isUnlocked ? 'text-white' : 'text-gray-400'}`}
|
||||
className={`font-bold truncate ${isUnlocked ? 'text-white' : 'text-kodo-content-dim'}`}
|
||||
>
|
||||
{achievement.name}
|
||||
</h4>
|
||||
<p className="text-xs text-gray-500 line-clamp-2 mb-2">
|
||||
<p className="text-xs text-kodo-content-dim line-clamp-2 mb-2">
|
||||
{achievement.description}
|
||||
</p>
|
||||
|
||||
{/* Progress */}
|
||||
<div className="w-full bg-gray-800 h-1.5 rounded-full overflow-hidden">
|
||||
<div className="w-full bg-kodo-graphite h-1.5 rounded-full overflow-hidden">
|
||||
<div
|
||||
className={`h-full transition-all duration-500 ${isUnlocked ? 'bg-kodo-gold' : 'bg-gray-600'}`}
|
||||
className={`h-full transition-all duration-500 ${isUnlocked ? 'bg-kodo-gold' : 'bg-kodo-steel'}`}
|
||||
style={{ width: `${percentage}%` }}
|
||||
></div>
|
||||
</div>
|
||||
<div className="flex justify-between text-[10px] mt-1 font-mono">
|
||||
<span className={isUnlocked ? 'text-kodo-gold' : 'text-gray-500'}>
|
||||
<span className={isUnlocked ? 'text-kodo-gold' : 'text-kodo-content-dim'}>
|
||||
{achievement.progress} / {achievement.maxProgress}
|
||||
</span>
|
||||
<span className="text-kodo-cyan">+{achievement.xpReward} XP</span>
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ export const AchievementsView: React.FC = () => {
|
|||
<h2 className="text-2xl font-display font-bold text-white mb-2">
|
||||
ACHIEVEMENTS
|
||||
</h2>
|
||||
<p className="text-gray-400 font-mono text-sm">
|
||||
<p className="text-kodo-content-dim font-mono text-sm">
|
||||
Track your milestones and earn rewards.
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ export const LeaderboardView: React.FC = () => {
|
|||
<h2 className="text-2xl font-display font-bold text-white mb-2">
|
||||
LEADERBOARD
|
||||
</h2>
|
||||
<p className="text-gray-400 font-mono text-sm">
|
||||
<p className="text-kodo-content-dim font-mono text-sm">
|
||||
Top producers dominating the network.
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -47,7 +47,7 @@ export const LeaderboardView: React.FC = () => {
|
|||
<button
|
||||
key={p}
|
||||
onClick={() => setPeriod(p as any)}
|
||||
className={`px-4 py-2 rounded text-xs font-bold uppercase transition-all ${period === p ? 'bg-kodo-gold text-black shadow-lg' : 'text-gray-400 hover:text-white'}`}
|
||||
className={`px-4 py-2 rounded text-xs font-bold uppercase transition-all ${period === p ? 'bg-kodo-gold text-black shadow-lg' : 'text-kodo-content-dim hover:text-white'}`}
|
||||
>
|
||||
{p === 'all' ? 'All Time' : p}
|
||||
</button>
|
||||
|
|
@ -72,7 +72,7 @@ export const LeaderboardView: React.FC = () => {
|
|||
>
|
||||
<div className="relative mb-4">
|
||||
<div
|
||||
className={`w-20 h-20 md:w-24 md:h-24 rounded-full overflow-hidden border-4 ${i === 1 ? 'border-kodo-gold' : i === 0 ? 'border-gray-300' : 'border-orange-400'}`}
|
||||
className={`w-20 h-20 md:w-24 md:h-24 rounded-full overflow-hidden border-4 ${i === 1 ? 'border-kodo-gold' : i === 0 ? 'border-kodo-steel' : 'border-orange-400'}`}
|
||||
>
|
||||
<img
|
||||
src={entry.avatar}
|
||||
|
|
@ -104,7 +104,7 @@ export const LeaderboardView: React.FC = () => {
|
|||
<Card variant="default" className="p-0 overflow-hidden">
|
||||
<table className="w-full text-left">
|
||||
<thead>
|
||||
<tr className="border-b border-kodo-steel bg-kodo-ink text-xs font-bold text-gray-500 uppercase tracking-wider">
|
||||
<tr className="border-b border-kodo-steel bg-kodo-ink text-xs font-bold text-kodo-content-dim uppercase tracking-wider">
|
||||
<th className="p-4 w-16 text-center">Rank</th>
|
||||
<th className="p-4">Producer</th>
|
||||
<th className="p-4">Level</th>
|
||||
|
|
@ -118,7 +118,7 @@ export const LeaderboardView: React.FC = () => {
|
|||
key={entry.userId}
|
||||
className="hover:bg-white/5 transition-colors group"
|
||||
>
|
||||
<td className="p-4 text-center font-bold font-mono text-gray-400">
|
||||
<td className="p-4 text-center font-bold font-mono text-kodo-content-dim">
|
||||
#{entry.rank}
|
||||
</td>
|
||||
<td className="p-4">
|
||||
|
|
@ -133,7 +133,7 @@ export const LeaderboardView: React.FC = () => {
|
|||
</div>
|
||||
</td>
|
||||
<td className="p-4">
|
||||
<span className="bg-kodo-slate px-2 py-1 rounded text-xs font-mono text-gray-300">
|
||||
<span className="bg-kodo-slate px-2 py-1 rounded text-xs font-mono text-kodo-text-main">
|
||||
LVL {entry.level}
|
||||
</span>
|
||||
</td>
|
||||
|
|
@ -151,7 +151,7 @@ export const LeaderboardView: React.FC = () => {
|
|||
{Math.abs(entry.trend)}
|
||||
</span>
|
||||
) : (
|
||||
<span className="text-gray-500 flex items-center justify-center">
|
||||
<span className="text-kodo-content-dim flex items-center justify-center">
|
||||
<Minus className="w-4 h-4" />
|
||||
</span>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ export const ProfileXPView: React.FC<ProfileXPViewProps> = ({ username }) => {
|
|||
<div className="flex justify-between items-end">
|
||||
<div>
|
||||
<h3 className="text-2xl font-bold text-white">{username}</h3>
|
||||
<p className="text-gray-400 text-sm">
|
||||
<p className="text-kodo-content-dim text-sm">
|
||||
Producer • Rank #{xpData.rank}
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -86,7 +86,7 @@ export const ProfileXPView: React.FC<ProfileXPViewProps> = ({ username }) => {
|
|||
<div className="text-2xl font-mono font-bold text-kodo-gold">
|
||||
{xpData.current} XP
|
||||
</div>
|
||||
<div className="text-xs text-gray-500">
|
||||
<div className="text-xs text-kodo-content-dim">
|
||||
Next Level: {xpData.next} XP
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -101,13 +101,13 @@ export const ProfileXPView: React.FC<ProfileXPViewProps> = ({ username }) => {
|
|||
/>
|
||||
|
||||
<div className="flex gap-4 pt-2">
|
||||
<div className="bg-black/30 px-3 py-1 rounded text-xs text-gray-400">
|
||||
<div className="bg-black/30 px-3 py-1 rounded text-xs text-kodo-content-dim">
|
||||
<span className="text-white font-bold">
|
||||
{xpData.totalEarned.toLocaleString()}
|
||||
</span>{' '}
|
||||
Total Lifetime XP
|
||||
</div>
|
||||
<div className="bg-black/30 px-3 py-1 rounded text-xs text-gray-400">
|
||||
<div className="bg-black/30 px-3 py-1 rounded text-xs text-kodo-content-dim">
|
||||
<span className="text-kodo-lime font-bold">+12%</span> vs Last
|
||||
Week
|
||||
</div>
|
||||
|
|
@ -123,7 +123,7 @@ export const ProfileXPView: React.FC<ProfileXPViewProps> = ({ username }) => {
|
|||
<Crown className="w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-xs text-gray-500 uppercase font-bold">
|
||||
<div className="text-xs text-kodo-content-dim uppercase font-bold">
|
||||
Global Rank
|
||||
</div>
|
||||
<div className="text-xl font-bold text-white">#{xpData.rank}</div>
|
||||
|
|
@ -134,7 +134,7 @@ export const ProfileXPView: React.FC<ProfileXPViewProps> = ({ username }) => {
|
|||
<Zap className="w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-xs text-gray-500 uppercase font-bold">
|
||||
<div className="text-xs text-kodo-content-dim uppercase font-bold">
|
||||
Daily Streak
|
||||
</div>
|
||||
<div className="text-xl font-bold text-white">12 Days</div>
|
||||
|
|
@ -145,7 +145,7 @@ export const ProfileXPView: React.FC<ProfileXPViewProps> = ({ username }) => {
|
|||
<Target className="w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-xs text-gray-500 uppercase font-bold">
|
||||
<div className="text-xs text-kodo-content-dim uppercase font-bold">
|
||||
Quests Complete
|
||||
</div>
|
||||
<div className="text-xl font-bold text-white">8/10</div>
|
||||
|
|
@ -189,7 +189,7 @@ export const ProfileXPView: React.FC<ProfileXPViewProps> = ({ username }) => {
|
|||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex justify-between text-xs text-gray-500 mt-2">
|
||||
<div className="flex justify-between text-xs text-kodo-content-dim mt-2">
|
||||
<span>14 Days Ago</span>
|
||||
<span>Today</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ export const XPBar: React.FC<XPBarProps> = ({
|
|||
className={`flex justify-between items-end mb-1 font-mono font-bold ${textClasses[size]}`}
|
||||
>
|
||||
<span className="text-kodo-gold">LVL {level}</span>
|
||||
<span className="text-gray-400">
|
||||
<span className="text-kodo-content-dim">
|
||||
<span className="text-white">{currentXP}</span> / {nextLevelXP} XP
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -64,7 +64,7 @@ export const XPBar: React.FC<XPBarProps> = ({
|
|||
</div>
|
||||
|
||||
{showLabels && size === 'lg' && (
|
||||
<div className="text-right text-[10px] text-gray-500 mt-1 font-mono">
|
||||
<div className="text-right text-[10px] text-kodo-content-dim mt-1 font-mono">
|
||||
{Math.round(nextLevelXP - currentXP)} XP to next level
|
||||
</div>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ export const AddEquipmentView: React.FC = () => {
|
|||
<h3 className="font-bold text-white mb-4 text-sm uppercase tracking-wider flex items-center gap-2">
|
||||
<Camera className="w-4 h-4 text-kodo-cyan" /> Photos
|
||||
</h3>
|
||||
<div className="aspect-square bg-kodo-ink border-2 border-dashed border-kodo-steel rounded-xl flex flex-col items-center justify-center text-gray-500 hover:text-white hover:border-kodo-cyan cursor-pointer transition-colors group mb-4">
|
||||
<div className="aspect-square bg-kodo-ink border-2 border-dashed border-kodo-steel rounded-xl flex flex-col items-center justify-center text-kodo-content-dim hover:text-white hover:border-kodo-cyan cursor-pointer transition-colors group mb-4">
|
||||
<Camera className="w-8 h-8 mb-2 group-hover:scale-110 transition-transform" />
|
||||
<span className="text-xs font-bold uppercase">Upload Photos</span>
|
||||
</div>
|
||||
|
|
@ -72,10 +72,10 @@ export const AddEquipmentView: React.FC = () => {
|
|||
|
||||
<Card variant="default">
|
||||
<h3 className="font-bold text-white mb-4 text-sm uppercase tracking-wider flex items-center gap-2">
|
||||
<FileText className="w-4 h-4 text-gray-400" /> Documents
|
||||
<FileText className="w-4 h-4 text-kodo-content-dim" /> Documents
|
||||
</h3>
|
||||
<FileUpload />
|
||||
<p className="text-xs text-gray-500 mt-2 text-center">
|
||||
<p className="text-xs text-kodo-content-dim mt-2 text-center">
|
||||
Receipts, Manuals, Warranty Cards
|
||||
</p>
|
||||
</Card>
|
||||
|
|
@ -89,7 +89,7 @@ export const AddEquipmentView: React.FC = () => {
|
|||
</h3>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-400 mb-2">
|
||||
<label className="block text-sm font-medium text-kodo-content-dim mb-2">
|
||||
Category
|
||||
</label>
|
||||
<select
|
||||
|
|
@ -159,7 +159,7 @@ export const AddEquipmentView: React.FC = () => {
|
|||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-400 mb-2">
|
||||
<label className="block text-sm font-medium text-kodo-content-dim mb-2">
|
||||
Location / Tags
|
||||
</label>
|
||||
<Input
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export const EquipmentCard: React.FC<EquipmentCardProps> = ({
|
|||
const statusColor = {
|
||||
Active: 'text-kodo-lime bg-kodo-lime/10',
|
||||
Maintenance: 'text-kodo-orange bg-kodo-orange/10',
|
||||
Sold: 'text-gray-400 bg-gray-500/10',
|
||||
Sold: 'text-kodo-content-dim bg-kodo-steel/10',
|
||||
Wishlist: 'text-kodo-magenta bg-kodo-magenta/10',
|
||||
};
|
||||
|
||||
|
|
@ -26,7 +26,7 @@ export const EquipmentCard: React.FC<EquipmentCardProps> = ({
|
|||
className="group p-0 overflow-hidden cursor-pointer hover:border-kodo-cyan/50 transition-all hover:shadow-lg flex flex-col h-full"
|
||||
onClick={() => onClick(item)}
|
||||
>
|
||||
<div className="relative aspect-square bg-gray-900 overflow-hidden">
|
||||
<div className="relative aspect-square bg-kodo-ink overflow-hidden">
|
||||
<img
|
||||
src={item.image || 'https://via.placeholder.com/400'}
|
||||
className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-110 opacity-90 group-hover:opacity-100"
|
||||
|
|
@ -53,7 +53,7 @@ export const EquipmentCard: React.FC<EquipmentCardProps> = ({
|
|||
</p>
|
||||
|
||||
<div className="mt-auto pt-3 border-t border-white/5 flex justify-between items-center text-xs">
|
||||
<div className="flex items-center gap-1 text-gray-400">
|
||||
<div className="flex items-center gap-1 text-kodo-content-dim">
|
||||
<Tag className="w-3 h-3" /> {item.condition}
|
||||
</div>
|
||||
<div className="flex items-center gap-1 font-mono text-white font-bold">
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ export const EquipmentDetailView: React.FC<EquipmentDetailViewProps> = ({
|
|||
);
|
||||
if (!item)
|
||||
return (
|
||||
<div className="text-center py-20 text-gray-500">Item not found</div>
|
||||
<div className="text-center py-20 text-kodo-content-dim">Item not found</div>
|
||||
);
|
||||
|
||||
const images =
|
||||
|
|
@ -80,7 +80,7 @@ export const EquipmentDetailView: React.FC<EquipmentDetailViewProps> = ({
|
|||
<Button
|
||||
variant="ghost"
|
||||
onClick={onBack}
|
||||
className="pl-0 text-gray-400 hover:text-white"
|
||||
className="pl-0 text-kodo-content-dim hover:text-white"
|
||||
>
|
||||
<ArrowLeft className="w-4 h-4 mr-2" /> Back to Inventory
|
||||
</Button>
|
||||
|
|
@ -124,7 +124,7 @@ export const EquipmentDetailView: React.FC<EquipmentDetailViewProps> = ({
|
|||
{images.map((_, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className={`w-2 h-2 rounded-full ${i === activeImgIndex ? 'bg-kodo-cyan' : 'bg-gray-600'}`}
|
||||
className={`w-2 h-2 rounded-full ${i === activeImgIndex ? 'bg-kodo-cyan' : 'bg-kodo-steel'}`}
|
||||
></div>
|
||||
))}
|
||||
</div>
|
||||
|
|
@ -140,14 +140,14 @@ export const EquipmentDetailView: React.FC<EquipmentDetailViewProps> = ({
|
|||
{item.specs ? (
|
||||
Object.entries(item.specs).map(([key, val]) => (
|
||||
<div key={key}>
|
||||
<span className="text-gray-500 block text-xs uppercase">
|
||||
<span className="text-kodo-content-dim block text-xs uppercase">
|
||||
{key}
|
||||
</span>
|
||||
<span className="text-white font-medium">{val}</span>
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
<p className="text-gray-500">No specs defined.</p>
|
||||
<p className="text-kodo-content-dim">No specs defined.</p>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
|
|
@ -159,7 +159,7 @@ export const EquipmentDetailView: React.FC<EquipmentDetailViewProps> = ({
|
|||
<div className="flex items-center gap-3 mb-2">
|
||||
<Badge label={item.category} variant="terminal" />
|
||||
<span
|
||||
className={`px-2 py-0.5 rounded text-[10px] font-bold uppercase ${item.status === 'Active' ? 'bg-kodo-lime/10 text-kodo-lime' : 'bg-gray-700 text-gray-300'}`}
|
||||
className={`px-2 py-0.5 rounded text-[10px] font-bold uppercase ${item.status === 'Active' ? 'bg-kodo-lime/10 text-kodo-lime' : 'bg-kodo-steel text-kodo-text-main'}`}
|
||||
>
|
||||
{item.status}
|
||||
</span>
|
||||
|
|
@ -171,21 +171,21 @@ export const EquipmentDetailView: React.FC<EquipmentDetailViewProps> = ({
|
|||
{item.brand} {item.model}
|
||||
</p>
|
||||
|
||||
<div className="flex gap-6 text-sm text-gray-400 mb-6 font-mono bg-kodo-ink p-4 rounded-lg border border-kodo-steel/50">
|
||||
<div className="flex gap-6 text-sm text-kodo-content-dim mb-6 font-mono bg-kodo-ink p-4 rounded-lg border border-kodo-steel/50">
|
||||
<div className="flex flex-col">
|
||||
<span className="text-[10px] uppercase font-bold text-gray-500">
|
||||
<span className="text-[10px] uppercase font-bold text-kodo-content-dim">
|
||||
Serial
|
||||
</span>
|
||||
<span className="text-white">{item.serialNumber}</span>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<span className="text-[10px] uppercase font-bold text-gray-500">
|
||||
<span className="text-[10px] uppercase font-bold text-kodo-content-dim">
|
||||
Purchased
|
||||
</span>
|
||||
<span className="text-white">{item.purchaseDate}</span>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<span className="text-[10px] uppercase font-bold text-gray-500">
|
||||
<span className="text-[10px] uppercase font-bold text-kodo-content-dim">
|
||||
Value
|
||||
</span>
|
||||
<span className="text-kodo-cyan font-bold">
|
||||
|
|
@ -196,13 +196,13 @@ export const EquipmentDetailView: React.FC<EquipmentDetailViewProps> = ({
|
|||
</div>
|
||||
|
||||
<Card variant="gaming">
|
||||
<h3 className="font-bold text-white mb-4 border-b border-gray-700 pb-2 flex items-center gap-2">
|
||||
<h3 className="font-bold text-white mb-4 border-b border-kodo-steel pb-2 flex items-center gap-2">
|
||||
<ShieldCheck className="w-4 h-4 text-kodo-lime" /> Warranty &
|
||||
Support
|
||||
</h3>
|
||||
<div className="flex justify-between items-center mb-4 p-3 bg-kodo-ink rounded border border-kodo-steel/30">
|
||||
<div>
|
||||
<span className="block text-xs text-gray-500 uppercase">
|
||||
<span className="block text-xs text-kodo-content-dim uppercase">
|
||||
Expires
|
||||
</span>
|
||||
<span className="font-bold text-white">
|
||||
|
|
@ -213,7 +213,7 @@ export const EquipmentDetailView: React.FC<EquipmentDetailViewProps> = ({
|
|||
</div>
|
||||
{item.supportContact && (
|
||||
<div className="text-sm">
|
||||
<span className="text-gray-500">Support: </span>
|
||||
<span className="text-kodo-content-dim">Support: </span>
|
||||
<a
|
||||
href={`mailto:${item.supportContact}`}
|
||||
className="text-kodo-cyan hover:underline"
|
||||
|
|
@ -226,7 +226,7 @@ export const EquipmentDetailView: React.FC<EquipmentDetailViewProps> = ({
|
|||
|
||||
<Card variant="default">
|
||||
<h3 className="font-bold text-white mb-4 border-b border-kodo-steel pb-2 flex items-center gap-2">
|
||||
<FileText className="w-4 h-4 text-gray-400" /> Documentation
|
||||
<FileText className="w-4 h-4 text-kodo-content-dim" /> Documentation
|
||||
</h3>
|
||||
<div className="space-y-2">
|
||||
{item.documents?.map((doc, i) => (
|
||||
|
|
@ -236,12 +236,12 @@ export const EquipmentDetailView: React.FC<EquipmentDetailViewProps> = ({
|
|||
>
|
||||
<div className="flex items-center gap-3">
|
||||
<FileText className="w-4 h-4 text-kodo-cyan" />
|
||||
<span className="text-sm text-gray-300">{doc.name}</span>
|
||||
<span className="text-sm text-kodo-text-main">{doc.name}</span>
|
||||
</div>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-8 w-8 text-gray-500 hover:text-white"
|
||||
className="h-8 w-8 text-kodo-content-dim hover:text-white"
|
||||
>
|
||||
<Download className="w-4 h-4" />
|
||||
</Button>
|
||||
|
|
@ -265,9 +265,9 @@ export const EquipmentDetailView: React.FC<EquipmentDetailViewProps> = ({
|
|||
<span className="font-bold text-white text-sm">
|
||||
{log.type}
|
||||
</span>
|
||||
<span className="text-xs text-gray-500">{log.date}</span>
|
||||
<span className="text-xs text-kodo-content-dim">{log.date}</span>
|
||||
</div>
|
||||
<p className="text-xs text-gray-400 mt-1">{log.notes}</p>
|
||||
<p className="text-xs text-kodo-content-dim mt-1">{log.notes}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ export const InventoryView: React.FC<InventoryViewProps> = ({ onNavigate }) => {
|
|||
<h2 className="text-2xl font-display font-bold text-white mb-2">
|
||||
GEAR INVENTORY
|
||||
</h2>
|
||||
<p className="text-gray-400 font-mono text-sm">
|
||||
<p className="text-kodo-content-dim font-mono text-sm">
|
||||
Track hardware, warranties, and maintenance.
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -90,9 +90,9 @@ export const InventoryView: React.FC<InventoryViewProps> = ({ onNavigate }) => {
|
|||
|
||||
<div className="flex flex-wrap gap-2 w-full md:w-auto">
|
||||
<div className="flex items-center gap-2 bg-kodo-void rounded-lg p-1 border border-kodo-steel">
|
||||
<Filter className="w-4 h-4 text-gray-500 ml-2" />
|
||||
<Filter className="w-4 h-4 text-kodo-content-dim ml-2" />
|
||||
<select
|
||||
className="bg-transparent text-sm text-gray-300 focus:outline-none p-1 cursor-pointer"
|
||||
className="bg-transparent text-sm text-kodo-text-main focus:outline-none p-1 cursor-pointer"
|
||||
value={filterCat}
|
||||
onChange={(e) => setFilterCat(e.target.value)}
|
||||
>
|
||||
|
|
@ -105,9 +105,9 @@ export const InventoryView: React.FC<InventoryViewProps> = ({ onNavigate }) => {
|
|||
</div>
|
||||
|
||||
<div className="flex items-center gap-2 bg-kodo-void rounded-lg p-1 border border-kodo-steel">
|
||||
<Box className="w-4 h-4 text-gray-500 ml-2" />
|
||||
<Box className="w-4 h-4 text-kodo-content-dim ml-2" />
|
||||
<select
|
||||
className="bg-transparent text-sm text-gray-300 focus:outline-none p-1 cursor-pointer"
|
||||
className="bg-transparent text-sm text-kodo-text-main focus:outline-none p-1 cursor-pointer"
|
||||
value={filterStatus}
|
||||
onChange={(e) => setFilterStatus(e.target.value)}
|
||||
>
|
||||
|
|
@ -136,7 +136,7 @@ export const InventoryView: React.FC<InventoryViewProps> = ({ onNavigate }) => {
|
|||
/>
|
||||
))}
|
||||
{filteredItems.length === 0 && (
|
||||
<div className="col-span-full text-center py-20 text-gray-500">
|
||||
<div className="col-span-full text-center py-20 text-kodo-content-dim">
|
||||
<Box className="w-12 h-12 mx-auto mb-4 opacity-50" />
|
||||
<p>No equipment found.</p>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -77,12 +77,12 @@ export function KeyboardShortcutsHelp({
|
|||
{shortcuts.map((shortcut, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="flex items-center justify-between border-b border-gray-200 dark:border-gray-700 pb-2 last:border-0"
|
||||
className="flex items-center justify-between border-b border-kodo-steel dark:border-kodo-steel pb-2 last:border-0"
|
||||
>
|
||||
<span className="text-sm text-gray-600 dark:text-gray-400">
|
||||
<span className="text-sm text-kodo-content-dim dark:text-kodo-content-dim">
|
||||
{shortcut.description}
|
||||
</span>
|
||||
<kbd className="px-2 py-1 text-xs font-semibold text-gray-800 dark:text-gray-200 bg-gray-100 dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded">
|
||||
<kbd className="px-2 py-1 text-xs font-semibold text-kodo-text-main dark:text-kodo-text-main bg-kodo-void dark:bg-kodo-graphite border border-kodo-steel dark:border-kodo-steel rounded">
|
||||
{shortcut.key}
|
||||
</kbd>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ export const AudioPlayer: React.FC = () => {
|
|||
<ListMusic className="w-4 h-4 text-kodo-cyan" /> PLAY QUEUE
|
||||
</h3>
|
||||
<X
|
||||
className="w-5 h-5 text-gray-400 cursor-pointer hover:text-white"
|
||||
className="w-5 h-5 text-kodo-content-dim cursor-pointer hover:text-white"
|
||||
onClick={() => setShowQueue(false)}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -77,13 +77,13 @@ export const AudioPlayer: React.FC = () => {
|
|||
<div className="flex-1 flex flex-col min-h-0">
|
||||
<div className="flex border-b border-kodo-steel bg-kodo-slate/30">
|
||||
<button
|
||||
className={`flex-1 py-3 text-xs font-bold uppercase tracking-wider transition-colors ${queueTab === 'up-next' ? 'text-kodo-cyan border-b-2 border-kodo-cyan bg-white/5' : 'text-gray-500 hover:text-white'}`}
|
||||
className={`flex-1 py-3 text-xs font-bold uppercase tracking-wider transition-colors ${queueTab === 'up-next' ? 'text-kodo-cyan border-b-2 border-kodo-cyan bg-white/5' : 'text-kodo-content-dim hover:text-white'}`}
|
||||
onClick={() => setQueueTab('up-next')}
|
||||
>
|
||||
Up Next ({queue.length})
|
||||
</button>
|
||||
<button
|
||||
className={`flex-1 py-3 text-xs font-bold uppercase tracking-wider transition-colors ${queueTab === 'history' ? 'text-kodo-magenta border-b-2 border-kodo-magenta bg-white/5' : 'text-gray-500 hover:text-white'}`}
|
||||
className={`flex-1 py-3 text-xs font-bold uppercase tracking-wider transition-colors ${queueTab === 'history' ? 'text-kodo-magenta border-b-2 border-kodo-magenta bg-white/5' : 'text-kodo-content-dim hover:text-white'}`}
|
||||
onClick={() => setQueueTab('history')}
|
||||
>
|
||||
History
|
||||
|
|
@ -107,12 +107,12 @@ export const AudioPlayer: React.FC = () => {
|
|||
<div className="text-sm font-bold text-white truncate">
|
||||
{currentTrack.title}
|
||||
</div>
|
||||
<div className="text-xs text-gray-400 truncate">
|
||||
<div className="text-xs text-kodo-content-dim truncate">
|
||||
{currentTrack.artist}
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="p-2 hover:bg-white/10 rounded-full text-gray-400 hover:text-kodo-magenta"
|
||||
className="p-2 hover:bg-white/10 rounded-full text-kodo-content-dim hover:text-kodo-magenta"
|
||||
onClick={() => addToast('Saved to Library', 'success')}
|
||||
>
|
||||
<Heart className="w-4 h-4" />
|
||||
|
|
@ -122,7 +122,7 @@ export const AudioPlayer: React.FC = () => {
|
|||
|
||||
<div className="p-2 space-y-1">
|
||||
{queue.length === 0 && (
|
||||
<div className="text-center text-gray-500 py-12 flex flex-col items-center">
|
||||
<div className="text-center text-kodo-content-dim py-12 flex flex-col items-center">
|
||||
<ListMusic className="w-8 h-8 mb-2 opacity-50" />
|
||||
<p className="text-sm italic">Queue is empty</p>
|
||||
</div>
|
||||
|
|
@ -137,7 +137,7 @@ export const AudioPlayer: React.FC = () => {
|
|||
onDragEnd={onDragEnd}
|
||||
className={`flex items-center gap-3 p-2 rounded-lg group transition-colors border border-transparent ${draggedItemIndex === i ? 'bg-kodo-cyan/10 border-kodo-cyan/50' : 'hover:bg-white/5 hover:border-white/5'}`}
|
||||
>
|
||||
<div className="cursor-grab active:cursor-grabbing text-gray-600 hover:text-white p-1">
|
||||
<div className="cursor-grab active:cursor-grabbing text-kodo-content-dim hover:text-white p-1">
|
||||
<GripVertical className="w-4 h-4" />
|
||||
</div>
|
||||
<div className="relative w-8 h-8 rounded overflow-hidden flex-shrink-0">
|
||||
|
|
@ -154,10 +154,10 @@ export const AudioPlayer: React.FC = () => {
|
|||
</div>
|
||||
</div>
|
||||
<div className="flex-1 min-w-0 select-none">
|
||||
<div className="text-sm font-medium text-gray-300 group-hover:text-white truncate">
|
||||
<div className="text-sm font-medium text-kodo-text-main group-hover:text-white truncate">
|
||||
{track.title}
|
||||
</div>
|
||||
<div className="text-xs text-gray-500 truncate">
|
||||
<div className="text-xs text-kodo-content-dim truncate">
|
||||
{track.artist}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -175,7 +175,7 @@ export const AudioPlayer: React.FC = () => {
|
|||
<ArrowUpToLine className="w-3.5 h-3.5" />
|
||||
</button>
|
||||
<button
|
||||
className="p-1.5 hover:text-red-500"
|
||||
className="p-1.5 hover:text-kodo-red"
|
||||
title="Remove"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
|
|
@ -194,7 +194,7 @@ export const AudioPlayer: React.FC = () => {
|
|||
{queueTab === 'history' && (
|
||||
<div className="p-2 space-y-1">
|
||||
{history.length === 0 && (
|
||||
<div className="text-center text-gray-500 py-12 flex flex-col items-center">
|
||||
<div className="text-center text-kodo-content-dim py-12 flex flex-col items-center">
|
||||
<Clock className="w-8 h-8 mb-2 opacity-50" />
|
||||
<p className="text-sm italic">No history yet</p>
|
||||
</div>
|
||||
|
|
@ -212,15 +212,15 @@ export const AudioPlayer: React.FC = () => {
|
|||
/>
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="text-sm font-medium text-gray-300 group-hover:text-white truncate">
|
||||
<div className="text-sm font-medium text-kodo-text-main group-hover:text-white truncate">
|
||||
{track.title}
|
||||
</div>
|
||||
<div className="text-xs text-gray-500 truncate">
|
||||
<div className="text-xs text-kodo-content-dim truncate">
|
||||
{track.artist}
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="p-1.5 text-gray-400 hover:text-kodo-cyan opacity-0 group-hover:opacity-100 transition-opacity"
|
||||
className="p-1.5 text-kodo-content-dim hover:text-kodo-cyan opacity-0 group-hover:opacity-100 transition-opacity"
|
||||
onClick={() => {
|
||||
addToQueue(track);
|
||||
addToast('Added back to Queue');
|
||||
|
|
@ -239,7 +239,7 @@ export const AudioPlayer: React.FC = () => {
|
|||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="w-full text-xs text-gray-400 hover:text-red-400"
|
||||
className="w-full text-xs text-kodo-content-dim hover:text-kodo-red"
|
||||
onClick={() => {
|
||||
clearQueue();
|
||||
addToast('Queue Cleared');
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ export function Header(_props: HeaderProps) {
|
|||
<div className="h-px bg-white/5 my-2 mx-2" />
|
||||
<button
|
||||
onClick={handleLogout}
|
||||
className="flex items-center gap-3 w-full px-3 py-2 text-sm text-red-400/80 hover:text-red-400 hover:bg-red-500/10 rounded-xl transition-all group cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-red-400 focus-visible:ring-offset-2 focus-visible:ring-offset-kodo-void"
|
||||
className="flex items-center gap-3 w-full px-3 py-2 text-sm text-kodo-red/80 hover:text-kodo-red hover:bg-kodo-red/10 rounded-xl transition-all group cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-red-400 focus-visible:ring-offset-2 focus-visible:ring-offset-kodo-void"
|
||||
>
|
||||
<LogOut className="w-4 h-4" />
|
||||
<span>Terminate.Session</span>
|
||||
|
|
|
|||
|
|
@ -321,7 +321,7 @@ export const Sidebar: React.FC<SidebarProps> = ({
|
|||
</Link>
|
||||
<button
|
||||
onClick={handleLogout}
|
||||
className="w-full flex items-center gap-3 px-4 py-2.5 text-red-400/80 hover:text-red-400 hover:bg-red-500/10 rounded-xl transition-all text-sm mt-1 cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-red-400 focus-visible:ring-offset-2 focus-visible:ring-offset-kodo-void"
|
||||
className="w-full flex items-center gap-3 px-4 py-2.5 text-kodo-red/80 hover:text-kodo-red hover:bg-kodo-red/10 rounded-xl transition-all text-sm mt-1 cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-red-400 focus-visible:ring-offset-2 focus-visible:ring-offset-kodo-void"
|
||||
>
|
||||
<LogOut className="w-4 h-4" />
|
||||
{sidebarOpen && (
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ export const AutoMetadataDetectionModal: React.FC<
|
|||
<Wand2 className="w-4 h-4 text-kodo-cyan" /> AI Metadata Detection
|
||||
</h3>
|
||||
<button onClick={onClose}>
|
||||
<X className="w-5 h-5 text-gray-400 hover:text-white" />
|
||||
<X className="w-5 h-5 text-kodo-content-dim hover:text-white" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
|
@ -66,7 +66,7 @@ export const AutoMetadataDetectionModal: React.FC<
|
|||
<h4 className="text-lg font-bold text-white animate-pulse">
|
||||
Analyzing Audio...
|
||||
</h4>
|
||||
<p className="text-sm text-gray-400 mt-2">
|
||||
<p className="text-sm text-kodo-content-dim mt-2">
|
||||
Detecting BPM, Key, and Genre for <br />
|
||||
<span className="text-kodo-cyan">{fileName}</span>
|
||||
</p>
|
||||
|
|
@ -77,7 +77,7 @@ export const AutoMetadataDetectionModal: React.FC<
|
|||
<div className="bg-kodo-ink border border-kodo-cyan/20 rounded-lg p-6 w-full">
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="text-center p-2">
|
||||
<div className="text-xs text-gray-500 uppercase font-bold mb-1">
|
||||
<div className="text-xs text-kodo-content-dim uppercase font-bold mb-1">
|
||||
Detected BPM
|
||||
</div>
|
||||
<div className="text-2xl font-bold text-white">
|
||||
|
|
@ -85,7 +85,7 @@ export const AutoMetadataDetectionModal: React.FC<
|
|||
</div>
|
||||
</div>
|
||||
<div className="text-center p-2">
|
||||
<div className="text-xs text-gray-500 uppercase font-bold mb-1">
|
||||
<div className="text-xs text-kodo-content-dim uppercase font-bold mb-1">
|
||||
Detected Key
|
||||
</div>
|
||||
<div className="text-2xl font-bold text-kodo-cyan">
|
||||
|
|
@ -93,7 +93,7 @@ export const AutoMetadataDetectionModal: React.FC<
|
|||
</div>
|
||||
</div>
|
||||
<div className="text-center p-2">
|
||||
<div className="text-xs text-gray-500 uppercase font-bold mb-1">
|
||||
<div className="text-xs text-kodo-content-dim uppercase font-bold mb-1">
|
||||
Genre
|
||||
</div>
|
||||
<div className="text-lg font-medium text-white">
|
||||
|
|
@ -101,7 +101,7 @@ export const AutoMetadataDetectionModal: React.FC<
|
|||
</div>
|
||||
</div>
|
||||
<div className="text-center p-2">
|
||||
<div className="text-xs text-gray-500 uppercase font-bold mb-1">
|
||||
<div className="text-xs text-kodo-content-dim uppercase font-bold mb-1">
|
||||
Energy Level
|
||||
</div>
|
||||
<div className="text-lg font-medium text-kodo-gold">
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ export const WatermarkSettingsModal: React.FC<WatermarkSettingsModalProps> = ({
|
|||
</span>
|
||||
<div
|
||||
onClick={() => setEnabled(!enabled)}
|
||||
className={`w-10 h-5 rounded-full relative transition-colors ${enabled ? 'bg-kodo-magenta' : 'bg-gray-600'}`}
|
||||
className={`w-10 h-5 rounded-full relative transition-colors ${enabled ? 'bg-kodo-magenta' : 'bg-kodo-steel'}`}
|
||||
>
|
||||
<div
|
||||
className={`absolute top-1 w-3 h-3 bg-white rounded-full transition-all ${enabled ? 'left-6' : 'left-1'}`}
|
||||
|
|
@ -69,7 +69,7 @@ export const WatermarkSettingsModal: React.FC<WatermarkSettingsModalProps> = ({
|
|||
/>
|
||||
|
||||
<div className="mt-4">
|
||||
<label className="block text-xs font-bold text-gray-400 uppercase mb-2">
|
||||
<label className="block text-xs font-bold text-kodo-content-dim uppercase mb-2">
|
||||
Position
|
||||
</label>
|
||||
<div className="grid grid-cols-3 gap-2">
|
||||
|
|
@ -77,11 +77,11 @@ export const WatermarkSettingsModal: React.FC<WatermarkSettingsModalProps> = ({
|
|||
<button
|
||||
key={i}
|
||||
onClick={() => setPosition(i)}
|
||||
className={`h-10 rounded border text-[10px] uppercase font-bold transition-all ${position === i ? 'bg-kodo-magenta border-kodo-magenta text-white' : 'bg-kodo-void border-kodo-steel text-gray-500 hover:border-gray-400'}`}
|
||||
className={`h-10 rounded border text-[10px] uppercase font-bold transition-all ${position === i ? 'bg-kodo-magenta border-kodo-magenta text-white' : 'bg-kodo-void border-kodo-steel text-kodo-content-dim hover:border-kodo-steel'}`}
|
||||
>
|
||||
{/* Icon representation usually better, but text works for demo */}
|
||||
<div
|
||||
className={`w-2 h-2 rounded-full mx-auto ${position === i ? 'bg-white' : 'bg-gray-600'}`}
|
||||
className={`w-2 h-2 rounded-full mx-auto ${position === i ? 'bg-white' : 'bg-kodo-steel'}`}
|
||||
></div>
|
||||
</button>
|
||||
))}
|
||||
|
|
@ -89,7 +89,7 @@ export const WatermarkSettingsModal: React.FC<WatermarkSettingsModalProps> = ({
|
|||
</div>
|
||||
|
||||
<div className="mt-4">
|
||||
<div className="flex justify-between text-xs text-gray-400 mb-2">
|
||||
<div className="flex justify-between text-xs text-kodo-content-dim mb-2">
|
||||
<span className="font-bold uppercase">Opacity</span>
|
||||
<span>{opacity}%</span>
|
||||
</div>
|
||||
|
|
@ -129,7 +129,7 @@ export const WatermarkSettingsModal: React.FC<WatermarkSettingsModalProps> = ({
|
|||
</div>
|
||||
|
||||
{/* Dummy Content */}
|
||||
<div className="w-3/4 aspect-square bg-gray-800 rounded-lg relative overflow-hidden shadow-2xl">
|
||||
<div className="w-3/4 aspect-square bg-kodo-graphite rounded-lg relative overflow-hidden shadow-2xl">
|
||||
<img
|
||||
src="https://picsum.photos/id/237/600/600"
|
||||
className="w-full h-full object-cover opacity-80"
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ export const AddToPlaylistModal: React.FC<AddToPlaylistModalProps> = ({
|
|||
<div className="p-4 border-b border-kodo-steel bg-kodo-ink flex justify-between items-center">
|
||||
<h3 className="font-bold text-white">Add to Playlist</h3>
|
||||
<button onClick={onClose}>
|
||||
<X className="w-5 h-5 text-gray-400 hover:text-white" />
|
||||
<X className="w-5 h-5 text-kodo-content-dim hover:text-white" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ export const AddToPlaylistModal: React.FC<AddToPlaylistModalProps> = ({
|
|||
onChange={(e) => setSearch(e.target.value)}
|
||||
autoFocus
|
||||
/>
|
||||
<Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-500" />
|
||||
<Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-kodo-content-dim" />
|
||||
</div>
|
||||
|
||||
<Button
|
||||
|
|
@ -123,12 +123,12 @@ export const AddToPlaylistModal: React.FC<AddToPlaylistModalProps> = ({
|
|||
>
|
||||
{playlist.title}
|
||||
</div>
|
||||
<div className="text-xs text-gray-500">
|
||||
<div className="text-xs text-kodo-content-dim">
|
||||
{playlist.track_count} tracks
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={`w-5 h-5 rounded-full border flex items-center justify-center ${selectedIds.includes(playlist.id) ? 'bg-kodo-cyan border-kodo-cyan' : 'border-gray-600'}`}
|
||||
className={`w-5 h-5 rounded-full border flex items-center justify-center ${selectedIds.includes(playlist.id) ? 'bg-kodo-cyan border-kodo-cyan' : 'border-kodo-steel'}`}
|
||||
>
|
||||
{selectedIds.includes(playlist.id) && (
|
||||
<Check className="w-3 h-3 text-black" />
|
||||
|
|
|
|||
|
|
@ -38,12 +38,12 @@ export const CreatePlaylistModal: React.FC<CreatePlaylistModalProps> = ({
|
|||
<div className="p-4 border-b border-kodo-steel bg-kodo-ink flex justify-between items-center">
|
||||
<h3 className="font-bold text-white">Create Playlist</h3>
|
||||
<button onClick={onClose}>
|
||||
<X className="w-5 h-5 text-gray-400 hover:text-white" />
|
||||
<X className="w-5 h-5 text-kodo-content-dim hover:text-white" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="p-6 flex flex-col md:flex-row gap-6">
|
||||
<div className="w-40 h-40 bg-kodo-ink border-2 border-dashed border-kodo-steel rounded-lg flex flex-col items-center justify-center text-gray-500 hover:text-white hover:border-kodo-cyan cursor-pointer transition-colors flex-shrink-0">
|
||||
<div className="w-40 h-40 bg-kodo-ink border-2 border-dashed border-kodo-steel rounded-lg flex flex-col items-center justify-center text-kodo-content-dim hover:text-white hover:border-kodo-cyan cursor-pointer transition-colors flex-shrink-0">
|
||||
<ImageIcon className="w-8 h-8 mb-2" />
|
||||
<span className="text-xs font-bold uppercase">Cover</span>
|
||||
</div>
|
||||
|
|
@ -78,7 +78,7 @@ export const CreatePlaylistModal: React.FC<CreatePlaylistModalProps> = ({
|
|||
<div className="text-white font-bold">
|
||||
{isPublic ? 'Public' : 'Private'}
|
||||
</div>
|
||||
<div className="text-xs text-gray-400">
|
||||
<div className="text-xs text-kodo-content-dim">
|
||||
{isPublic
|
||||
? 'Visible to everyone'
|
||||
: 'Only you can see this'}
|
||||
|
|
@ -86,7 +86,7 @@ export const CreatePlaylistModal: React.FC<CreatePlaylistModalProps> = ({
|
|||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={`w-8 h-4 rounded-full relative transition-colors ${isPublic ? 'bg-kodo-cyan' : 'bg-gray-600'}`}
|
||||
className={`w-8 h-4 rounded-full relative transition-colors ${isPublic ? 'bg-kodo-cyan' : 'bg-kodo-steel'}`}
|
||||
>
|
||||
<div
|
||||
className={`absolute top-0.5 w-3 h-3 bg-white rounded-full transition-all ${isPublic ? 'left-4.5' : 'left-0.5'}`}
|
||||
|
|
@ -100,17 +100,17 @@ export const CreatePlaylistModal: React.FC<CreatePlaylistModalProps> = ({
|
|||
>
|
||||
<div className="flex items-center gap-3">
|
||||
<Users
|
||||
className={`w-4 h-4 ${isCollaborative ? 'text-kodo-lime' : 'text-gray-400'}`}
|
||||
className={`w-4 h-4 ${isCollaborative ? 'text-kodo-lime' : 'text-kodo-content-dim'}`}
|
||||
/>
|
||||
<div className="text-sm">
|
||||
<div className="text-white font-bold">Collaborative</div>
|
||||
<div className="text-xs text-gray-400">
|
||||
<div className="text-xs text-kodo-content-dim">
|
||||
Friends can add tracks
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={`w-8 h-4 rounded-full relative transition-colors ${isCollaborative ? 'bg-kodo-lime' : 'bg-gray-600'}`}
|
||||
className={`w-8 h-4 rounded-full relative transition-colors ${isCollaborative ? 'bg-kodo-lime' : 'bg-kodo-steel'}`}
|
||||
>
|
||||
<div
|
||||
className={`absolute top-0.5 w-3 h-3 bg-white rounded-full transition-all ${isCollaborative ? 'left-4.5' : 'left-0.5'}`}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ export const EditPlaylistModal: React.FC<EditPlaylistModalProps> = ({
|
|||
<h3 className="text-xl font-bold text-white mb-2">
|
||||
Delete "{playlist.title}"?
|
||||
</h3>
|
||||
<p className="text-sm text-gray-400 mb-6">
|
||||
<p className="text-sm text-kodo-content-dim mb-6">
|
||||
This action cannot be undone.
|
||||
</p>
|
||||
<div className="flex gap-3 justify-center">
|
||||
|
|
@ -59,7 +59,7 @@ export const EditPlaylistModal: React.FC<EditPlaylistModalProps> = ({
|
|||
</Button>
|
||||
<Button
|
||||
variant="primary"
|
||||
className="bg-red-600 hover:bg-red-700 border-red-500"
|
||||
className="bg-kodo-red hover:bg-kodo-red border-kodo-red"
|
||||
onClick={handleDelete}
|
||||
>
|
||||
Delete
|
||||
|
|
@ -80,7 +80,7 @@ export const EditPlaylistModal: React.FC<EditPlaylistModalProps> = ({
|
|||
<div className="p-4 border-b border-kodo-steel bg-kodo-ink flex justify-between items-center">
|
||||
<h3 className="font-bold text-white">Edit Details</h3>
|
||||
<button onClick={onClose}>
|
||||
<X className="w-5 h-5 text-gray-400 hover:text-white" />
|
||||
<X className="w-5 h-5 text-kodo-content-dim hover:text-white" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
|
@ -127,7 +127,7 @@ export const EditPlaylistModal: React.FC<EditPlaylistModalProps> = ({
|
|||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={`w-8 h-4 rounded-full relative transition-colors ${isPublic ? 'bg-kodo-cyan' : 'bg-gray-600'}`}
|
||||
className={`w-8 h-4 rounded-full relative transition-colors ${isPublic ? 'bg-kodo-cyan' : 'bg-kodo-steel'}`}
|
||||
>
|
||||
<div
|
||||
className={`absolute top-0.5 w-3 h-3 bg-white rounded-full transition-all ${isPublic ? 'left-4.5' : 'left-0.5'}`}
|
||||
|
|
|
|||
|
|
@ -118,20 +118,20 @@ export const PlaylistDetailView: React.FC<PlaylistDetailViewProps> = ({
|
|||
<h1 className="text-4xl md:text-6xl font-display font-bold text-white mb-4 leading-tight">
|
||||
{playlist.title}
|
||||
</h1>
|
||||
<p className="text-gray-400 text-sm mb-6 max-w-2xl">
|
||||
<p className="text-kodo-content-dim text-sm mb-6 max-w-2xl">
|
||||
{playlist.description}
|
||||
</p>
|
||||
|
||||
<div className="flex items-center gap-4 text-sm text-gray-300 font-medium mb-6">
|
||||
<div className="flex items-center gap-4 text-sm text-kodo-text-main font-medium mb-6">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-6 h-6 rounded-full bg-gray-700"></div>
|
||||
<div className="w-6 h-6 rounded-full bg-kodo-steel"></div>
|
||||
<span className="text-white hover:underline cursor-pointer">
|
||||
{playlist.creator}
|
||||
</span>
|
||||
</div>
|
||||
<span className="w-1 h-1 bg-gray-500 rounded-full"></span>
|
||||
<span className="w-1 h-1 bg-kodo-steel rounded-full"></span>
|
||||
<span>{playlist.likes} likes</span>
|
||||
<span className="w-1 h-1 bg-gray-500 rounded-full"></span>
|
||||
<span className="w-1 h-1 bg-kodo-steel rounded-full"></span>
|
||||
<span>
|
||||
{tracks.length} songs, {playlist.duration}
|
||||
</span>
|
||||
|
|
@ -157,7 +157,7 @@ export const PlaylistDetailView: React.FC<PlaylistDetailViewProps> = ({
|
|||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="border border-white/10 hover:border-white text-gray-300 hover:text-white"
|
||||
className="border border-white/10 hover:border-white text-kodo-text-main hover:text-white"
|
||||
onClick={() => addToast('Saved to Library')}
|
||||
aria-label="Ajouter à la bibliothèque"
|
||||
>
|
||||
|
|
@ -166,7 +166,7 @@ export const PlaylistDetailView: React.FC<PlaylistDetailViewProps> = ({
|
|||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="border border-white/10 hover:border-white text-gray-300 hover:text-white"
|
||||
className="border border-white/10 hover:border-white text-kodo-text-main hover:text-white"
|
||||
onClick={() => setIsEditing(true)}
|
||||
aria-label="Plus d'options"
|
||||
>
|
||||
|
|
@ -178,7 +178,7 @@ export const PlaylistDetailView: React.FC<PlaylistDetailViewProps> = ({
|
|||
|
||||
{/* Tracks List */}
|
||||
<div className="px-2">
|
||||
<div className="grid grid-cols-[auto_1fr_auto_auto_auto] gap-4 text-xs font-bold text-gray-500 uppercase px-4 pb-2 border-b border-white/10 mb-2">
|
||||
<div className="grid grid-cols-[auto_1fr_auto_auto_auto] gap-4 text-xs font-bold text-kodo-content-dim uppercase px-4 pb-2 border-b border-white/10 mb-2">
|
||||
<div className="w-8 text-center">#</div>
|
||||
<div>Title</div>
|
||||
<div className="hidden md:block">Album</div>
|
||||
|
|
@ -198,7 +198,7 @@ export const PlaylistDetailView: React.FC<PlaylistDetailViewProps> = ({
|
|||
onDragEnd={() => setDraggedIndex(null)}
|
||||
className={`grid grid-cols-[auto_1fr_auto_auto_auto] gap-4 items-center p-2 rounded-lg hover:bg-white/5 group transition-colors ${draggedIndex === i ? 'bg-kodo-cyan/10' : ''}`}
|
||||
>
|
||||
<div className="w-8 text-center flex justify-center text-gray-500 group-hover:text-white cursor-grab active:cursor-grabbing">
|
||||
<div className="w-8 text-center flex justify-center text-kodo-content-dim group-hover:text-white cursor-grab active:cursor-grabbing">
|
||||
<span className="group-hover:hidden">{i + 1}</span>
|
||||
<Play
|
||||
className="w-4 h-4 fill-current hidden group-hover:block cursor-pointer"
|
||||
|
|
@ -214,18 +214,18 @@ export const PlaylistDetailView: React.FC<PlaylistDetailViewProps> = ({
|
|||
<div className="text-white font-bold text-sm truncate">
|
||||
{track.title}
|
||||
</div>
|
||||
<div className="text-gray-400 text-xs truncate hover:underline cursor-pointer">
|
||||
<div className="text-kodo-content-dim text-xs truncate hover:underline cursor-pointer">
|
||||
{track.artist}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="hidden md:block text-gray-400 text-sm truncate">
|
||||
<div className="hidden md:block text-kodo-content-dim text-sm truncate">
|
||||
{track.album}
|
||||
</div>
|
||||
<div className="hidden sm:block text-gray-500 text-xs">
|
||||
<div className="hidden sm:block text-kodo-content-dim text-xs">
|
||||
2 days ago
|
||||
</div>
|
||||
<div className="text-right pr-2 flex items-center justify-end gap-4 text-sm text-gray-400 font-mono">
|
||||
<div className="text-right pr-2 flex items-center justify-end gap-4 text-sm text-kodo-content-dim font-mono">
|
||||
<Heart className="w-4 h-4 opacity-0 group-hover:opacity-100 hover:text-kodo-magenta cursor-pointer transition-all" />
|
||||
<span>{track.duration}</span>
|
||||
<MoreHorizontal className="w-4 h-4 opacity-0 group-hover:opacity-100 hover:text-white cursor-pointer" />
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ export const PlaylistsView: React.FC<{
|
|||
<h1 className="text-3xl font-display font-bold text-white mb-2">
|
||||
MY PLAYLISTS
|
||||
</h1>
|
||||
<p className="text-gray-400 font-mono text-sm">
|
||||
<p className="text-kodo-content-dim font-mono text-sm">
|
||||
Curate your sonic collection.
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -128,14 +128,14 @@ export const PlaylistsView: React.FC<{
|
|||
className="p-0 overflow-hidden group cursor-pointer hover:border-kodo-cyan/50 transition-all hover:-translate-y-1"
|
||||
onClick={() => onNavigate(playlist.id)}
|
||||
>
|
||||
<div className="aspect-square relative bg-gray-900">
|
||||
<div className="aspect-square relative bg-kodo-ink">
|
||||
{playlist.cover_url ? (
|
||||
<img
|
||||
src={playlist.cover_url}
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
) : (
|
||||
<div className="w-full h-full flex items-center justify-center text-gray-600">
|
||||
<div className="w-full h-full flex items-center justify-center text-kodo-content-dim">
|
||||
<ListMusic className="w-12 h-12 opacity-50" />
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -154,15 +154,15 @@ export const PlaylistsView: React.FC<{
|
|||
<h3 className="font-bold text-white truncate mb-1">
|
||||
{playlist.title}
|
||||
</h3>
|
||||
<p className="text-xs text-gray-400 mb-3 line-clamp-1">
|
||||
<p className="text-xs text-kodo-content-dim mb-3 line-clamp-1">
|
||||
{playlist.description || 'No description'}
|
||||
</p>
|
||||
<div className="flex justify-between items-center text-[10px] font-bold text-gray-500 uppercase">
|
||||
<div className="flex justify-between items-center text-[10px] font-bold text-kodo-content-dim uppercase">
|
||||
<span>{playlist.track_count} Tracks</span>
|
||||
{playlist.is_public ? (
|
||||
<Globe className="w-3 h-3 text-gray-600" />
|
||||
<Globe className="w-3 h-3 text-kodo-content-dim" />
|
||||
) : (
|
||||
<Lock className="w-3 h-3 text-gray-600" />
|
||||
<Lock className="w-3 h-3 text-kodo-content-dim" />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ export const QueueView: React.FC = () => {
|
|||
<h1 className="text-3xl font-display font-bold text-white mb-2">
|
||||
PLAY QUEUE
|
||||
</h1>
|
||||
<p className="text-gray-400 font-mono text-sm">
|
||||
<p className="text-kodo-content-dim font-mono text-sm">
|
||||
{queue.length} tracks upcoming
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -87,7 +87,7 @@ export const QueueView: React.FC = () => {
|
|||
{/* Current Track */}
|
||||
{currentTrack && (
|
||||
<div>
|
||||
<h3 className="text-xs font-bold text-gray-500 uppercase tracking-widest mb-3">
|
||||
<h3 className="text-xs font-bold text-kodo-content-dim uppercase tracking-widest mb-3">
|
||||
Now Playing
|
||||
</h3>
|
||||
<Card
|
||||
|
|
@ -123,7 +123,7 @@ export const QueueView: React.FC = () => {
|
|||
</h2>
|
||||
<p className="text-kodo-cyan">{currentTrack.artist}</p>
|
||||
</div>
|
||||
<div className="text-gray-500 font-mono text-sm hidden md:block">
|
||||
<div className="text-kodo-content-dim font-mono text-sm hidden md:block">
|
||||
{currentTrack.duration}
|
||||
</div>
|
||||
</Card>
|
||||
|
|
@ -133,7 +133,7 @@ export const QueueView: React.FC = () => {
|
|||
{/* Up Next */}
|
||||
<div>
|
||||
<div className="flex justify-between items-center mb-3">
|
||||
<h3 className="text-xs font-bold text-gray-500 uppercase tracking-widest">
|
||||
<h3 className="text-xs font-bold text-kodo-content-dim uppercase tracking-widest">
|
||||
Up Next
|
||||
</h3>
|
||||
<div
|
||||
|
|
@ -141,12 +141,12 @@ export const QueueView: React.FC = () => {
|
|||
onClick={toggleAutoplay}
|
||||
>
|
||||
<span
|
||||
className={`text-xs font-bold ${autoplay ? 'text-kodo-lime' : 'text-gray-500'}`}
|
||||
className={`text-xs font-bold ${autoplay ? 'text-kodo-lime' : 'text-kodo-content-dim'}`}
|
||||
>
|
||||
Autoplay
|
||||
</span>
|
||||
<div
|
||||
className={`w-8 h-4 rounded-full relative transition-colors ${autoplay ? 'bg-kodo-lime' : 'bg-gray-700'}`}
|
||||
className={`w-8 h-4 rounded-full relative transition-colors ${autoplay ? 'bg-kodo-lime' : 'bg-kodo-steel'}`}
|
||||
>
|
||||
<div
|
||||
className={`absolute top-0.5 w-3 h-3 bg-white rounded-full transition-all ${autoplay ? 'left-4.5' : 'left-0.5'}`}
|
||||
|
|
@ -157,7 +157,7 @@ export const QueueView: React.FC = () => {
|
|||
|
||||
<div className="space-y-2">
|
||||
{queue.length === 0 ? (
|
||||
<div className="text-center py-12 border-2 border-dashed border-kodo-steel rounded-xl text-gray-500">
|
||||
<div className="text-center py-12 border-2 border-dashed border-kodo-steel rounded-xl text-kodo-content-dim">
|
||||
<ListMusic className="w-12 h-12 mx-auto mb-4 opacity-50" />
|
||||
<p className="text-sm">
|
||||
Queue is empty. Add tracks to keep the vibe going.
|
||||
|
|
@ -178,7 +178,7 @@ export const QueueView: React.FC = () => {
|
|||
onDragEnd={() => setDraggedIndex(null)}
|
||||
className={`flex items-center gap-4 p-3 bg-kodo-ink rounded-lg border border-transparent hover:border-kodo-steel transition-all group ${draggedIndex === i ? 'opacity-50 border-kodo-cyan' : ''}`}
|
||||
>
|
||||
<div className="text-gray-600 cursor-grab active:cursor-grabbing hover:text-white p-1">
|
||||
<div className="text-kodo-content-dim cursor-grab active:cursor-grabbing hover:text-white p-1">
|
||||
<GripVertical className="w-5 h-5" />
|
||||
</div>
|
||||
<div className="w-10 h-10 rounded overflow-hidden flex-shrink-0 relative">
|
||||
|
|
@ -197,15 +197,15 @@ export const QueueView: React.FC = () => {
|
|||
<div className="text-sm font-bold text-white truncate">
|
||||
{track.title}
|
||||
</div>
|
||||
<div className="text-xs text-gray-400 truncate">
|
||||
<div className="text-xs text-kodo-content-dim truncate">
|
||||
{track.artist}
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-gray-500 font-mono text-xs hidden sm:block">
|
||||
<div className="text-kodo-content-dim font-mono text-xs hidden sm:block">
|
||||
{track.duration}
|
||||
</div>
|
||||
<button
|
||||
className="p-2 text-gray-500 hover:text-kodo-red opacity-0 group-hover:opacity-100 transition-opacity"
|
||||
className="p-2 text-kodo-content-dim hover:text-kodo-red opacity-0 group-hover:opacity-100 transition-opacity"
|
||||
onClick={() => removeFromQueue(track.id)}
|
||||
>
|
||||
<X className="w-4 h-4" />
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ export const SaveQueueAsPlaylistModal: React.FC<
|
|||
<div className="p-4 border-b border-kodo-steel bg-kodo-ink flex justify-between items-center">
|
||||
<h3 className="font-bold text-white">Save Queue as Playlist</h3>
|
||||
<button onClick={onClose}>
|
||||
<X className="w-5 h-5 text-gray-400 hover:text-white" />
|
||||
<X className="w-5 h-5 text-kodo-content-dim hover:text-white" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
|
@ -49,7 +49,7 @@ export const SaveQueueAsPlaylistModal: React.FC<
|
|||
/>
|
||||
|
||||
<div
|
||||
className="flex items-center justify-between p-3 bg-kodo-ink rounded border border-kodo-steel cursor-pointer hover:border-gray-500"
|
||||
className="flex items-center justify-between p-3 bg-kodo-ink rounded border border-kodo-steel cursor-pointer hover:border-kodo-steel"
|
||||
onClick={() => setIsPublic(!isPublic)}
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
|
|
@ -62,13 +62,13 @@ export const SaveQueueAsPlaylistModal: React.FC<
|
|||
<div className="text-sm font-bold text-white">
|
||||
{isPublic ? 'Public Playlist' : 'Private Playlist'}
|
||||
</div>
|
||||
<div className="text-xs text-gray-400">
|
||||
<div className="text-xs text-kodo-content-dim">
|
||||
{isPublic ? 'Visible on your profile' : 'Only visible to you'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={`w-10 h-5 rounded-full relative transition-colors ${isPublic ? 'bg-kodo-cyan' : 'bg-gray-600'}`}
|
||||
className={`w-10 h-5 rounded-full relative transition-colors ${isPublic ? 'bg-kodo-cyan' : 'bg-kodo-steel'}`}
|
||||
>
|
||||
<div
|
||||
className={`absolute top-1 w-3 h-3 bg-white rounded-full transition-all ${isPublic ? 'left-6' : 'left-1'}`}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ export const LiveStreamDetailView: React.FC<LiveStreamDetailViewProps> = ({
|
|||
id: 2,
|
||||
user: 'Studio_Rat',
|
||||
text: 'What VST is that?',
|
||||
color: 'text-gray-400',
|
||||
color: 'text-kodo-content-dim',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
|
|
@ -167,7 +167,7 @@ export const LiveStreamDetailView: React.FC<LiveStreamDetailViewProps> = ({
|
|||
<div className="w-80 md:w-96 bg-kodo-graphite border-l border-kodo-steel flex flex-col z-20 shadow-2xl">
|
||||
<div className="p-4 border-b border-kodo-steel bg-kodo-ink flex justify-between items-center">
|
||||
<h3 className="font-bold text-white text-sm">LIVE CHAT</h3>
|
||||
<Settings className="w-4 h-4 text-gray-400 cursor-pointer hover:text-white" />
|
||||
<Settings className="w-4 h-4 text-kodo-content-dim cursor-pointer hover:text-white" />
|
||||
</div>
|
||||
|
||||
<div className="flex-1 overflow-y-auto p-4 space-y-2 font-mono text-sm custom-scrollbar">
|
||||
|
|
@ -178,7 +178,7 @@ export const LiveStreamDetailView: React.FC<LiveStreamDetailViewProps> = ({
|
|||
>
|
||||
{msg.user}:
|
||||
</span>
|
||||
<span className="text-gray-300">{msg.text}</span>
|
||||
<span className="text-kodo-text-main">{msg.text}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
@ -200,7 +200,7 @@ export const LiveStreamDetailView: React.FC<LiveStreamDetailViewProps> = ({
|
|||
</button>
|
||||
</div>
|
||||
<div className="flex justify-between items-center mt-2 px-2">
|
||||
<span className="text-[10px] text-gray-500">Slow Mode: Off</span>
|
||||
<span className="text-[10px] text-kodo-content-dim">Slow Mode: Off</span>
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
className="text-kodo-gold hover:text-white"
|
||||
|
|
|
|||
|
|
@ -43,14 +43,14 @@ export const TipStreamerModal: React.FC<TipStreamerModalProps> = ({
|
|||
<DollarSign className="w-5 h-5" /> Support {streamerName}
|
||||
</h3>
|
||||
<button onClick={onClose}>
|
||||
<X className="w-5 h-5 text-gray-400 hover:text-white" />
|
||||
<X className="w-5 h-5 text-kodo-content-dim hover:text-white" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="p-6 space-y-6">
|
||||
{/* Amount Selection */}
|
||||
<div>
|
||||
<label className="block text-xs font-bold text-gray-400 uppercase mb-2">
|
||||
<label className="block text-xs font-bold text-kodo-content-dim uppercase mb-2">
|
||||
Select Amount
|
||||
</label>
|
||||
<div className="flex gap-2 mb-3">
|
||||
|
|
@ -58,14 +58,14 @@ export const TipStreamerModal: React.FC<TipStreamerModalProps> = ({
|
|||
<button
|
||||
key={val}
|
||||
onClick={() => setAmount(val)}
|
||||
className={`flex-1 py-2 rounded font-bold border transition-colors ${amount === val ? 'bg-kodo-gold text-black border-kodo-gold' : 'bg-kodo-void border-kodo-steel text-gray-400 hover:text-white'}`}
|
||||
className={`flex-1 py-2 rounded font-bold border transition-colors ${amount === val ? 'bg-kodo-gold text-black border-kodo-gold' : 'bg-kodo-void border-kodo-steel text-kodo-content-dim hover:text-white'}`}
|
||||
>
|
||||
${val}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<div className="relative">
|
||||
<span className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 font-bold">
|
||||
<span className="absolute left-3 top-1/2 -translate-y-1/2 text-kodo-content-dim font-bold">
|
||||
$
|
||||
</span>
|
||||
<input
|
||||
|
|
@ -80,7 +80,7 @@ export const TipStreamerModal: React.FC<TipStreamerModalProps> = ({
|
|||
|
||||
{/* Message */}
|
||||
<div>
|
||||
<label className="block text-xs font-bold text-gray-400 uppercase mb-2">
|
||||
<label className="block text-xs font-bold text-kodo-content-dim uppercase mb-2">
|
||||
Message (Optional)
|
||||
</label>
|
||||
<textarea
|
||||
|
|
@ -90,26 +90,26 @@ export const TipStreamerModal: React.FC<TipStreamerModalProps> = ({
|
|||
onChange={(e) => setMessage(e.target.value)}
|
||||
maxLength={200}
|
||||
/>
|
||||
<p className="text-right text-xs text-gray-500 mt-1">
|
||||
<p className="text-right text-xs text-kodo-content-dim mt-1">
|
||||
{message.length}/200
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Payment Method (Mock) */}
|
||||
<div>
|
||||
<label className="block text-xs font-bold text-gray-400 uppercase mb-2">
|
||||
<label className="block text-xs font-bold text-kodo-content-dim uppercase mb-2">
|
||||
Payment Method
|
||||
</label>
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
onClick={() => setPaymentMethod('card')}
|
||||
className={`flex-1 flex items-center justify-center gap-2 py-2 rounded border ${paymentMethod === 'card' ? 'bg-kodo-cyan/10 border-kodo-cyan text-kodo-cyan' : 'bg-kodo-void border-kodo-steel text-gray-400'}`}
|
||||
className={`flex-1 flex items-center justify-center gap-2 py-2 rounded border ${paymentMethod === 'card' ? 'bg-kodo-cyan/10 border-kodo-cyan text-kodo-cyan' : 'bg-kodo-void border-kodo-steel text-kodo-content-dim'}`}
|
||||
>
|
||||
<CreditCard className="w-4 h-4" /> Card
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setPaymentMethod('crypto')}
|
||||
className={`flex-1 flex items-center justify-center gap-2 py-2 rounded border ${paymentMethod === 'crypto' ? 'bg-kodo-magenta/10 border-kodo-magenta text-kodo-magenta' : 'bg-kodo-void border-kodo-steel text-gray-400'}`}
|
||||
className={`flex-1 flex items-center justify-center gap-2 py-2 rounded border ${paymentMethod === 'crypto' ? 'bg-kodo-magenta/10 border-kodo-magenta text-kodo-magenta' : 'bg-kodo-void border-kodo-steel text-kodo-content-dim'}`}
|
||||
>
|
||||
<span className="font-bold">Ξ</span> Crypto
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -39,13 +39,13 @@ export const LicenceCard: React.FC<LicenceCardProps> = ({
|
|||
|
||||
<ul className="space-y-2 mb-6 flex-1">
|
||||
{license.features.slice(0, 3).map((feat, i) => (
|
||||
<li key={i} className="flex items-start gap-2 text-sm text-gray-300">
|
||||
<li key={i} className="flex items-start gap-2 text-sm text-kodo-text-main">
|
||||
<Check className="w-4 h-4 text-kodo-lime flex-shrink-0 mt-0.5" />
|
||||
<span className="leading-snug">{feat}</span>
|
||||
</li>
|
||||
))}
|
||||
{license.features.length > 3 && (
|
||||
<li className="text-xs text-gray-500 pl-6">
|
||||
<li className="text-xs text-kodo-content-dim pl-6">
|
||||
+ {license.features.length - 3} more features
|
||||
</li>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -92,9 +92,9 @@ export const ProductCard: React.FC<ProductCardProps> = ({
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<p className="text-gray-400 text-xs mb-4 flex items-center gap-1">
|
||||
<p className="text-kodo-content-dim text-xs mb-4 flex items-center gap-1">
|
||||
by{' '}
|
||||
<span className="text-gray-300 hover:underline">
|
||||
<span className="text-kodo-text-main hover:underline">
|
||||
{product.author}
|
||||
</span>
|
||||
</p>
|
||||
|
|
@ -102,7 +102,7 @@ export const ProductCard: React.FC<ProductCardProps> = ({
|
|||
<div className="flex items-center gap-2 mb-4 text-xs text-kodo-gold">
|
||||
<Star className="w-3 h-3 fill-current" />
|
||||
<span className="font-bold">{product.rating}</span>
|
||||
<span className="text-gray-500">({product.reviewCount || 0})</span>
|
||||
<span className="text-kodo-content-dim">({product.reviewCount || 0})</span>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-2">
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ export const ProductDetailView: React.FC<ProductDetailViewProps> = ({
|
|||
>
|
||||
Back to Market
|
||||
</Button>
|
||||
<span className="text-gray-500 text-sm">
|
||||
<span className="text-kodo-content-dim text-sm">
|
||||
/ {product.type} / {product.title}
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -90,7 +90,7 @@ export const ProductDetailView: React.FC<ProductDetailViewProps> = ({
|
|||
<div className="text-xs font-bold text-white mb-1">
|
||||
Audio Preview
|
||||
</div>
|
||||
<div className="h-1 bg-gray-600 rounded-full overflow-hidden">
|
||||
<div className="h-1 bg-kodo-steel rounded-full overflow-hidden">
|
||||
<div className="h-full bg-kodo-cyan w-1/3 animate-pulse"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -122,14 +122,14 @@ export const ProductDetailView: React.FC<ProductDetailViewProps> = ({
|
|||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="border border-kodo-steel text-gray-400 hover:text-kodo-magenta"
|
||||
className="border border-kodo-steel text-kodo-content-dim hover:text-kodo-magenta"
|
||||
>
|
||||
<Heart className="w-5 h-5" />
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="border border-kodo-steel text-gray-400 hover:text-white"
|
||||
className="border border-kodo-steel text-kodo-content-dim hover:text-white"
|
||||
>
|
||||
<Share2 className="w-5 h-5" />
|
||||
</Button>
|
||||
|
|
@ -138,7 +138,7 @@ export const ProductDetailView: React.FC<ProductDetailViewProps> = ({
|
|||
<h1 className="text-4xl md:text-5xl font-display font-bold text-white mb-2 leading-tight">
|
||||
{product.title}
|
||||
</h1>
|
||||
<div className="flex items-center gap-4 text-sm text-gray-400">
|
||||
<div className="flex items-center gap-4 text-sm text-kodo-content-dim">
|
||||
<span className="flex items-center gap-1 text-kodo-gold font-bold">
|
||||
<Star className="w-4 h-4 fill-current" /> {product.rating}
|
||||
</span>
|
||||
|
|
@ -152,25 +152,25 @@ export const ProductDetailView: React.FC<ProductDetailViewProps> = ({
|
|||
{/* Metadata Grid */}
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 mb-8">
|
||||
<div className="bg-kodo-ink p-3 rounded border border-kodo-steel/50">
|
||||
<div className="text-[10px] text-gray-500 uppercase font-bold">
|
||||
<div className="text-[10px] text-kodo-content-dim uppercase font-bold">
|
||||
BPM
|
||||
</div>
|
||||
<div className="text-white font-mono">{product.bpm || '-'}</div>
|
||||
</div>
|
||||
<div className="bg-kodo-ink p-3 rounded border border-kodo-steel/50">
|
||||
<div className="text-[10px] text-gray-500 uppercase font-bold">
|
||||
<div className="text-[10px] text-kodo-content-dim uppercase font-bold">
|
||||
Key
|
||||
</div>
|
||||
<div className="text-white font-mono">{product.key || '-'}</div>
|
||||
</div>
|
||||
<div className="bg-kodo-ink p-3 rounded border border-kodo-steel/50">
|
||||
<div className="text-[10px] text-gray-500 uppercase font-bold">
|
||||
<div className="text-[10px] text-kodo-content-dim uppercase font-bold">
|
||||
Genre
|
||||
</div>
|
||||
<div className="text-white truncate">{product.genre || '-'}</div>
|
||||
</div>
|
||||
<div className="bg-kodo-ink p-3 rounded border border-kodo-steel/50">
|
||||
<div className="text-[10px] text-gray-500 uppercase font-bold">
|
||||
<div className="text-[10px] text-kodo-content-dim uppercase font-bold">
|
||||
Size
|
||||
</div>
|
||||
<div className="text-white">{product.size || '-'}</div>
|
||||
|
|
@ -179,7 +179,7 @@ export const ProductDetailView: React.FC<ProductDetailViewProps> = ({
|
|||
|
||||
{/* Licenses */}
|
||||
<div className="mb-8">
|
||||
<h3 className="text-sm font-bold text-gray-400 uppercase tracking-wider mb-4 flex items-center gap-2">
|
||||
<h3 className="text-sm font-bold text-kodo-content-dim uppercase tracking-wider mb-4 flex items-center gap-2">
|
||||
<Layers className="w-4 h-4" /> Select License
|
||||
</h3>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
|
|
@ -198,7 +198,7 @@ export const ProductDetailView: React.FC<ProductDetailViewProps> = ({
|
|||
{/* Sticky Action Bar (Mobile optimized) */}
|
||||
<div className="mt-auto bg-kodo-graphite border border-kodo-steel p-4 rounded-xl shadow-2xl flex flex-col md:flex-row gap-4 items-center">
|
||||
<div className="flex-1">
|
||||
<div className="text-xs text-gray-400 uppercase font-bold">
|
||||
<div className="text-xs text-kodo-content-dim uppercase font-bold">
|
||||
Total Price
|
||||
</div>
|
||||
<div className="text-3xl font-mono font-bold text-white">
|
||||
|
|
@ -225,7 +225,7 @@ export const ProductDetailView: React.FC<ProductDetailViewProps> = ({
|
|||
<h3 className="font-bold text-white text-xl mb-4 border-b border-kodo-steel pb-2">
|
||||
Description
|
||||
</h3>
|
||||
<div className="prose prose-invert max-w-none text-gray-300">
|
||||
<div className="prose prose-invert max-w-none text-kodo-text-main">
|
||||
<p>{product.description}</p>
|
||||
<ul>
|
||||
{product.features?.map((f: string, i: number) => (
|
||||
|
|
@ -252,7 +252,7 @@ export const ProductDetailView: React.FC<ProductDetailViewProps> = ({
|
|||
<div key={review.id} className="flex gap-4">
|
||||
<img
|
||||
src={review.avatar}
|
||||
className="w-10 h-10 rounded-full bg-gray-700"
|
||||
className="w-10 h-10 rounded-full bg-kodo-steel"
|
||||
/>
|
||||
<div>
|
||||
<div className="flex items-center gap-2 mb-1">
|
||||
|
|
@ -263,20 +263,20 @@ export const ProductDetailView: React.FC<ProductDetailViewProps> = ({
|
|||
{[...Array(5)].map((_, i) => (
|
||||
<Star
|
||||
key={i}
|
||||
className={`w-3 h-3 ${i < review.rating ? 'fill-current' : 'text-gray-600'}`}
|
||||
className={`w-3 h-3 ${i < review.rating ? 'fill-current' : 'text-kodo-content-dim'}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<span className="text-xs text-gray-500">
|
||||
<span className="text-xs text-kodo-content-dim">
|
||||
{review.date}
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-gray-300">{review.comment}</p>
|
||||
<p className="text-sm text-kodo-text-main">{review.comment}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
{(!product.reviews || product.reviews.length === 0) && (
|
||||
<p className="text-gray-500 italic text-center py-4">
|
||||
<p className="text-kodo-content-dim italic text-center py-4">
|
||||
No reviews yet. Be the first!
|
||||
</p>
|
||||
)}
|
||||
|
|
@ -311,13 +311,13 @@ export const ProductDetailView: React.FC<ProductDetailViewProps> = ({
|
|||
>
|
||||
<img
|
||||
src={p.coverUrl}
|
||||
className="w-16 h-16 rounded bg-gray-800 object-cover"
|
||||
className="w-16 h-16 rounded bg-kodo-graphite object-cover"
|
||||
/>
|
||||
<div>
|
||||
<h4 className="font-bold text-white text-sm group-hover:text-kodo-cyan">
|
||||
{p.title}
|
||||
</h4>
|
||||
<p className="text-xs text-gray-500">{p.type}</p>
|
||||
<p className="text-xs text-kodo-content-dim">{p.type}</p>
|
||||
<p className="text-xs font-mono text-white mt-1">
|
||||
${p.price}
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ export const LicenceDetailsModal: React.FC<LicenceDetailsModalProps> = ({
|
|||
<ShieldCheck className="w-5 h-5 text-kodo-cyan" /> License Agreement
|
||||
</h3>
|
||||
<button onClick={onClose}>
|
||||
<X className="w-5 h-5 text-gray-400 hover:text-white" />
|
||||
<X className="w-5 h-5 text-kodo-content-dim hover:text-white" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ export const LicenceDetailsModal: React.FC<LicenceDetailsModalProps> = ({
|
|||
<h2 className="text-2xl font-bold text-white">
|
||||
{license.name} License
|
||||
</h2>
|
||||
<p className="text-gray-400 text-sm">
|
||||
<p className="text-kodo-content-dim text-sm">
|
||||
Review usage rights and restrictions.
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -54,7 +54,7 @@ export const LicenceDetailsModal: React.FC<LicenceDetailsModalProps> = ({
|
|||
{license.features.map((feat, i) => (
|
||||
<li
|
||||
key={i}
|
||||
className="flex items-start gap-3 text-sm text-gray-300"
|
||||
className="flex items-start gap-3 text-sm text-kodo-text-main"
|
||||
>
|
||||
<div className="mt-0.5 bg-kodo-lime/10 p-0.5 rounded-full">
|
||||
<Check className="w-3 h-3 text-kodo-lime" />
|
||||
|
|
@ -70,13 +70,13 @@ export const LicenceDetailsModal: React.FC<LicenceDetailsModalProps> = ({
|
|||
Restrictions
|
||||
</h4>
|
||||
<ul className="space-y-2">
|
||||
<li className="flex items-start gap-3 text-sm text-gray-400">
|
||||
<li className="flex items-start gap-3 text-sm text-kodo-content-dim">
|
||||
<div className="mt-0.5 bg-kodo-red/10 p-0.5 rounded-full">
|
||||
<XCircle className="w-3 h-3 text-kodo-red" />
|
||||
</div>
|
||||
Do not resell or redistribute as a sample pack.
|
||||
</li>
|
||||
<li className="flex items-start gap-3 text-sm text-gray-400">
|
||||
<li className="flex items-start gap-3 text-sm text-kodo-content-dim">
|
||||
<div className="mt-0.5 bg-kodo-red/10 p-0.5 rounded-full">
|
||||
<XCircle className="w-3 h-3 text-kodo-red" />
|
||||
</div>
|
||||
|
|
@ -85,7 +85,7 @@ export const LicenceDetailsModal: React.FC<LicenceDetailsModalProps> = ({
|
|||
</ul>
|
||||
</div>
|
||||
|
||||
<p className="text-xs text-gray-500 italic">
|
||||
<p className="text-xs text-kodo-content-dim italic">
|
||||
This is a simplified summary. Please read the full{' '}
|
||||
<a href="#" className="text-kodo-cyan hover:underline">
|
||||
legal contract
|
||||
|
|
|
|||
|
|
@ -40,13 +40,13 @@ export const ReviewProductModal: React.FC<ReviewProductModalProps> = ({
|
|||
<MessageSquare className="w-4 h-4 text-kodo-cyan" /> Write Review
|
||||
</h3>
|
||||
<button onClick={onClose}>
|
||||
<X className="w-5 h-5 text-gray-400 hover:text-white" />
|
||||
<X className="w-5 h-5 text-kodo-content-dim hover:text-white" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="p-6 space-y-6">
|
||||
<div className="text-center">
|
||||
<p className="text-gray-400 text-sm mb-2">
|
||||
<p className="text-kodo-content-dim text-sm mb-2">
|
||||
How was your experience with
|
||||
</p>
|
||||
<h4 className="font-bold text-white text-lg">{productTitle}?</h4>
|
||||
|
|
@ -65,7 +65,7 @@ export const ReviewProductModal: React.FC<ReviewProductModalProps> = ({
|
|||
className={`w-8 h-8 transition-colors ${
|
||||
star <= (hoverRating || rating)
|
||||
? 'fill-kodo-gold text-kodo-gold'
|
||||
: 'text-gray-600'
|
||||
: 'text-kodo-content-dim'
|
||||
}`}
|
||||
/>
|
||||
</button>
|
||||
|
|
@ -73,7 +73,7 @@ export const ReviewProductModal: React.FC<ReviewProductModalProps> = ({
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-xs font-bold text-gray-400 uppercase mb-2">
|
||||
<label className="block text-xs font-bold text-kodo-content-dim uppercase mb-2">
|
||||
Your Review
|
||||
</label>
|
||||
<textarea
|
||||
|
|
|
|||
|
|
@ -45,25 +45,25 @@ export const CreatorModal: React.FC<CreatorModalProps> = ({
|
|||
<div className="flex bg-kodo-slate rounded-lg p-1">
|
||||
<button
|
||||
onClick={() => setActiveTab('track')}
|
||||
className={`px-4 py-1.5 rounded text-sm font-bold transition-all flex items-center gap-2 ${activeTab === 'track' ? 'bg-kodo-cyan text-black' : 'text-gray-400 hover:text-white'}`}
|
||||
className={`px-4 py-1.5 rounded text-sm font-bold transition-all flex items-center gap-2 ${activeTab === 'track' ? 'bg-kodo-cyan text-black' : 'text-kodo-content-dim hover:text-white'}`}
|
||||
>
|
||||
<Music className="w-4 h-4" /> Track
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab('product')}
|
||||
className={`px-4 py-1.5 rounded text-sm font-bold transition-all flex items-center gap-2 ${activeTab === 'product' ? 'bg-kodo-magenta text-white' : 'text-gray-400 hover:text-white'}`}
|
||||
className={`px-4 py-1.5 rounded text-sm font-bold transition-all flex items-center gap-2 ${activeTab === 'product' ? 'bg-kodo-magenta text-white' : 'text-kodo-content-dim hover:text-white'}`}
|
||||
>
|
||||
<Package className="w-4 h-4" /> Product
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab('course')}
|
||||
className={`px-4 py-1.5 rounded text-sm font-bold transition-all flex items-center gap-2 ${activeTab === 'course' ? 'bg-kodo-gold text-black' : 'text-gray-400 hover:text-white'}`}
|
||||
className={`px-4 py-1.5 rounded text-sm font-bold transition-all flex items-center gap-2 ${activeTab === 'course' ? 'bg-kodo-gold text-black' : 'text-kodo-content-dim hover:text-white'}`}
|
||||
>
|
||||
<BookOpen className="w-4 h-4" /> Course
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button onClick={onClose} className="text-gray-400 hover:text-white">
|
||||
<button onClick={onClose} className="text-kodo-content-dim hover:text-white">
|
||||
<X className="w-6 h-6" />
|
||||
</button>
|
||||
</div>
|
||||
|
|
@ -76,7 +76,7 @@ export const CreatorModal: React.FC<CreatorModalProps> = ({
|
|||
{[1, 2, 3].map((i) => (
|
||||
<div
|
||||
key={i}
|
||||
className={`w-8 h-8 rounded-full flex items-center justify-center font-bold text-sm transition-colors ${step >= i ? 'bg-kodo-cyan text-black' : 'bg-kodo-slate text-gray-500'}`}
|
||||
className={`w-8 h-8 rounded-full flex items-center justify-center font-bold text-sm transition-colors ${step >= i ? 'bg-kodo-cyan text-black' : 'bg-kodo-slate text-kodo-content-dim'}`}
|
||||
>
|
||||
{step > i ? <CheckCircle className="w-5 h-5" /> : i}
|
||||
</div>
|
||||
|
|
@ -88,10 +88,10 @@ export const CreatorModal: React.FC<CreatorModalProps> = ({
|
|||
<div className="space-y-6">
|
||||
<FileUpload />
|
||||
<div className="bg-kodo-slate p-4 rounded-lg border border-kodo-steel">
|
||||
<h4 className="font-bold text-gray-400 text-sm mb-2 uppercase">
|
||||
<h4 className="font-bold text-kodo-content-dim text-sm mb-2 uppercase">
|
||||
File Requirements
|
||||
</h4>
|
||||
<ul className="text-xs text-gray-500 space-y-1">
|
||||
<ul className="text-xs text-kodo-content-dim space-y-1">
|
||||
<li>• WAV, FLAC, AIFF (Lossless preferred)</li>
|
||||
<li>• Max size 500MB</li>
|
||||
<li>• 44.1kHz / 24-bit minimum</li>
|
||||
|
|
@ -106,7 +106,7 @@ export const CreatorModal: React.FC<CreatorModalProps> = ({
|
|||
</div>
|
||||
<Input label="Genre" placeholder="Cyberpunk / Synthwave" />
|
||||
<div className="pt-4">
|
||||
<label className="block text-sm font-medium text-gray-400 mb-2 font-body">
|
||||
<label className="block text-sm font-medium text-kodo-content-dim mb-2 font-body">
|
||||
Visibility
|
||||
</label>
|
||||
<div className="grid grid-cols-3 gap-2">
|
||||
|
|
@ -114,11 +114,11 @@ export const CreatorModal: React.FC<CreatorModalProps> = ({
|
|||
<Tag className="w-5 h-5" />{' '}
|
||||
<span className="text-xs font-bold">Public</span>
|
||||
</button>
|
||||
<button className="p-3 rounded border border-kodo-steel bg-kodo-slate text-gray-400 flex flex-col items-center justify-center gap-2 hover:border-white hover:text-white">
|
||||
<button className="p-3 rounded border border-kodo-steel bg-kodo-slate text-kodo-content-dim flex flex-col items-center justify-center gap-2 hover:border-white hover:text-white">
|
||||
<Lock className="w-5 h-5" />{' '}
|
||||
<span className="text-xs font-bold">Private</span>
|
||||
</button>
|
||||
<button className="p-3 rounded border border-kodo-steel bg-kodo-slate text-gray-400 flex flex-col items-center justify-center gap-2 hover:border-white hover:text-white">
|
||||
<button className="p-3 rounded border border-kodo-steel bg-kodo-slate text-kodo-content-dim flex flex-col items-center justify-center gap-2 hover:border-white hover:text-white">
|
||||
<DollarSign className="w-5 h-5" />{' '}
|
||||
<span className="text-xs font-bold">Premium</span>
|
||||
</button>
|
||||
|
|
@ -133,7 +133,7 @@ export const CreatorModal: React.FC<CreatorModalProps> = ({
|
|||
<h3 className="text-xl font-bold text-white mb-2">
|
||||
Sell Your Sounds
|
||||
</h3>
|
||||
<p className="text-gray-400 mb-6">
|
||||
<p className="text-kodo-content-dim mb-6">
|
||||
Create Sample Packs, Presets, or DAW Templates.
|
||||
</p>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ export const NotificationBell: React.FC<NotificationBellProps> = ({
|
|||
<div className="p-4 border-b border-kodo-steel/50 flex justify-between items-center bg-kodo-ink">
|
||||
<div>
|
||||
<h3 className="font-bold text-white">Notifications</h3>
|
||||
<p className="text-xs text-gray-400">{unreadCount} unread</p>
|
||||
<p className="text-xs text-kodo-content-dim">{unreadCount} unread</p>
|
||||
</div>
|
||||
{unreadCount > 0 && (
|
||||
<button
|
||||
|
|
@ -68,7 +68,7 @@ export const NotificationBell: React.FC<NotificationBellProps> = ({
|
|||
|
||||
<div className="flex-1 overflow-y-auto custom-scrollbar p-2 space-y-1">
|
||||
{notifications.length === 0 ? (
|
||||
<div className="text-center py-10 text-gray-500">
|
||||
<div className="text-center py-10 text-kodo-content-dim">
|
||||
<Bell className="w-8 h-8 mx-auto mb-2 opacity-50" />
|
||||
<p className="text-sm">No new notifications</p>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ export const NotificationItem: React.FC<NotificationItemProps> = ({
|
|||
case 'security':
|
||||
return <ShieldAlert className="w-4 h-4 text-kodo-red" />;
|
||||
default:
|
||||
return <Info className="w-4 h-4 text-gray-400" />;
|
||||
return <Info className="w-4 h-4 text-kodo-content-dim" />;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -60,10 +60,10 @@ export const NotificationItem: React.FC<NotificationItemProps> = ({
|
|||
</div>
|
||||
|
||||
<div className="flex-1 min-w-0">
|
||||
<p className="text-sm text-gray-200 leading-relaxed">
|
||||
<p className="text-sm text-kodo-text-main leading-relaxed">
|
||||
{notification.message}
|
||||
</p>
|
||||
<span className="text-xs text-gray-500 font-mono mt-1 block">
|
||||
<span className="text-xs text-kodo-content-dim font-mono mt-1 block">
|
||||
{notification.timestamp}
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ export const LyricsPanel: React.FC = () => {
|
|||
|
||||
if (!currentTrack?.lyrics) {
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center h-full text-gray-500 opacity-50">
|
||||
<div className="flex flex-col items-center justify-center h-full text-kodo-content-dim opacity-50">
|
||||
<Mic2 className="w-16 h-16 mb-4" />
|
||||
<p>No lyrics available</p>
|
||||
</div>
|
||||
|
|
@ -47,7 +47,7 @@ export const LyricsPanel: React.FC = () => {
|
|||
<div className="absolute top-2 right-2 z-10 opacity-0 group-hover:opacity-100 transition-opacity">
|
||||
<button
|
||||
onClick={() => setAutoScroll(!autoScroll)}
|
||||
className={`p-2 rounded-full backdrop-blur-md ${autoScroll ? 'bg-kodo-cyan/20 text-kodo-cyan' : 'bg-black/30 text-gray-400'}`}
|
||||
className={`p-2 rounded-full backdrop-blur-md ${autoScroll ? 'bg-kodo-cyan/20 text-kodo-cyan' : 'bg-black/30 text-kodo-content-dim'}`}
|
||||
title="Auto-scroll"
|
||||
>
|
||||
<AlignLeft className="w-4 h-4" />
|
||||
|
|
|
|||
|
|
@ -58,12 +58,12 @@ export const MiniPlayer: React.FC<MiniPlayerProps> = ({
|
|||
{currentTrack.title}
|
||||
</h4>
|
||||
</div>
|
||||
<p className="text-gray-400 text-xs truncate hover:text-white cursor-pointer">
|
||||
<p className="text-kodo-content-dim text-xs truncate hover:text-white cursor-pointer">
|
||||
{currentTrack.artist}
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
className="text-gray-500 hover:text-kodo-magenta transition-colors ml-2"
|
||||
className="text-kodo-content-dim hover:text-kodo-magenta transition-colors ml-2"
|
||||
onClick={() => addToast('Added to Liked Songs')}
|
||||
>
|
||||
<Heart className="w-5 h-5" />
|
||||
|
|
@ -75,7 +75,7 @@ export const MiniPlayer: React.FC<MiniPlayerProps> = ({
|
|||
<PlayerControls layout="compact" />
|
||||
|
||||
<div className="w-full flex items-center gap-3 group mt-1">
|
||||
<span className="text-[10px] font-mono text-gray-500 w-8 text-right">
|
||||
<span className="text-[10px] font-mono text-kodo-content-dim w-8 text-right">
|
||||
{formatTime(currentTime)}
|
||||
</span>
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ export const MiniPlayer: React.FC<MiniPlayerProps> = ({
|
|||
></div>
|
||||
</div>
|
||||
|
||||
<span className="text-[10px] font-mono text-gray-500 w-8">
|
||||
<span className="text-[10px] font-mono text-kodo-content-dim w-8">
|
||||
{formatTime(duration)}
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -103,21 +103,21 @@ export const MiniPlayer: React.FC<MiniPlayerProps> = ({
|
|||
{/* 3. Right Actions */}
|
||||
<div className="flex items-center justify-end gap-3 w-[30%] min-w-[200px]">
|
||||
<button
|
||||
className="text-gray-400 hover:text-kodo-magenta transition-colors hidden xl:block"
|
||||
className="text-kodo-content-dim hover:text-kodo-magenta transition-colors hidden xl:block"
|
||||
title="Lyrics"
|
||||
onClick={onExpand}
|
||||
>
|
||||
<Mic2 className="w-4 h-4" />
|
||||
</button>
|
||||
<button
|
||||
className="text-gray-400 hover:text-kodo-lime transition-colors"
|
||||
className="text-kodo-content-dim hover:text-kodo-lime transition-colors"
|
||||
title="Devices"
|
||||
onClick={() => addToast('Device Menu')}
|
||||
>
|
||||
<Cast className="w-4 h-4" />
|
||||
</button>
|
||||
<button
|
||||
className={`text-gray-400 hover:text-kodo-cyan transition-colors ${isQueueOpen ? 'text-kodo-cyan' : ''}`}
|
||||
className={`text-kodo-content-dim hover:text-kodo-cyan transition-colors ${isQueueOpen ? 'text-kodo-cyan' : ''}`}
|
||||
onClick={onToggleQueue}
|
||||
>
|
||||
<ListMusic className="w-5 h-5" />
|
||||
|
|
|
|||
|
|
@ -24,14 +24,14 @@ export const PlaybackSpeedModal: React.FC<PlaybackSpeedModalProps> = ({
|
|||
<Gauge className="w-4 h-4 text-kodo-gold" /> Playback Speed
|
||||
</h3>
|
||||
<button onClick={onClose}>
|
||||
<X className="w-4 h-4 text-gray-400 hover:text-white" />
|
||||
<X className="w-4 h-4 text-kodo-content-dim hover:text-white" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="p-6 space-y-6">
|
||||
{/* Slider */}
|
||||
<div className="space-y-2">
|
||||
<div className="flex justify-between text-xs text-gray-400">
|
||||
<div className="flex justify-between text-xs text-kodo-content-dim">
|
||||
<span>0.5x</span>
|
||||
<span className="font-bold text-kodo-gold text-lg">
|
||||
{playbackRate}x
|
||||
|
|
@ -55,7 +55,7 @@ export const PlaybackSpeedModal: React.FC<PlaybackSpeedModalProps> = ({
|
|||
<button
|
||||
key={rate}
|
||||
onClick={() => setPlaybackRate(rate)}
|
||||
className={`px-2 py-1.5 rounded text-xs font-bold transition-all ${playbackRate === rate ? 'bg-kodo-gold text-black' : 'bg-kodo-slate text-gray-400 hover:text-white'}`}
|
||||
className={`px-2 py-1.5 rounded text-xs font-bold transition-all ${playbackRate === rate ? 'bg-kodo-gold text-black' : 'bg-kodo-slate text-kodo-content-dim hover:text-white'}`}
|
||||
>
|
||||
{rate}x
|
||||
</button>
|
||||
|
|
@ -68,13 +68,13 @@ export const PlaybackSpeedModal: React.FC<PlaybackSpeedModalProps> = ({
|
|||
<span className="text-sm font-bold text-white">
|
||||
Pitch Correction
|
||||
</span>
|
||||
<span className="text-[10px] text-gray-500">
|
||||
<span className="text-[10px] text-kodo-content-dim">
|
||||
Maintain key when changing speed
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
onClick={togglePitchCorrection}
|
||||
className={`w-10 h-5 rounded-full relative cursor-pointer transition-colors ${pitchCorrection ? 'bg-kodo-gold' : 'bg-gray-600'}`}
|
||||
className={`w-10 h-5 rounded-full relative cursor-pointer transition-colors ${pitchCorrection ? 'bg-kodo-gold' : 'bg-kodo-steel'}`}
|
||||
>
|
||||
<div
|
||||
className={`absolute top-1 w-3 h-3 bg-white rounded-full transition-all ${pitchCorrection ? 'left-6' : 'left-1'}`}
|
||||
|
|
|
|||
|
|
@ -48,14 +48,14 @@ export const PlayerControls: React.FC<PlayerControlsProps> = ({
|
|||
{/* 1. Playback Modifiers */}
|
||||
<div className="flex items-center gap-4 relative">
|
||||
<button
|
||||
className={`transition-colors hover:text-white ${shuffle ? 'text-kodo-cyan' : 'text-gray-500'}`}
|
||||
className={`transition-colors hover:text-white ${shuffle ? 'text-kodo-cyan' : 'text-kodo-content-dim'}`}
|
||||
onClick={toggleShuffle}
|
||||
title="Shuffle"
|
||||
>
|
||||
<Shuffle className={layout === 'full' ? 'w-5 h-5' : 'w-4 h-4'} />
|
||||
</button>
|
||||
<button
|
||||
className={`transition-colors hover:text-white relative ${repeatMode !== 'off' ? 'text-kodo-cyan' : 'text-gray-500'}`}
|
||||
className={`transition-colors hover:text-white relative ${repeatMode !== 'off' ? 'text-kodo-cyan' : 'text-kodo-content-dim'}`}
|
||||
onClick={toggleRepeat}
|
||||
title="Repeat"
|
||||
>
|
||||
|
|
@ -71,7 +71,7 @@ export const PlayerControls: React.FC<PlayerControlsProps> = ({
|
|||
{/* 2. Main Transport */}
|
||||
<div className="flex items-center gap-6">
|
||||
<button
|
||||
className="text-gray-400 hover:text-white transition-colors hover:scale-110"
|
||||
className="text-kodo-content-dim hover:text-white transition-colors hover:scale-110"
|
||||
onClick={prevTrack}
|
||||
>
|
||||
<SkipBack
|
||||
|
|
@ -105,7 +105,7 @@ export const PlayerControls: React.FC<PlayerControlsProps> = ({
|
|||
)}
|
||||
</button>
|
||||
<button
|
||||
className="text-gray-400 hover:text-white transition-colors hover:scale-110"
|
||||
className="text-kodo-content-dim hover:text-white transition-colors hover:scale-110"
|
||||
onClick={nextTrack}
|
||||
>
|
||||
<SkipForward
|
||||
|
|
@ -123,7 +123,7 @@ export const PlayerControls: React.FC<PlayerControlsProps> = ({
|
|||
{layout === 'full' && (
|
||||
<>
|
||||
<button
|
||||
className={`text-gray-400 hover:text-kodo-gold transition-colors ${showSpeed ? 'text-kodo-gold' : ''}`}
|
||||
className={`text-kodo-content-dim hover:text-kodo-gold transition-colors ${showSpeed ? 'text-kodo-gold' : ''}`}
|
||||
onClick={() => {
|
||||
setShowSpeed(!showSpeed);
|
||||
setShowVisualizer(false);
|
||||
|
|
@ -133,7 +133,7 @@ export const PlayerControls: React.FC<PlayerControlsProps> = ({
|
|||
<Gauge className="w-5 h-5" />
|
||||
</button>
|
||||
<button
|
||||
className={`text-gray-400 hover:text-kodo-cyan transition-colors ${showVisualizer ? 'text-kodo-cyan' : ''}`}
|
||||
className={`text-kodo-content-dim hover:text-kodo-cyan transition-colors ${showVisualizer ? 'text-kodo-cyan' : ''}`}
|
||||
onClick={() => {
|
||||
setShowVisualizer(!showVisualizer);
|
||||
setShowSpeed(false);
|
||||
|
|
@ -149,7 +149,7 @@ export const PlayerControls: React.FC<PlayerControlsProps> = ({
|
|||
<div className="flex items-center gap-2 group w-24">
|
||||
<button
|
||||
onClick={toggleMute}
|
||||
className="text-gray-400 hover:text-white"
|
||||
className="text-kodo-content-dim hover:text-white"
|
||||
>
|
||||
{isMuted || volume === 0 ? (
|
||||
<VolumeX className="w-4 h-4" />
|
||||
|
|
|
|||
|
|
@ -24,14 +24,14 @@ export const VisualizerSettingsModal: React.FC<
|
|||
<Activity className="w-4 h-4 text-kodo-cyan" /> Visualizer
|
||||
</h3>
|
||||
<button onClick={onClose}>
|
||||
<X className="w-4 h-4 text-gray-400 hover:text-white" />
|
||||
<X className="w-4 h-4 text-kodo-content-dim hover:text-white" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="p-5 space-y-5">
|
||||
{/* Mode */}
|
||||
<div>
|
||||
<label className="block text-xs font-bold text-gray-400 uppercase mb-2">
|
||||
<label className="block text-xs font-bold text-kodo-content-dim uppercase mb-2">
|
||||
Display Mode
|
||||
</label>
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
|
|
@ -39,7 +39,7 @@ export const VisualizerSettingsModal: React.FC<
|
|||
<button
|
||||
key={mode}
|
||||
onClick={() => updateSetting('mode', mode)}
|
||||
className={`px-2 py-1.5 rounded text-xs font-bold capitalize transition-all border ${visualizerSettings.mode === mode ? 'bg-kodo-cyan/10 border-kodo-cyan text-kodo-cyan' : 'bg-kodo-slate border-transparent text-gray-400 hover:text-white'}`}
|
||||
className={`px-2 py-1.5 rounded text-xs font-bold capitalize transition-all border ${visualizerSettings.mode === mode ? 'bg-kodo-cyan/10 border-kodo-cyan text-kodo-cyan' : 'bg-kodo-slate border-transparent text-kodo-content-dim hover:text-white'}`}
|
||||
>
|
||||
{mode}
|
||||
</button>
|
||||
|
|
@ -49,7 +49,7 @@ export const VisualizerSettingsModal: React.FC<
|
|||
|
||||
{/* Sensitivity */}
|
||||
<div>
|
||||
<div className="flex justify-between text-xs text-gray-400 mb-1">
|
||||
<div className="flex justify-between text-xs text-kodo-content-dim mb-1">
|
||||
<span>Sensitivity</span>
|
||||
<span>{visualizerSettings.sensitivity}%</span>
|
||||
</div>
|
||||
|
|
@ -67,7 +67,7 @@ export const VisualizerSettingsModal: React.FC<
|
|||
|
||||
{/* Color */}
|
||||
<div>
|
||||
<label className="block text-xs font-bold text-gray-400 uppercase mb-2">
|
||||
<label className="block text-xs font-bold text-kodo-content-dim uppercase mb-2">
|
||||
Accent Color
|
||||
</label>
|
||||
<div className="flex gap-3">
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ export const SearchBar: React.FC<SearchBarProps> = ({
|
|||
className={`flex items-center bg-kodo-ink border rounded-xl px-4 py-3 transition-all ${isFocused ? 'border-kodo-cyan shadow-neon-cyan/10 ring-1 ring-kodo-cyan/20' : 'border-kodo-steel'}`}
|
||||
>
|
||||
<Search
|
||||
className={`w-5 h-5 mr-3 transition-colors ${isFocused ? 'text-kodo-cyan' : 'text-gray-500'}`}
|
||||
className={`w-5 h-5 mr-3 transition-colors ${isFocused ? 'text-kodo-cyan' : 'text-kodo-content-dim'}`}
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
|
|
@ -109,7 +109,7 @@ export const SearchBar: React.FC<SearchBarProps> = ({
|
|||
<button
|
||||
type="button"
|
||||
onClick={() => setQuery('')}
|
||||
className="text-gray-500 hover:text-white transition-colors"
|
||||
className="text-kodo-content-dim hover:text-white transition-colors"
|
||||
>
|
||||
<X className="w-4 h-4" />
|
||||
</button>
|
||||
|
|
@ -123,7 +123,7 @@ export const SearchBar: React.FC<SearchBarProps> = ({
|
|||
<div>
|
||||
{filteredSuggestions.length > 0 ? (
|
||||
<div className="py-2">
|
||||
<div className="px-4 py-2 text-[10px] font-bold text-gray-500 uppercase">
|
||||
<div className="px-4 py-2 text-[10px] font-bold text-kodo-content-dim uppercase">
|
||||
Top Results
|
||||
</div>
|
||||
{filteredSuggestions.map((item, i) => (
|
||||
|
|
@ -132,14 +132,14 @@ export const SearchBar: React.FC<SearchBarProps> = ({
|
|||
className="px-4 py-2 hover:bg-white/5 cursor-pointer flex items-center gap-3 transition-colors"
|
||||
onClick={() => handleSuggestionClick(item.label)}
|
||||
>
|
||||
<div className="w-8 h-8 rounded bg-kodo-slate flex items-center justify-center text-gray-400">
|
||||
<div className="w-8 h-8 rounded bg-kodo-slate flex items-center justify-center text-kodo-content-dim">
|
||||
{getIcon(item.type)}
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-sm font-bold text-white">
|
||||
{item.label}
|
||||
</div>
|
||||
<div className="text-xs text-gray-500 capitalize">
|
||||
<div className="text-xs text-kodo-content-dim capitalize">
|
||||
{item.type}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -147,7 +147,7 @@ export const SearchBar: React.FC<SearchBarProps> = ({
|
|||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="p-4 text-center text-gray-500 text-sm">
|
||||
<div className="p-4 text-center text-kodo-content-dim text-sm">
|
||||
No results found for "{query}"
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -155,7 +155,7 @@ export const SearchBar: React.FC<SearchBarProps> = ({
|
|||
) : (
|
||||
<div className="py-2">
|
||||
<div className="px-4 py-2 flex justify-between items-center">
|
||||
<span className="text-[10px] font-bold text-gray-500 uppercase">
|
||||
<span className="text-[10px] font-bold text-kodo-content-dim uppercase">
|
||||
Recent Searches
|
||||
</span>
|
||||
<button
|
||||
|
|
@ -171,11 +171,11 @@ export const SearchBar: React.FC<SearchBarProps> = ({
|
|||
className="px-4 py-2 hover:bg-white/5 cursor-pointer flex items-center justify-between group transition-colors"
|
||||
onClick={() => handleSuggestionClick(term)}
|
||||
>
|
||||
<div className="flex items-center gap-3 text-gray-300 group-hover:text-white">
|
||||
<Clock className="w-4 h-4 text-gray-500" />
|
||||
<div className="flex items-center gap-3 text-kodo-text-main group-hover:text-white">
|
||||
<Clock className="w-4 h-4 text-kodo-content-dim" />
|
||||
<span className="text-sm">{term}</span>
|
||||
</div>
|
||||
<ArrowUpRight className="w-3 h-3 text-gray-600 opacity-0 group-hover:opacity-100" />
|
||||
<ArrowUpRight className="w-3 h-3 text-kodo-content-dim opacity-0 group-hover:opacity-100" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ export const CreateProductView: React.FC = () => {
|
|||
<h2 className="text-2xl font-display font-bold text-white mb-2">
|
||||
CREATE PRODUCT
|
||||
</h2>
|
||||
<p className="text-gray-400 font-mono text-sm">
|
||||
<p className="text-kodo-content-dim font-mono text-sm">
|
||||
Upload and monetize your sound assets.
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -83,11 +83,11 @@ export const CreateProductView: React.FC = () => {
|
|||
<h3 className="font-bold text-white mb-4 flex items-center gap-2 text-sm uppercase tracking-wider">
|
||||
<ImageIcon className="w-4 h-4 text-kodo-cyan" /> Cover Art
|
||||
</h3>
|
||||
<div className="aspect-square bg-kodo-ink border-2 border-dashed border-kodo-steel rounded-xl flex flex-col items-center justify-center text-gray-500 hover:text-white hover:border-kodo-cyan cursor-pointer transition-colors group">
|
||||
<div className="aspect-square bg-kodo-ink border-2 border-dashed border-kodo-steel rounded-xl flex flex-col items-center justify-center text-kodo-content-dim hover:text-white hover:border-kodo-cyan cursor-pointer transition-colors group">
|
||||
<UploadCloud className="w-8 h-8 mb-2 group-hover:scale-110 transition-transform" />
|
||||
<span className="text-xs font-bold uppercase">Upload Image</span>
|
||||
</div>
|
||||
<p className="text-xs text-gray-500 mt-2 text-center">
|
||||
<p className="text-xs text-kodo-content-dim mt-2 text-center">
|
||||
3000x3000px JPG/PNG
|
||||
</p>
|
||||
</Card>
|
||||
|
|
@ -98,21 +98,21 @@ export const CreateProductView: React.FC = () => {
|
|||
</h3>
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<label className="text-xs text-gray-400 mb-1 block">
|
||||
<label className="text-xs text-kodo-content-dim mb-1 block">
|
||||
Main File (ZIP/RAR)
|
||||
</label>
|
||||
<div className="h-20 bg-kodo-ink border border-kodo-steel rounded-lg flex items-center justify-center cursor-pointer hover:border-gray-500">
|
||||
<span className="text-xs text-gray-500">
|
||||
<div className="h-20 bg-kodo-ink border border-kodo-steel rounded-lg flex items-center justify-center cursor-pointer hover:border-kodo-steel">
|
||||
<span className="text-xs text-kodo-content-dim">
|
||||
Drop full product here
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-xs text-gray-400 mb-1 block">
|
||||
<label className="text-xs text-kodo-content-dim mb-1 block">
|
||||
Audio Preview (MP3)
|
||||
</label>
|
||||
<div className="h-12 bg-kodo-ink border border-kodo-steel rounded-lg flex items-center justify-center cursor-pointer hover:border-gray-500">
|
||||
<span className="text-xs text-gray-500">
|
||||
<div className="h-12 bg-kodo-ink border border-kodo-steel rounded-lg flex items-center justify-center cursor-pointer hover:border-kodo-steel">
|
||||
<span className="text-xs text-kodo-content-dim">
|
||||
Drop preview audio
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -136,7 +136,7 @@ export const CreateProductView: React.FC = () => {
|
|||
/>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-400 mb-2">
|
||||
<label className="block text-sm font-medium text-kodo-content-dim mb-2">
|
||||
Description
|
||||
</label>
|
||||
<textarea
|
||||
|
|
@ -149,7 +149,7 @@ export const CreateProductView: React.FC = () => {
|
|||
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-400 mb-2">
|
||||
<label className="block text-sm font-medium text-kodo-content-dim mb-2">
|
||||
Category
|
||||
</label>
|
||||
<select
|
||||
|
|
@ -186,10 +186,10 @@ export const CreateProductView: React.FC = () => {
|
|||
onChange={(e) => setKey(e.target.value)}
|
||||
/>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-400 mb-2">
|
||||
<label className="block text-sm font-medium text-kodo-content-dim mb-2">
|
||||
Format
|
||||
</label>
|
||||
<div className="p-3 bg-kodo-ink border border-kodo-steel rounded-lg text-gray-400 text-sm">
|
||||
<div className="p-3 bg-kodo-ink border border-kodo-steel rounded-lg text-kodo-content-dim text-sm">
|
||||
WAV 24-bit
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -214,7 +214,7 @@ export const CreateProductView: React.FC = () => {
|
|||
onClick={() =>
|
||||
updateLicense(lic.type, 'enabled', !lic.enabled)
|
||||
}
|
||||
className={`w-10 h-5 rounded-full relative cursor-pointer transition-colors ${lic.enabled ? 'bg-kodo-cyan' : 'bg-gray-600'}`}
|
||||
className={`w-10 h-5 rounded-full relative cursor-pointer transition-colors ${lic.enabled ? 'bg-kodo-cyan' : 'bg-kodo-steel'}`}
|
||||
>
|
||||
<div
|
||||
className={`absolute top-1 w-3 h-3 bg-white rounded-full transition-all ${lic.enabled ? 'left-6' : 'left-1'}`}
|
||||
|
|
@ -224,7 +224,7 @@ export const CreateProductView: React.FC = () => {
|
|||
<div className="font-bold text-white capitalize">
|
||||
{lic.type} License
|
||||
</div>
|
||||
<div className="text-xs text-gray-400">
|
||||
<div className="text-xs text-kodo-content-dim">
|
||||
{lic.type === 'personal' &&
|
||||
'Royalty-free for non-commercial use.'}
|
||||
{lic.type === 'commercial' &&
|
||||
|
|
@ -236,7 +236,7 @@ export const CreateProductView: React.FC = () => {
|
|||
</div>
|
||||
<div className="w-32">
|
||||
<div className="relative">
|
||||
<span className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-500">
|
||||
<span className="absolute left-3 top-1/2 -translate-y-1/2 text-kodo-content-dim">
|
||||
$
|
||||
</span>
|
||||
<input
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ export const SellerDashboardView: React.FC<SellerDashboardProps> = ({
|
|||
<h2 className="text-2xl font-display font-bold text-white mb-2">
|
||||
SELLER DASHBOARD
|
||||
</h2>
|
||||
<p className="text-gray-400 font-mono text-sm">
|
||||
<p className="text-kodo-content-dim font-mono text-sm">
|
||||
Manage your products, sales, and analytics.
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -100,7 +100,7 @@ export const SellerDashboardView: React.FC<SellerDashboardProps> = ({
|
|||
<div className="absolute right-0 top-0 p-4 opacity-10 group-hover:opacity-20 transition-opacity">
|
||||
<DollarSign className="w-16 h-16 text-kodo-gold" />
|
||||
</div>
|
||||
<div className="text-gray-400 text-xs font-bold uppercase mb-1">
|
||||
<div className="text-kodo-content-dim text-xs font-bold uppercase mb-1">
|
||||
Total Revenue
|
||||
</div>
|
||||
<div className="text-3xl font-mono font-bold text-white mb-2">
|
||||
|
|
@ -115,7 +115,7 @@ export const SellerDashboardView: React.FC<SellerDashboardProps> = ({
|
|||
<div className="absolute right-0 top-0 p-4 opacity-10 group-hover:opacity-20 transition-opacity">
|
||||
<Package className="w-16 h-16 text-kodo-cyan" />
|
||||
</div>
|
||||
<div className="text-gray-400 text-xs font-bold uppercase mb-1">
|
||||
<div className="text-kodo-content-dim text-xs font-bold uppercase mb-1">
|
||||
Total Sales
|
||||
</div>
|
||||
<div className="text-3xl font-mono font-bold text-white mb-2">
|
||||
|
|
@ -130,7 +130,7 @@ export const SellerDashboardView: React.FC<SellerDashboardProps> = ({
|
|||
<div className="absolute right-0 top-0 p-4 opacity-10 group-hover:opacity-20 transition-opacity">
|
||||
<Eye className="w-16 h-16 text-kodo-magenta" />
|
||||
</div>
|
||||
<div className="text-gray-400 text-xs font-bold uppercase mb-1">
|
||||
<div className="text-kodo-content-dim text-xs font-bold uppercase mb-1">
|
||||
Page Views
|
||||
</div>
|
||||
<div className="text-3xl font-mono font-bold text-white mb-2">
|
||||
|
|
@ -147,7 +147,7 @@ export const SellerDashboardView: React.FC<SellerDashboardProps> = ({
|
|||
<div className="absolute right-0 top-0 p-4 opacity-10 group-hover:opacity-20 transition-opacity">
|
||||
<Users className="w-16 h-16 text-white" />
|
||||
</div>
|
||||
<div className="text-gray-400 text-xs font-bold uppercase mb-1">
|
||||
<div className="text-kodo-content-dim text-xs font-bold uppercase mb-1">
|
||||
Conversion Rate
|
||||
</div>
|
||||
<div className="text-3xl font-mono font-bold text-white mb-2">
|
||||
|
|
@ -175,7 +175,7 @@ export const SellerDashboardView: React.FC<SellerDashboardProps> = ({
|
|||
key={product.id}
|
||||
className="flex items-center gap-4 p-3 bg-kodo-ink rounded-lg border border-transparent hover:border-kodo-steel transition-all"
|
||||
>
|
||||
<div className="w-8 text-center font-mono text-gray-500">
|
||||
<div className="w-8 text-center font-mono text-kodo-content-dim">
|
||||
{i + 1}
|
||||
</div>
|
||||
<img
|
||||
|
|
@ -186,7 +186,7 @@ export const SellerDashboardView: React.FC<SellerDashboardProps> = ({
|
|||
<div className="font-bold text-white truncate">
|
||||
{product.title}
|
||||
</div>
|
||||
<div className="text-xs text-gray-400">
|
||||
<div className="text-xs text-kodo-content-dim">
|
||||
{product.reviewCount} reviews • {product.rating} stars
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -219,11 +219,11 @@ export const SellerDashboardView: React.FC<SellerDashboardProps> = ({
|
|||
<div className="text-sm text-white font-bold">
|
||||
{sale.product}
|
||||
</div>
|
||||
<div className="text-xs text-gray-400 flex justify-between mt-1">
|
||||
<div className="text-xs text-kodo-content-dim flex justify-between mt-1">
|
||||
<span>{sale.buyer}</span>
|
||||
<span>${sale.amount}</span>
|
||||
</div>
|
||||
<div className="text-[10px] text-gray-500 mt-1">
|
||||
<div className="text-[10px] text-kodo-content-dim mt-1">
|
||||
{sale.date}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ export const FlashSaleModal: React.FC<FlashSaleModalProps> = ({
|
|||
<Zap className="w-5 h-5 text-kodo-gold" /> Start Flash Sale
|
||||
</h3>
|
||||
<button onClick={onClose}>
|
||||
<X className="w-5 h-5 text-gray-400 hover:text-white" />
|
||||
<X className="w-5 h-5 text-kodo-content-dim hover:text-white" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
|
@ -55,11 +55,11 @@ export const FlashSaleModal: React.FC<FlashSaleModalProps> = ({
|
|||
{/* Left: Configuration */}
|
||||
<div className="w-full md:w-1/2 space-y-6">
|
||||
<div>
|
||||
<label className="block text-xs font-bold text-gray-400 uppercase mb-2">
|
||||
<label className="block text-xs font-bold text-kodo-content-dim uppercase mb-2">
|
||||
Discount Percentage
|
||||
</label>
|
||||
<div className="relative">
|
||||
<Percent className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-500" />
|
||||
<Percent className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-kodo-content-dim" />
|
||||
<input
|
||||
type="number"
|
||||
className="w-full bg-kodo-void border border-kodo-steel rounded pl-10 pr-4 py-2 text-white focus:border-kodo-gold outline-none"
|
||||
|
|
@ -72,11 +72,11 @@ export const FlashSaleModal: React.FC<FlashSaleModalProps> = ({
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-xs font-bold text-gray-400 uppercase mb-2">
|
||||
<label className="block text-xs font-bold text-kodo-content-dim uppercase mb-2">
|
||||
Duration (Hours)
|
||||
</label>
|
||||
<div className="relative">
|
||||
<Calendar className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-500" />
|
||||
<Calendar className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-kodo-content-dim" />
|
||||
<select
|
||||
className="w-full bg-kodo-void border border-kodo-steel rounded pl-10 pr-4 py-2 text-white focus:border-kodo-gold outline-none appearance-none"
|
||||
value={duration}
|
||||
|
|
@ -96,7 +96,7 @@ export const FlashSaleModal: React.FC<FlashSaleModalProps> = ({
|
|||
<h4 className="text-kodo-gold font-bold text-sm mb-1">
|
||||
Impact Summary
|
||||
</h4>
|
||||
<p className="text-xs text-gray-300">
|
||||
<p className="text-xs text-kodo-text-main">
|
||||
Applying a{' '}
|
||||
<span className="font-bold text-white">{discount}%</span>{' '}
|
||||
discount to{' '}
|
||||
|
|
@ -111,7 +111,7 @@ export const FlashSaleModal: React.FC<FlashSaleModalProps> = ({
|
|||
{/* Right: Product Selection */}
|
||||
<div className="w-full md:w-1/2 flex flex-col">
|
||||
<div className="flex justify-between items-center mb-2">
|
||||
<label className="block text-xs font-bold text-gray-400 uppercase">
|
||||
<label className="block text-xs font-bold text-kodo-content-dim uppercase">
|
||||
Select Products
|
||||
</label>
|
||||
<button
|
||||
|
|
@ -138,7 +138,7 @@ export const FlashSaleModal: React.FC<FlashSaleModalProps> = ({
|
|||
onClick={() => toggleProduct(product.id)}
|
||||
>
|
||||
<div
|
||||
className={`text-gray-500 ${selectedIds.includes(product.id) ? 'text-kodo-gold' : ''}`}
|
||||
className={`text-kodo-content-dim ${selectedIds.includes(product.id) ? 'text-kodo-gold' : ''}`}
|
||||
>
|
||||
{selectedIds.includes(product.id) ? (
|
||||
<CheckSquare className="w-4 h-4" />
|
||||
|
|
@ -154,7 +154,7 @@ export const FlashSaleModal: React.FC<FlashSaleModalProps> = ({
|
|||
<div className="text-sm font-bold text-white truncate">
|
||||
{product.title}
|
||||
</div>
|
||||
<div className="text-xs text-gray-500">
|
||||
<div className="text-xs text-kodo-content-dim">
|
||||
${product.price}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ export const AccessibilitySettingsView: React.FC = () => {
|
|||
<h2 className="text-3xl font-display font-bold text-white mb-2">
|
||||
ACCESSIBILITY
|
||||
</h2>
|
||||
<p className="text-gray-400 font-mono text-sm">
|
||||
<p className="text-kodo-content-dim font-mono text-sm">
|
||||
Tools to make the platform work for you.
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -132,7 +132,7 @@ const ToggleRow: React.FC<{
|
|||
<div className="text-sm font-bold text-white group-hover:text-kodo-cyan transition-colors">
|
||||
{label}
|
||||
</div>
|
||||
<div className="text-xs text-gray-400">{desc}</div>
|
||||
<div className="text-xs text-kodo-content-dim">{desc}</div>
|
||||
</div>
|
||||
<Switch checked={active} onChange={onToggle} />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -11,14 +11,14 @@ export function EmailVerificationBadge({
|
|||
}: EmailVerificationBadgeProps) {
|
||||
if (verified) {
|
||||
return (
|
||||
<span className="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-kodo-lime/20 text-green-800 dark:bg-green-900 dark:text-green-200">
|
||||
<span className="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-kodo-lime/20 text-kodo-lime dark:bg-kodo-lime/20 dark:text-kodo-lime">
|
||||
✓ Email Verified
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<span className="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200">
|
||||
<span className="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-kodo-gold/20 text-kodo-gold dark:bg-kodo-gold/20 dark:text-kodo-gold">
|
||||
⚠ Email Not Verified
|
||||
</span>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -52,16 +52,16 @@ export function PasswordStrengthIndicator({
|
|||
color = 'bg-kodo-red';
|
||||
} else if (strength === 2) {
|
||||
label = 'Faible';
|
||||
color = 'bg-orange-500';
|
||||
color = 'bg-kodo-gold';
|
||||
} else if (strength === 3) {
|
||||
label = 'Moyen';
|
||||
color = 'bg-yellow-500';
|
||||
color = 'bg-kodo-gold';
|
||||
} else if (strength === 4) {
|
||||
label = 'Fort';
|
||||
color = 'bg-kodo-lime/100';
|
||||
} else {
|
||||
label = 'Très fort';
|
||||
color = 'bg-green-600';
|
||||
color = 'bg-kodo-lime';
|
||||
}
|
||||
|
||||
return { level: strength, label, color, requirements };
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ export function ForgotPasswordPage() {
|
|||
>
|
||||
{error && (
|
||||
<div
|
||||
className="bg-red-50 border border-kodo-red text-kodo-red px-4 py-3 rounded"
|
||||
className="bg-kodo-red/10 border border-kodo-red text-kodo-red px-4 py-3 rounded"
|
||||
role="alert"
|
||||
aria-live="assertive"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@ export function LoginPage() {
|
|||
>
|
||||
{error && (
|
||||
<div
|
||||
className="bg-red-50 border border-kodo-red text-kodo-red px-4 py-3 rounded"
|
||||
className="bg-kodo-red/10 border border-kodo-red text-kodo-red px-4 py-3 rounded"
|
||||
role="alert"
|
||||
aria-live="assertive"
|
||||
aria-atomic="true"
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ export function RegisterPage() {
|
|||
>
|
||||
{error && (
|
||||
<div
|
||||
className="bg-red-50 border border-kodo-red text-kodo-red px-4 py-3 rounded"
|
||||
className="bg-kodo-red/10 border border-kodo-red text-kodo-red px-4 py-3 rounded"
|
||||
role="alert"
|
||||
aria-live="assertive"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ export function ResetPasswordPage() {
|
|||
role="alert"
|
||||
aria-live="assertive"
|
||||
>
|
||||
<div className="bg-red-50 border border-kodo-red text-kodo-red px-4 py-3 rounded">
|
||||
<div className="bg-kodo-red/10 border border-kodo-red text-kodo-red px-4 py-3 rounded">
|
||||
<p className="font-medium">Lien invalide</p>
|
||||
<p className="text-sm mt-1">
|
||||
Le lien de réinitialisation est invalide ou a expiré. Veuillez
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@ export function VerifyEmailPage() {
|
|||
>
|
||||
<div className="text-center space-y-4">
|
||||
<div
|
||||
className="bg-red-50 border border-kodo-red text-kodo-red px-4 py-3 rounded"
|
||||
className="bg-kodo-red/10 border border-kodo-red text-kodo-red px-4 py-3 rounded"
|
||||
role="alert"
|
||||
aria-live="assertive"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ function DashboardPage() {
|
|||
value: '45',
|
||||
change: '+5%',
|
||||
icon: Users,
|
||||
color: 'text-purple-600',
|
||||
color: 'text-kodo-magenta',
|
||||
},
|
||||
];
|
||||
|
||||
|
|
@ -111,7 +111,7 @@ function DashboardPage() {
|
|||
</div>
|
||||
</div>
|
||||
<div className="flex items-center space-x-4">
|
||||
<div className="w-2 h-2 bg-green-600 rounded-full"></div>
|
||||
<div className="w-2 h-2 bg-kodo-lime rounded-full"></div>
|
||||
<div className="flex-1 space-y-1">
|
||||
<p className="text-sm font-medium">Message reçu de @alice</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
|
|
@ -120,7 +120,7 @@ function DashboardPage() {
|
|||
</div>
|
||||
</div>
|
||||
<div className="flex items-center space-x-4">
|
||||
<div className="w-2 h-2 bg-purple-600 rounded-full"></div>
|
||||
<div className="w-2 h-2 bg-kodo-magenta rounded-full"></div>
|
||||
<div className="flex-1 space-y-1">
|
||||
<p className="text-sm font-medium">Nouveau favori ajouté</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ function ServerErrorPage() {
|
|||
<div className="w-full max-w-2xl">
|
||||
<Card className="text-center">
|
||||
<CardHeader>
|
||||
<div className="mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-red-100 dark:bg-red-900">
|
||||
<div className="mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-kodo-red/10 dark:bg-kodo-red/20">
|
||||
<AlertTriangle className="h-8 w-8 text-kodo-red dark:text-kodo-red" />
|
||||
</div>
|
||||
<CardTitle className="text-2xl">Erreur serveur</CardTitle>
|
||||
|
|
@ -60,7 +60,7 @@ function ServerErrorPage() {
|
|||
</p>
|
||||
|
||||
{/* Status Info */}
|
||||
<div className="bg-kodo-cyan/10 dark:bg-kodo-cyan/20 border border-kodo-cyan dark:border-blue-800 rounded-lg p-4">
|
||||
<div className="bg-kodo-cyan/10 dark:bg-kodo-cyan/20 border border-kodo-cyan dark:border-kodo-cyan rounded-lg p-4">
|
||||
<div className="flex items-start gap-3 text-left">
|
||||
<Clock className="h-5 w-5 text-kodo-cyan dark:text-kodo-cyan mt-0.5" />
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ export function PlaylistBatchActions({
|
|||
<div
|
||||
className={cn(
|
||||
'flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 sm:gap-4',
|
||||
'p-4 bg-kodo-cyan/10 dark:bg-kodo-cyan/20 border border-kodo-cyan dark:border-blue-800 rounded-lg',
|
||||
'p-4 bg-kodo-cyan/10 dark:bg-kodo-cyan/20 border border-kodo-cyan dark:border-kodo-cyan rounded-lg',
|
||||
'sticky top-0 z-10 backdrop-blur-sm',
|
||||
className,
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ export function PlaybackSummary({ trackId, className }: PlaybackSummaryProps) {
|
|||
<CardTitle className="text-sm font-medium">
|
||||
Taux de complétion
|
||||
</CardTitle>
|
||||
<CheckCircle2 className="h-4 w-4 text-purple-600" />
|
||||
<CheckCircle2 className="h-4 w-4 text-kodo-magenta" />
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">
|
||||
|
|
|
|||
|
|
@ -126,11 +126,11 @@ export function TrackHistory({
|
|||
case 'updated':
|
||||
return 'text-kodo-cyan bg-kodo-cyan/10';
|
||||
case 'deleted':
|
||||
return 'text-kodo-red bg-red-50';
|
||||
return 'text-kodo-red bg-kodo-red/10';
|
||||
case 'published':
|
||||
return 'text-purple-600 bg-purple-50';
|
||||
return 'text-kodo-magenta bg-kodo-magenta/10';
|
||||
case 'unpublished':
|
||||
return 'text-orange-600 bg-orange-50';
|
||||
return 'text-kodo-gold bg-kodo-gold/10';
|
||||
case 'restored':
|
||||
return 'text-cyan-600 bg-cyan-50';
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ export function TrackListEmpty({
|
|||
className={cn(
|
||||
'text-lg font-semibold mb-2',
|
||||
determinedType === 'error'
|
||||
? 'text-red-900 dark:text-red-100'
|
||||
? 'text-kodo-red dark:text-kodo-red'
|
||||
: 'text-kodo-text-main dark:text-white',
|
||||
)}
|
||||
>
|
||||
|
|
@ -114,7 +114,7 @@ export function TrackListEmpty({
|
|||
className={cn(
|
||||
'text-sm max-w-md mb-4',
|
||||
determinedType === 'error'
|
||||
? 'text-kodo-red dark:text-red-300'
|
||||
? 'text-kodo-red dark:text-kodo-red'
|
||||
: 'text-kodo-content-dim dark:text-kodo-content-dim',
|
||||
)}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ export function UploadQuota({
|
|||
className={cn(
|
||||
'text-sm font-medium',
|
||||
isQuotaExceeded && 'text-destructive',
|
||||
isQuotaNearLimit && !isQuotaExceeded && 'text-yellow-600',
|
||||
isQuotaNearLimit && !isQuotaExceeded && 'text-kodo-gold',
|
||||
)}
|
||||
>
|
||||
{quota.tracks_count} / {quota.tracks_limit}
|
||||
|
|
@ -139,7 +139,7 @@ export function UploadQuota({
|
|||
value={Math.min(tracksPercent, 100)}
|
||||
className={cn(
|
||||
isQuotaExceeded && '[&>div]:bg-destructive',
|
||||
isQuotaNearLimit && !isQuotaExceeded && '[&>div]:bg-yellow-500',
|
||||
isQuotaNearLimit && !isQuotaExceeded && '[&>div]:bg-kodo-gold',
|
||||
)}
|
||||
/>
|
||||
{isQuotaExceeded && (
|
||||
|
|
@ -160,7 +160,7 @@ export function UploadQuota({
|
|||
className={cn(
|
||||
'text-sm font-medium',
|
||||
isQuotaExceeded && 'text-destructive',
|
||||
isQuotaNearLimit && !isQuotaExceeded && 'text-yellow-600',
|
||||
isQuotaNearLimit && !isQuotaExceeded && 'text-kodo-gold',
|
||||
)}
|
||||
>
|
||||
{formatFileSize(quota.storage_used)} /{' '}
|
||||
|
|
@ -171,7 +171,7 @@ export function UploadQuota({
|
|||
value={Math.min(storagePercent, 100)}
|
||||
className={cn(
|
||||
isQuotaExceeded && '[&>div]:bg-destructive',
|
||||
isQuotaNearLimit && !isQuotaExceeded && '[&>div]:bg-yellow-500',
|
||||
isQuotaNearLimit && !isQuotaExceeded && '[&>div]:bg-kodo-gold',
|
||||
)}
|
||||
/>
|
||||
{isQuotaExceeded && (
|
||||
|
|
@ -183,7 +183,7 @@ export function UploadQuota({
|
|||
|
||||
{/* Warning message if quota is near limit */}
|
||||
{isQuotaNearLimit && !isQuotaExceeded && (
|
||||
<div className="flex items-start gap-2 p-2 bg-yellow-50 dark:bg-yellow-900/20 rounded-md text-xs text-yellow-800 dark:text-yellow-200">
|
||||
<div className="flex items-start gap-2 p-2 bg-kodo-gold/10 dark:bg-kodo-gold/20 rounded-md text-xs text-kodo-gold dark:text-kodo-gold">
|
||||
<AlertCircle className="h-4 w-4 shrink-0 mt-0.5" />
|
||||
<span>
|
||||
Votre quota d'upload approche de sa limite. Pensez à libérer de
|
||||
|
|
|
|||
Loading…
Reference in a new issue