linguabot commited on
Commit
551780e
·
verified ·
1 Parent(s): 6e0c85e

Upload folder using huggingface_hub

Browse files
client/src/components/HitokotoBar.tsx CHANGED
@@ -62,16 +62,16 @@ const HitokotoBar: React.FC = () => {
62
  return (
63
  <div className="fixed bottom-0 right-0 z-50 w-[calc(100%-240px)] md:w-[calc(100%-240px)]">
64
  <div className="ml-auto max-w-7xl px-4 sm:px-6 lg:px-8 pb-3">
65
- <div className="bg-white border border-ui-bg shadow-md rounded-lg px-4 py-2 flex items-center justify-between">
66
  <div className="flex items-center min-w-0">
67
  <span className="mr-2 text-ui-navy">💬</span>
68
  <div className="min-w-0">
69
  {loading ? (
70
- <div className="text-sm text-ui-navy/70">Loading…</div>
71
  ) : error ? (
72
- <div className="text-sm text-red-600">{error}</div>
73
  ) : (
74
- <div className="text-sm text-ui-navy truncate">
75
  {quote ? `『${quote.hitokoto}』 — ${quote.from_who || quote.from || 'Hitokoto'}` : ' '}
76
  </div>
77
  )}
@@ -80,14 +80,14 @@ const HitokotoBar: React.FC = () => {
80
  <div className="flex items-center space-x-2 flex-shrink-0">
81
  <button
82
  onClick={fetchQuote}
83
- className="text-xs px-2 py-1 rounded bg-ui-bg hover:bg-white border border-ui-bg text-ui-navy"
84
  title="Next quote"
85
  >
86
  Next
87
  </button>
88
  <button
89
  onClick={() => { setHidden(true); localStorage.setItem(LOCAL_HIDE_KEY, '1'); }}
90
- className="text-xs px-2 py-1 rounded bg-ui-bg hover:bg-white border border-ui-bg text-ui-navy"
91
  title="Hide"
92
  >
93
  Hide
 
62
  return (
63
  <div className="fixed bottom-0 right-0 z-50 w-[calc(100%-240px)] md:w-[calc(100%-240px)]">
64
  <div className="ml-auto max-w-7xl px-4 sm:px-6 lg:px-8 pb-3">
65
+ <div className="bg-ui-panel border border-ui-border shadow-md rounded-lg px-4 py-2 flex items-center justify-between">
66
  <div className="flex items-center min-w-0">
67
  <span className="mr-2 text-ui-navy">💬</span>
68
  <div className="min-w-0">
69
  {loading ? (
70
+ <div className="text-sm text-ui-text/70">Loading…</div>
71
  ) : error ? (
72
+ <div className="text-sm text-red-400">{error}</div>
73
  ) : (
74
+ <div className="text-sm text-ui-text truncate">
75
  {quote ? `『${quote.hitokoto}』 — ${quote.from_who || quote.from || 'Hitokoto'}` : ' '}
76
  </div>
77
  )}
 
80
  <div className="flex items-center space-x-2 flex-shrink-0">
81
  <button
82
  onClick={fetchQuote}
83
+ className="text-xs px-2 py-1 rounded bg-ui-panel hover:bg-ui-panel/80 border border-ui-border text-ui-text"
84
  title="Next quote"
85
  >
86
  Next
87
  </button>
88
  <button
89
  onClick={() => { setHidden(true); localStorage.setItem(LOCAL_HIDE_KEY, '1'); }}
90
+ className="text-xs px-2 py-1 rounded bg-ui-panel hover:bg-ui-panel/80 border border-ui-border text-ui-text"
91
  title="Hide"
92
  >
93
  Hide
client/src/components/Layout.tsx CHANGED
@@ -163,11 +163,11 @@ const Layout: React.FC<{ children: React.ReactNode }> = ({ children }) => {
163
  }
164
 
165
  return (
166
- <div className="min-h-screen bg-ui-bg text-ui-navy">
167
  {/* Top Bar */}
168
- <header className="sticky top-0 z-40 bg-white/80 backdrop-blur border-b border-ui-bg">
169
  <div className="px-4 sm:px-6 lg:px-8 h-14 flex items-center justify-between">
170
- <Link to="/dashboard" className="text-lg font-bold text-ui-navy">TransHub</Link>
171
  <div />
172
  </div>
173
  </header>
@@ -175,7 +175,7 @@ const Layout: React.FC<{ children: React.ReactNode }> = ({ children }) => {
175
  {/* Shell: Sidebar + Content */}
176
  <div className="flex">
177
  {/* Sidebar */}
178
- <aside className="hidden md:flex md:flex-col w-60 min-h-[calc(100vh-56px)] border-r border-ui-bg bg-white">
179
  <nav className="p-3 space-y-1 flex-1">
180
  {navigation.map((item) => {
181
  const isActive = location.pathname === item.href;
@@ -184,7 +184,7 @@ const Layout: React.FC<{ children: React.ReactNode }> = ({ children }) => {
184
  key={item.name}
185
  to={item.href}
186
  className={`flex items-center px-3 py-2 rounded-md text-sm font-medium transition-colors ${
187
- isActive ? 'bg-white text-ui-navy shadow-sm' : 'text-ui-navy/80 hover:bg-ui-bg'
188
  }`}
189
  >
190
  <item.icon className="h-4 w-4 mr-2" />
@@ -193,14 +193,14 @@ const Layout: React.FC<{ children: React.ReactNode }> = ({ children }) => {
193
  );
194
  })}
195
  </nav>
196
- <div className="p-3 border-t border-ui-bg">
197
  {user ? (
198
- <button onClick={handleLogout} className="w-full flex items-center justify-start px-3 py-2 rounded-md text-sm font-medium text-ui-navy/80 hover:bg-ui-bg">
199
  <PowerIcon className="h-4 w-4 mr-2" />
200
  Log Out
201
  </button>
202
  ) : (
203
- <Link to="/login" className="w-full flex items-center justify-start px-3 py-2 rounded-md text-sm font-medium text-ui-navy/80 hover:bg-ui-bg">
204
  <PowerIcon className="h-4 w-4 mr-2" />
205
  Log In
206
  </Link>
@@ -217,9 +217,9 @@ const Layout: React.FC<{ children: React.ReactNode }> = ({ children }) => {
217
  {/* Transition Loading Indicator */}
218
  {isTransitioning && (
219
  <div className="fixed top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 z-50">
220
- <div className="bg-white rounded-lg shadow-lg p-4 flex items-center space-x-3">
221
- <div className="animate-spin rounded-full h-6 w-6 border-b-2 border-ui-navy"></div>
222
- <span className="text-ui-navy font-medium">Loading...</span>
223
  </div>
224
  </div>
225
  )}
 
163
  }
164
 
165
  return (
166
+ <div className="min-h-screen bg-ui-bg text-ui-text">
167
  {/* Top Bar */}
168
+ <header className="sticky top-0 z-40 bg-ui-panel/80 backdrop-blur border-b border-ui-border">
169
  <div className="px-4 sm:px-6 lg:px-8 h-14 flex items-center justify-between">
170
+ <Link to="/dashboard" className="text-lg font-bold text-ui-neonCyan">TransHub</Link>
171
  <div />
172
  </div>
173
  </header>
 
175
  {/* Shell: Sidebar + Content */}
176
  <div className="flex">
177
  {/* Sidebar */}
178
+ <aside className="hidden md:flex md:flex-col w-60 min-h-[calc(100vh-56px)] border-r border-ui-border bg-ui-panel">
179
  <nav className="p-3 space-y-1 flex-1">
180
  {navigation.map((item) => {
181
  const isActive = location.pathname === item.href;
 
184
  key={item.name}
185
  to={item.href}
186
  className={`flex items-center px-3 py-2 rounded-md text-sm font-medium transition-colors ${
187
+ isActive ? 'bg-ui-bg text-ui-text neon-border' : 'text-ui-text/80 hover:bg-ui-panel/60'
188
  }`}
189
  >
190
  <item.icon className="h-4 w-4 mr-2" />
 
193
  );
194
  })}
195
  </nav>
196
+ <div className="p-3 border-t border-ui-border">
197
  {user ? (
198
+ <button onClick={handleLogout} className="w-full flex items-center justify-start px-3 py-2 rounded-md text-sm font-medium text-ui-text/80 hover:bg-ui-panel/60">
199
  <PowerIcon className="h-4 w-4 mr-2" />
200
  Log Out
201
  </button>
202
  ) : (
203
+ <Link to="/login" className="w-full flex items-center justify-start px-3 py-2 rounded-md text-sm font-medium text-ui-text/80 hover:bg-ui-panel/60">
204
  <PowerIcon className="h-4 w-4 mr-2" />
205
  Log In
206
  </Link>
 
217
  {/* Transition Loading Indicator */}
218
  {isTransitioning && (
219
  <div className="fixed top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 z-50">
220
+ <div className="bg-ui-panel rounded-lg shadow-lg p-4 flex items-center space-x-3 border border-ui-border">
221
+ <div className="animate-spin rounded-full h-6 w-6 border-b-2 border-ui-neonCyan"></div>
222
+ <span className="text-ui-text font-medium">Loading...</span>
223
  </div>
224
  </div>
225
  )}
client/src/index.css CHANGED
@@ -7,17 +7,17 @@
7
  font-family: 'Inter', system-ui, sans-serif;
8
  }
9
  body {
10
- @apply bg-ui-bg text-ui-navy;
11
  }
12
  }
13
 
14
  @layer components {
15
  .btn-primary {
16
- @apply bg-ui-navy hover:bg-ui-navy/90 text-white font-medium py-2 px-4 rounded-lg transition-colors duration-200;
17
  }
18
 
19
  .btn-secondary {
20
- @apply bg-white hover:bg-ui-bg text-ui-navy font-medium py-2 px-4 rounded-lg border border-ui-bg transition-colors duration-200;
21
  }
22
 
23
  .btn-danger {
@@ -25,11 +25,11 @@
25
  }
26
 
27
  .input-field {
28
- @apply w-full px-3 py-2 border border-ui-bg rounded-lg focus:outline-none focus:ring-2 focus:ring-ui-navy focus:border-transparent;
29
  }
30
 
31
  .card {
32
- @apply bg-white rounded-xl shadow-sm border border-ui-bg p-6;
33
  }
34
 
35
  .highlight-cultural {
@@ -37,7 +37,11 @@
37
  }
38
 
39
  .text-gradient {
40
- @apply bg-gradient-to-r from-ui-navy to-ui-teal bg-clip-text text-transparent;
 
 
 
 
41
  }
42
 
43
  .font-smiley {
 
7
  font-family: 'Inter', system-ui, sans-serif;
8
  }
9
  body {
10
+ @apply bg-ui-bg text-ui-text;
11
  }
12
  }
13
 
14
  @layer components {
15
  .btn-primary {
16
+ @apply bg-ui-neonPink hover:bg-ui-neonPink/90 text-ui-bg font-semibold py-2 px-4 rounded-lg transition-colors duration-200 shadow-[0_0_12px_rgba(255,45,172,0.7)];
17
  }
18
 
19
  .btn-secondary {
20
+ @apply bg-ui-panel hover:bg-ui-panel/80 text-ui-text font-medium py-2 px-4 rounded-lg border border-ui-border transition-colors duration-200;
21
  }
22
 
23
  .btn-danger {
 
25
  }
26
 
27
  .input-field {
28
+ @apply w-full px-3 py-2 border border-ui-border rounded-lg bg-ui-panel text-ui-text placeholder-ui-text/50 focus:outline-none focus:ring-2 focus:ring-ui-neonCyan focus:border-transparent;
29
  }
30
 
31
  .card {
32
+ @apply bg-ui-panel rounded-xl shadow-sm border border-ui-border p-6;
33
  }
34
 
35
  .highlight-cultural {
 
37
  }
38
 
39
  .text-gradient {
40
+ @apply bg-gradient-to-r from-ui-neonPink to-ui-neonCyan bg-clip-text text-transparent;
41
+ }
42
+
43
+ .neon-border {
44
+ box-shadow: 0 0 0 1px theme('colors.ui.border') inset, 0 0 16px rgba(41,243,255,0.35);
45
  }
46
 
47
  .font-smiley {
client/src/pages/Dashboard.tsx CHANGED
@@ -113,15 +113,15 @@ const Dashboard: React.FC = () => {
113
  <div className="mb-8">
114
  <div className="flex items-center justify-between">
115
  <div>
116
- <h1 className="text-3xl font-bold text-ui-navy">{getGreeting()}</h1>
117
- <p className="text-ui-navy/70 mt-2">
118
  Ready to practice your translation skills?
119
  </p>
120
  </div>
121
  <div className="flex items-center space-x-3">
122
- <span className="text-sm text-ui-navy/70">{getRoleDisplay()}</span>
123
  {user.role === 'admin' && (
124
- <span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-ui-gold/20 text-ui-navy border border-ui-bg">
125
  Admin
126
  </span>
127
  )}
@@ -131,21 +131,21 @@ const Dashboard: React.FC = () => {
131
 
132
  {/* Quick Actions */}
133
  <div className="mb-8">
134
- <h2 className="text-lg font-semibold text-ui-navy mb-4">Quick Actions</h2>
135
  <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
136
  {actionsToShow.map((action) => (
137
  <Link
138
  key={action.name}
139
  to={action.href}
140
- className="bg-white rounded-xl shadow-sm border border-ui-bg p-6 hover:shadow-md hover:border-ui-bg transition"
141
  >
142
  <div className="flex items-center">
143
- <div className={`p-3 rounded-lg bg-ui-teal`}>
144
- <action.icon className="h-6 w-6 text-white" />
145
  </div>
146
  <div className="ml-4">
147
- <h3 className="text-lg font-medium text-ui-navy">{action.name}</h3>
148
- <p className="text-ui-navy/70">{action.description}</p>
149
  </div>
150
  </div>
151
  </Link>
@@ -176,23 +176,23 @@ const Dashboard: React.FC = () => {
176
  )}
177
 
178
  {/* Overview */}
179
- <div className="bg-white rounded-xl shadow-sm border border-ui-bg p-6">
180
  <div className="flex items-center mb-4">
181
- <ChartBarIcon className="h-6 w-6 text-ui-navy mr-3" />
182
- <h3 className="text-lg font-semibold text-ui-navy">Course Overview</h3>
183
  </div>
184
  <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
185
  <div className="text-center">
186
- <div className="text-2xl font-bold text-ui-navy">6</div>
187
- <div className="text-sm text-ui-navy/70">Weeks</div>
188
  </div>
189
  <div className="text-center">
190
- <div className="text-2xl font-bold text-ui-navy">2</div>
191
- <div className="text-sm text-ui-navy/70">Task Types</div>
192
  </div>
193
  <div className="text-center">
194
- <div className="text-2xl font-bold text-ui-navy">Voting</div>
195
- <div className="text-sm text-ui-navy/70">Peer Review</div>
196
  </div>
197
  </div>
198
  </div>
 
113
  <div className="mb-8">
114
  <div className="flex items-center justify-between">
115
  <div>
116
+ <h1 className="text-3xl font-bold text-ui-text">{getGreeting()}</h1>
117
+ <p className="text-ui-text/70 mt-2">
118
  Ready to practice your translation skills?
119
  </p>
120
  </div>
121
  <div className="flex items-center space-x-3">
122
+ <span className="text-sm text-ui-text/70">{getRoleDisplay()}</span>
123
  {user.role === 'admin' && (
124
+ <span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-ui-panel text-ui-text border border-ui-border">
125
  Admin
126
  </span>
127
  )}
 
131
 
132
  {/* Quick Actions */}
133
  <div className="mb-8">
134
+ <h2 className="text-lg font-semibold text-ui-text mb-4">Quick Actions</h2>
135
  <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
136
  {actionsToShow.map((action) => (
137
  <Link
138
  key={action.name}
139
  to={action.href}
140
+ className="bg-ui-panel rounded-xl shadow-sm border border-ui-border p-6 hover:shadow-md transition neon-border"
141
  >
142
  <div className="flex items-center">
143
+ <div className={`p-3 rounded-lg bg-ui-neonPink animate-pulse-glow`}>
144
+ <action.icon className="h-6 w-6 text-ui-bg" />
145
  </div>
146
  <div className="ml-4">
147
+ <h3 className="text-lg font-medium text-ui-text">{action.name}</h3>
148
+ <p className="text-ui-text/70">{action.description}</p>
149
  </div>
150
  </div>
151
  </Link>
 
176
  )}
177
 
178
  {/* Overview */}
179
+ <div className="bg-ui-panel rounded-xl shadow-sm border border-ui-border p-6">
180
  <div className="flex items-center mb-4">
181
+ <ChartBarIcon className="h-6 w-6 text-ui-neonCyan mr-3" />
182
+ <h3 className="text-lg font-semibold text-ui-text">Course Overview</h3>
183
  </div>
184
  <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
185
  <div className="text-center">
186
+ <div className="text-2xl font-bold text-ui-neonCyan">6</div>
187
+ <div className="text-sm text-ui-text/70">Weeks</div>
188
  </div>
189
  <div className="text-center">
190
+ <div className="text-2xl font-bold text-ui-neonCyan">2</div>
191
+ <div className="text-sm text-ui-text/70">Task Types</div>
192
  </div>
193
  <div className="text-center">
194
+ <div className="text-2xl font-bold text-ui-neonCyan">Voting</div>
195
+ <div className="text-sm text-ui-text/70">Peer Review</div>
196
  </div>
197
  </div>
198
  </div>
client/tailwind.config.js CHANGED
@@ -6,12 +6,18 @@ module.exports = {
6
  theme: {
7
  extend: {
8
  colors: {
9
- // Dashboard palette (sampled from provided image)
10
  ui: {
11
- bg: '#EDEDED', // light gray background
12
- gold: '#E1AB3D', // accent badges/buttons
13
- teal: '#63C6AF', // charts/highlights
14
- navy: '#242B3E', // primary text/buttons
 
 
 
 
 
 
15
  },
16
  },
17
  fontFamily: {
@@ -21,6 +27,7 @@ module.exports = {
21
  'fade-in': 'fadeIn 0.3s ease-in-out',
22
  'slide-in': 'slideIn 0.3s ease-out',
23
  'bounce-in': 'bounceIn 0.6s ease-out',
 
24
  },
25
  keyframes: {
26
  fadeIn: {
@@ -37,6 +44,10 @@ module.exports = {
37
  '70%': { transform: 'scale(0.9)' },
38
  '100%': { transform: 'scale(1)', opacity: '1' },
39
  },
 
 
 
 
40
  },
41
  },
42
  },
 
6
  theme: {
7
  extend: {
8
  colors: {
9
+ // Cyberpunk palette
10
  ui: {
11
+ bg: '#0A0B10', // near-black background
12
+ panel: '#121424', // dark panel
13
+ neonPink: '#FF2DAC', // neon primary
14
+ neonCyan: '#29F3FF', // neon secondary
15
+ neonLime: '#C7FF41', // highlights
16
+ magenta: '#D700FF', // accents
17
+ warning: '#FFB020', // warnings
18
+ text: '#E6E8FF', // primary text
19
+ textDim: '#A7ACD9', // secondary text
20
+ border: '#1F2238', // borders
21
  },
22
  },
23
  fontFamily: {
 
27
  'fade-in': 'fadeIn 0.3s ease-in-out',
28
  'slide-in': 'slideIn 0.3s ease-out',
29
  'bounce-in': 'bounceIn 0.6s ease-out',
30
+ 'pulse-glow': 'pulseGlow 2s ease-in-out infinite',
31
  },
32
  keyframes: {
33
  fadeIn: {
 
44
  '70%': { transform: 'scale(0.9)' },
45
  '100%': { transform: 'scale(1)', opacity: '1' },
46
  },
47
+ pulseGlow: {
48
+ '0%, 100%': { boxShadow: '0 0 0px rgba(255, 45, 172, 0.0)' },
49
+ '50%': { boxShadow: '0 0 24px rgba(255, 45, 172, 0.6)' },
50
+ },
51
  },
52
  },
53
  },