akhaliq HF Staff commited on
Commit
d669273
·
1 Parent(s): 4c3311e

update landing page style

Browse files
Files changed (1) hide show
  1. frontend/src/components/LandingPage.tsx +149 -151
frontend/src/components/LandingPage.tsx CHANGED
@@ -177,34 +177,32 @@ export default function LandingPage({
177
  };
178
 
179
  return (
180
- <div className="min-h-screen flex flex-col bg-[#1e1e1e] overflow-y-auto">
181
- {/* Header - Minimal Apple style */}
182
- <header className="flex items-center justify-between px-8 py-4 border-b border-[#3e3e42]/30 flex-shrink-0">
183
- <h1 className="text-base font-semibold text-[#cccccc] tracking-tight">
184
  AnyCoder
185
  </h1>
186
 
187
  {/* Auth Section */}
188
  <div className="flex items-center space-x-3">
189
  {isAuthLoading ? (
190
- <div className="px-4 py-2">
191
- <span className="text-xs text-[#858585] font-medium">Loading...</span>
192
- </div>
193
  ) : userInfo ? (
194
  <div className="flex items-center space-x-3">
195
  {userInfo.avatarUrl && (
196
  <img
197
  src={userInfo.avatarUrl}
198
  alt={userInfo.name}
199
- className="w-7 h-7 rounded-full ring-2 ring-[#3e3e42]"
200
  />
201
  )}
202
- <span className="hidden sm:inline text-sm text-[#cccccc] font-medium truncate max-w-[120px]">
203
  {userInfo.preferredUsername || userInfo.name}
204
  </span>
205
  <button
206
  onClick={handleLogout}
207
- className="px-4 py-2 bg-[#2d2d30] text-[#cccccc] text-xs rounded-lg hover:bg-[#3a3a3c] transition-all border border-[#3e3e42] font-semibold active:scale-95"
208
  >
209
  Logout
210
  </button>
@@ -215,20 +213,19 @@ export default function LandingPage({
215
  {isDevMode && (
216
  <>
217
  {showDevLogin ? (
218
- <div className="flex items-center space-x-2 bg-[#2d2d30] px-3 py-2 rounded-lg border border-[#ff9f0a]">
219
- <span className="hidden sm:inline text-xs text-[#ff9f0a] font-semibold">DEV</span>
220
  <input
221
  type="text"
222
  value={devUsername}
223
  onChange={(e) => setDevUsername(e.target.value)}
224
  onKeyPress={(e) => e.key === 'Enter' && handleDevLogin()}
225
  placeholder="username"
226
- className="px-3 py-1.5 rounded-lg text-xs bg-[#1e1e1e] text-[#cccccc] border border-[#3e3e42] focus:outline-none focus:ring-2 focus:ring-[#ff9f0a] focus:border-transparent w-28 font-medium"
227
  autoFocus
228
  />
229
  <button
230
  onClick={handleDevLogin}
231
- className="px-3 py-1.5 bg-[#ff9f0a] text-white rounded-lg hover:bg-[#ff8800] text-xs font-semibold active:scale-95"
232
  >
233
  OK
234
  </button>
@@ -237,7 +234,7 @@ export default function LandingPage({
237
  setShowDevLogin(false);
238
  setDevUsername('');
239
  }}
240
- className="text-[#858585] hover:text-[#cccccc] text-sm transition-colors"
241
  >
242
 
243
  </button>
@@ -245,178 +242,179 @@ export default function LandingPage({
245
  ) : (
246
  <button
247
  onClick={() => setShowDevLogin(true)}
248
- className="px-4 py-2 bg-[#ff9f0a] text-white rounded-lg hover:bg-[#ff8800] transition-all text-xs flex items-center space-x-2 font-semibold active:scale-95"
249
- title="Dev Mode (localhost)"
250
  >
251
- <span>🔧</span>
252
- <span>Dev Login</span>
253
  </button>
254
  )}
255
- <span className="text-[#858585] text-xs font-medium">or</span>
256
  </>
257
  )}
258
 
259
  {/* OAuth Login */}
260
  <button
261
  onClick={handleLogin}
262
- className="px-4 py-2 bg-[#007acc] text-white rounded-lg hover:bg-[#0066b3] transition-all text-xs flex items-center space-x-2 font-semibold active:scale-95"
263
  >
264
- <span>🤗</span>
265
- <span>Sign in</span>
266
  </button>
267
  </div>
268
  )}
269
  </div>
270
  </header>
271
 
272
- {/* Main Content - Centered with generous Apple spacing */}
273
- <main className="flex-1 flex items-center justify-center px-6 md:px-8 py-8 md:py-12 min-h-0">
274
- <div className="w-full max-w-4xl">
275
- {/* Headline - Apple typography with VS Code colors */}
276
- <div className="text-center mb-8 md:mb-10">
277
- <h2 className="text-4xl md:text-5xl lg:text-6xl font-bold text-[#cccccc] mb-4 tracking-[-0.02em] leading-[1.1]">
278
  Build with AnyCoder
279
  </h2>
280
- <p className="text-base md:text-lg text-[#858585] font-light tracking-tight">
281
  Create apps and websites by chatting with AI
282
  </p>
283
  </div>
284
 
285
- {/* Prompt Input - VS Code style with Apple polish */}
286
  <form onSubmit={handleSubmit} className="relative">
287
- <div className="relative bg-[#252526] rounded-2xl border border-[#3e3e42] overflow-hidden shadow-2xl shadow-black/60">
288
- {/* Options Row - Language and Model dropdowns */}
289
- <div className="flex items-center gap-3 px-6 pt-5 pb-4 border-b border-[#3e3e42]/40">
290
- {/* Language Dropdown */}
291
- <div className="relative flex-1" ref={languageDropdownRef}>
292
- <button
293
- type="button"
294
- onClick={() => {
295
- setShowLanguageDropdown(!showLanguageDropdown);
296
- setShowModelDropdown(false);
297
- }}
298
- disabled={isLoading}
299
- className="w-full px-4 py-2.5 bg-[#2d2d30] text-[#cccccc] text-sm border border-[#3e3e42] rounded-lg focus:outline-none focus:ring-2 focus:ring-[#007acc]/50 focus:border-[#007acc] disabled:opacity-50 font-medium flex items-center justify-between hover:bg-[#323233] transition-all duration-150"
300
- >
301
- <span className="text-[#cccccc]">{isLoading ? 'Loading...' : formatLanguageName(selectedLanguage)}</span>
302
- <svg
303
- className={`w-4 h-4 text-[#858585] transition-transform duration-200 ${showLanguageDropdown ? 'rotate-180' : ''}`}
304
- fill="none"
305
- stroke="currentColor"
306
- viewBox="0 0 24 24"
307
- >
308
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
309
- </svg>
310
- </button>
311
-
312
- {/* Language Dropdown Tray */}
313
- {showLanguageDropdown && !isLoading && languages.length > 0 && (
314
- <div className="absolute z-50 w-full mt-1.5 bg-[#252526] border border-[#3e3e42] rounded-lg shadow-2xl shadow-black/70 overflow-hidden">
315
- <div className="max-h-64 overflow-y-auto">
316
- {languages.map((lang) => (
317
- <button
318
- key={lang}
319
- type="button"
320
- onClick={() => {
321
- setSelectedLanguage(lang);
322
- setShowLanguageDropdown(false);
323
- }}
324
- className={`w-full px-4 py-2.5 text-left text-sm text-[#cccccc] hover:bg-[#2a2d2e] transition-colors duration-150 ${
325
- selectedLanguage === lang ? 'bg-[#264f78] hover:bg-[#264f78] text-[#ffffff]' : ''
326
- }`}
327
- >
328
- {formatLanguageName(lang)}
329
- </button>
330
- ))}
331
- </div>
332
- </div>
333
- )}
334
- </div>
335
-
336
- {/* Model Dropdown */}
337
- <div className="relative flex-1" ref={modelDropdownRef}>
338
- <button
339
- type="button"
340
- onClick={() => {
341
- setShowModelDropdown(!showModelDropdown);
342
- setShowLanguageDropdown(false);
343
- }}
344
- disabled={isLoading}
345
- className="w-full px-4 py-2.5 bg-[#2d2d30] text-[#cccccc] text-sm border border-[#3e3e42] rounded-lg focus:outline-none focus:ring-2 focus:ring-[#007acc]/50 focus:border-[#007acc] disabled:opacity-50 font-medium flex items-center justify-between hover:bg-[#323233] transition-all duration-150"
346
- >
347
- <span className="truncate text-[#cccccc]">
348
- {isLoading
349
- ? 'Loading...'
350
- : models.find(m => m.id === selectedModel)?.name || 'Select model'
351
- }
352
- </span>
353
- <svg
354
- className={`w-4 h-4 text-[#858585] transition-transform duration-200 flex-shrink-0 ml-2 ${showModelDropdown ? 'rotate-180' : ''}`}
355
- fill="none"
356
- stroke="currentColor"
357
- viewBox="0 0 24 24"
358
- >
359
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
360
- </svg>
361
- </button>
362
-
363
- {/* Model Dropdown Tray */}
364
- {showModelDropdown && !isLoading && models.length > 0 && (
365
- <div className="absolute z-50 w-full mt-1.5 bg-[#252526] border border-[#3e3e42] rounded-lg shadow-2xl shadow-black/70 overflow-hidden">
366
- <div className="max-h-80 overflow-y-auto">
367
- {models.map((model) => (
368
- <button
369
- key={model.id}
370
- type="button"
371
- onClick={() => {
372
- setSelectedModel(model.id);
373
- setShowModelDropdown(false);
374
- }}
375
- className={`w-full px-4 py-3 text-left transition-colors duration-150 ${
376
- selectedModel === model.id
377
- ? 'bg-[#264f78] hover:bg-[#264f78]'
378
- : 'hover:bg-[#2a2d2e]'
379
- }`}
380
- >
381
- <div className="text-sm font-medium text-[#cccccc]">{model.name}</div>
382
- {model.description && (
383
- <div className="text-xs text-[#858585] mt-1 leading-relaxed">
384
- {model.description}
385
- </div>
386
- )}
387
- </button>
388
- ))}
389
- </div>
390
- </div>
391
- )}
392
- </div>
393
- </div>
394
-
395
  {/* Textarea */}
396
  <textarea
397
  value={prompt}
398
  onChange={(e) => setPrompt(e.target.value)}
399
- placeholder="Ask AnyCoder to create a landing page for my..."
400
- className="w-full px-6 py-5 text-base md:text-lg text-[#cccccc] bg-transparent placeholder:text-[#858585] resize-none focus:outline-none min-h-[120px] md:min-h-[140px] font-normal leading-relaxed"
401
- rows={3}
402
  onKeyDown={(e) => {
403
- if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {
 
404
  handleSubmit(e);
405
  }
406
  }}
407
  />
408
 
409
- {/* Input Controls - Apple style button */}
410
- <div className="flex items-center justify-end px-6 pb-5 pt-4 border-t border-[#3e3e42]/40">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
411
  <button
412
  type="submit"
413
  disabled={!prompt.trim() || !isAuthenticated}
414
- className="px-8 py-3 bg-[#007acc] text-white text-sm font-semibold rounded-lg hover:bg-[#0066b3] disabled:opacity-40 disabled:cursor-not-allowed transition-all duration-200 shadow-lg shadow-[#007acc]/20 hover:shadow-[#007acc]/30 active:scale-[0.97] flex items-center space-x-2 tracking-tight"
415
- title="Send (⌘+Enter)"
416
  >
417
- <span>Send</span>
418
  <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={2.5}>
419
- <path strokeLinecap="round" strokeLinejoin="round" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8" />
420
  </svg>
421
  </button>
422
  </div>
@@ -424,8 +422,8 @@ export default function LandingPage({
424
 
425
  {!isAuthenticated && (
426
  <div className="mt-6 text-center">
427
- <p className="text-sm text-[#858585] font-medium">
428
- Please sign in to get started
429
  </p>
430
  </div>
431
  )}
 
177
  };
178
 
179
  return (
180
+ <div className="min-h-screen flex flex-col bg-[#000000] overflow-y-auto">
181
+ {/* Header - Apple style */}
182
+ <header className="flex items-center justify-between px-6 py-4 backdrop-blur-xl bg-[#000000]/80 border-b border-[#424245]/30 flex-shrink-0">
183
+ <h1 className="text-sm font-medium text-[#f5f5f7]">
184
  AnyCoder
185
  </h1>
186
 
187
  {/* Auth Section */}
188
  <div className="flex items-center space-x-3">
189
  {isAuthLoading ? (
190
+ <span className="text-xs text-[#86868b]">Loading...</span>
 
 
191
  ) : userInfo ? (
192
  <div className="flex items-center space-x-3">
193
  {userInfo.avatarUrl && (
194
  <img
195
  src={userInfo.avatarUrl}
196
  alt={userInfo.name}
197
+ className="w-7 h-7 rounded-full"
198
  />
199
  )}
200
+ <span className="hidden sm:inline text-sm text-[#f5f5f7] truncate max-w-[120px] font-medium">
201
  {userInfo.preferredUsername || userInfo.name}
202
  </span>
203
  <button
204
  onClick={handleLogout}
205
+ className="px-3 py-1.5 text-sm text-[#f5f5f7] hover:text-white transition-colors"
206
  >
207
  Logout
208
  </button>
 
213
  {isDevMode && (
214
  <>
215
  {showDevLogin ? (
216
+ <div className="flex items-center space-x-2">
 
217
  <input
218
  type="text"
219
  value={devUsername}
220
  onChange={(e) => setDevUsername(e.target.value)}
221
  onKeyPress={(e) => e.key === 'Enter' && handleDevLogin()}
222
  placeholder="username"
223
+ className="px-3 py-1.5 rounded-lg text-sm bg-[#1d1d1f] text-[#f5f5f7] border border-[#424245] focus:outline-none focus:border-white/50 w-32 font-medium"
224
  autoFocus
225
  />
226
  <button
227
  onClick={handleDevLogin}
228
+ className="px-3 py-1.5 bg-white text-black rounded-lg text-sm hover:bg-[#f5f5f7] font-medium"
229
  >
230
  OK
231
  </button>
 
234
  setShowDevLogin(false);
235
  setDevUsername('');
236
  }}
237
+ className="text-[#86868b] hover:text-[#f5f5f7] text-sm"
238
  >
239
 
240
  </button>
 
242
  ) : (
243
  <button
244
  onClick={() => setShowDevLogin(true)}
245
+ className="px-3 py-1.5 text-sm text-[#f5f5f7] hover:text-white transition-colors"
246
+ title="Dev Mode"
247
  >
248
+ 🔧 Dev
 
249
  </button>
250
  )}
251
+ <span className="text-[#86868b] text-sm">or</span>
252
  </>
253
  )}
254
 
255
  {/* OAuth Login */}
256
  <button
257
  onClick={handleLogin}
258
+ className="px-4 py-2 bg-white text-black rounded-full text-sm hover:bg-[#f5f5f7] transition-all font-medium"
259
  >
260
+ Sign in
 
261
  </button>
262
  </div>
263
  )}
264
  </div>
265
  </header>
266
 
267
+ {/* Main Content - Apple-style centered layout */}
268
+ <main className="flex-1 flex items-center justify-center px-4 py-12 min-h-0">
269
+ <div className="w-full max-w-3xl">
270
+ {/* Apple-style Headline */}
271
+ <div className="text-center mb-12">
272
+ <h2 className="text-5xl md:text-6xl lg:text-7xl font-semibold text-white mb-3 tracking-tight leading-[1.05]">
273
  Build with AnyCoder
274
  </h2>
275
+ <p className="text-lg md:text-xl text-[#86868b] font-normal">
276
  Create apps and websites by chatting with AI
277
  </p>
278
  </div>
279
 
280
+ {/* Simple prompt form */}
281
  <form onSubmit={handleSubmit} className="relative">
282
+ <div className="relative bg-[#2d2d30] rounded-2xl border border-[#424245] shadow-2xl">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
283
  {/* Textarea */}
284
  <textarea
285
  value={prompt}
286
  onChange={(e) => setPrompt(e.target.value)}
287
+ placeholder="Message AnyCoder"
288
+ className="w-full px-5 py-4 text-base text-[#f5f5f7] bg-transparent placeholder:text-[#86868b] resize-none focus:outline-none min-h-[56px] font-normal"
289
+ rows={1}
290
  onKeyDown={(e) => {
291
+ if (e.key === 'Enter' && !e.shiftKey) {
292
+ e.preventDefault();
293
  handleSubmit(e);
294
  }
295
  }}
296
  />
297
 
298
+ {/* Bottom controls - Apple style */}
299
+ <div className="flex items-center justify-between px-4 pb-4 gap-3">
300
+ {/* Compact dropdowns on the left */}
301
+ <div className="flex items-center gap-2">
302
+ {/* Language Dropdown */}
303
+ <div className="relative" ref={languageDropdownRef}>
304
+ <button
305
+ type="button"
306
+ onClick={() => {
307
+ setShowLanguageDropdown(!showLanguageDropdown);
308
+ setShowModelDropdown(false);
309
+ }}
310
+ disabled={isLoading}
311
+ className="px-3 py-1.5 bg-[#1d1d1f] text-[#f5f5f7] text-xs border border-[#424245] rounded-full hover:bg-[#2d2d2f] transition-all disabled:opacity-50 flex items-center gap-1.5 font-medium"
312
+ >
313
+ <span>{isLoading ? '...' : formatLanguageName(selectedLanguage)}</span>
314
+ <svg
315
+ className={`w-3 h-3 text-[#86868b] transition-transform ${showLanguageDropdown ? 'rotate-180' : ''}`}
316
+ fill="none"
317
+ stroke="currentColor"
318
+ viewBox="0 0 24 24"
319
+ strokeWidth={2.5}
320
+ >
321
+ <path strokeLinecap="round" strokeLinejoin="round" d="M19 9l-7 7-7-7" />
322
+ </svg>
323
+ </button>
324
+
325
+ {/* Language Dropdown Menu */}
326
+ {showLanguageDropdown && !isLoading && languages.length > 0 && (
327
+ <div className="absolute bottom-full left-0 mb-2 w-48 bg-[#1d1d1f] border border-[#424245] rounded-xl shadow-2xl overflow-hidden backdrop-blur-xl">
328
+ <div className="max-h-64 overflow-y-auto py-1">
329
+ {languages.map((lang) => (
330
+ <button
331
+ key={lang}
332
+ type="button"
333
+ onClick={() => {
334
+ setSelectedLanguage(lang);
335
+ setShowLanguageDropdown(false);
336
+ }}
337
+ className={`w-full px-4 py-2.5 text-left text-xs text-[#f5f5f7] hover:bg-[#2d2d2f] transition-colors font-medium ${
338
+ selectedLanguage === lang ? 'bg-[#2d2d2f]' : ''
339
+ }`}
340
+ >
341
+ {formatLanguageName(lang)}
342
+ </button>
343
+ ))}
344
+ </div>
345
+ </div>
346
+ )}
347
+ </div>
348
+
349
+ {/* Model Dropdown */}
350
+ <div className="relative" ref={modelDropdownRef}>
351
+ <button
352
+ type="button"
353
+ onClick={() => {
354
+ setShowModelDropdown(!showModelDropdown);
355
+ setShowLanguageDropdown(false);
356
+ }}
357
+ disabled={isLoading}
358
+ className="px-3 py-1.5 bg-[#1d1d1f] text-[#f5f5f7] text-xs border border-[#424245] rounded-full hover:bg-[#2d2d2f] transition-all disabled:opacity-50 flex items-center gap-1.5 max-w-[200px] font-medium"
359
+ >
360
+ <span className="truncate">
361
+ {isLoading
362
+ ? '...'
363
+ : models.find(m => m.id === selectedModel)?.name || 'Model'
364
+ }
365
+ </span>
366
+ <svg
367
+ className={`w-3 h-3 text-[#86868b] flex-shrink-0 transition-transform ${showModelDropdown ? 'rotate-180' : ''}`}
368
+ fill="none"
369
+ stroke="currentColor"
370
+ viewBox="0 0 24 24"
371
+ strokeWidth={2.5}
372
+ >
373
+ <path strokeLinecap="round" strokeLinejoin="round" d="M19 9l-7 7-7-7" />
374
+ </svg>
375
+ </button>
376
+
377
+ {/* Model Dropdown Menu */}
378
+ {showModelDropdown && !isLoading && models.length > 0 && (
379
+ <div className="absolute bottom-full left-0 mb-2 w-80 bg-[#1d1d1f] border border-[#424245] rounded-xl shadow-2xl overflow-hidden backdrop-blur-xl">
380
+ <div className="max-h-96 overflow-y-auto py-1">
381
+ {models.map((model) => (
382
+ <button
383
+ key={model.id}
384
+ type="button"
385
+ onClick={() => {
386
+ setSelectedModel(model.id);
387
+ setShowModelDropdown(false);
388
+ }}
389
+ className={`w-full px-4 py-2.5 text-left transition-colors ${
390
+ selectedModel === model.id
391
+ ? 'bg-[#2d2d2f]'
392
+ : 'hover:bg-[#2d2d2f]'
393
+ }`}
394
+ >
395
+ <div className="text-xs font-medium text-[#f5f5f7]">{model.name}</div>
396
+ {model.description && (
397
+ <div className="text-[10px] text-[#86868b] mt-1 leading-relaxed">
398
+ {model.description}
399
+ </div>
400
+ )}
401
+ </button>
402
+ ))}
403
+ </div>
404
+ </div>
405
+ )}
406
+ </div>
407
+ </div>
408
+
409
+ {/* Send button on the right - Apple style */}
410
  <button
411
  type="submit"
412
  disabled={!prompt.trim() || !isAuthenticated}
413
+ className="p-2 bg-white text-[#1d1d1f] rounded-full hover:bg-[#f5f5f7] disabled:opacity-30 disabled:cursor-not-allowed transition-all active:scale-95 shadow-lg"
414
+ title="Send"
415
  >
 
416
  <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={2.5}>
417
+ <path strokeLinecap="round" strokeLinejoin="round" d="M5 12h14M12 5l7 7-7 7" />
418
  </svg>
419
  </button>
420
  </div>
 
422
 
423
  {!isAuthenticated && (
424
  <div className="mt-6 text-center">
425
+ <p className="text-sm text-[#86868b]">
426
+ Sign in to get started
427
  </p>
428
  </div>
429
  )}