ntphuc149 commited on
Commit
bf1e8ee
·
verified ·
1 Parent(s): 02ae15a

Update src/App.js

Browse files
Files changed (1) hide show
  1. src/App.js +113 -83
src/App.js CHANGED
@@ -1,4 +1,4 @@
1
- import React, { useState } from "react";
2
 
3
  // Zodiac Icon Components using Tabler Icons SVGs
4
  const ZodiacIcon = ({ sign, size = 24, className = "" }) => {
@@ -75,11 +75,12 @@ const ZodiacIcon = ({ sign, size = 24, className = "" }) => {
75
  };
76
 
77
  const HoroscopeApp = () => {
78
- const [selectedSign, setSelectedSign] = useState("aries");
79
  const [selectedGender, setSelectedGender] = useState("female");
80
  const [selectedPeriod, setSelectedPeriod] = useState("today");
81
- const [selectedCategory, setSelectedCategory] = useState("love");
82
  const [isDarkMode, setIsDarkMode] = useState(false);
 
83
 
84
  const zodiacSigns = [
85
  {
@@ -188,25 +189,75 @@ const HoroscopeApp = () => {
188
  ];
189
 
190
  const categories = [
191
- { id: "love", name: "Love", icon: <i className="ri-hearts-line"></i> },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
  {
193
  id: "health",
194
  name: "Health",
195
  icon: <i className="ri-open-arm-line"></i>,
196
  },
197
- {
198
- id: "relationship",
199
- name: "Relationship",
200
- icon: <i className="ri-team-line"></i>,
201
- },
202
  {
203
  id: "finance",
204
  name: "Finance",
205
  icon: <i className="ri-wallet-3-line"></i>,
206
  },
 
 
 
 
 
207
  ];
208
 
209
  const horoscopeContent = {
 
 
 
 
 
 
 
 
210
  love: {
211
  today:
212
  "Love is in the air today! Your romantic side is highlighted, making it a perfect day for expressing your feelings.",
@@ -239,6 +290,14 @@ const HoroscopeApp = () => {
239
  "Money matters require attention this month. Budget wisely for future security.",
240
  year: "Financial growth and stability are highlighted throughout this year.",
241
  },
 
 
 
 
 
 
 
 
242
  };
243
 
244
  const luckyData = {
@@ -320,34 +379,50 @@ const HoroscopeApp = () => {
320
  setIsDarkMode(!isDarkMode);
321
  };
322
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
323
  return (
324
  <div
325
  className={`min-h-screen transition-all duration-500 ${
326
- isDarkMode
327
- ? "bg-gradient-to-br from-gray-900 via-blue-900 to-purple-900 text-white"
328
- : "bg-gradient-to-br from-blue-50 via-purple-50 to-pink-50 text-gray-800"
329
  }`}
 
 
 
 
 
330
  >
331
  <div className="max-w-6xl mx-auto p-5">
332
  {/* Header Controls */}
333
  <div className="flex justify-between items-center mb-6 md:mb-8">
334
- {/* Theme Toggle */}
335
  <button
336
  onClick={toggleTheme}
337
- className={`flex items-center gap-2 px-3 md:px-4 py-2 rounded-full font-medium transition-all duration-300 ${
338
  isDarkMode
339
  ? "bg-white bg-opacity-10 text-white hover:bg-opacity-20"
340
  : "bg-white bg-opacity-90 text-gray-700 hover:bg-opacity-100"
341
- } shadow-lg hover:scale-105`}
342
  >
343
  <i
344
  className={`text-xl ${
345
  isDarkMode ? "ri-sun-line" : "ri-moon-line"
346
  }`}
347
  ></i>
348
- <span className="hidden sm:inline">
349
- {isDarkMode ? "Light Mode" : "Dark Mode"}
350
- </span>
351
  </button>
352
 
353
  {/* App Icon - Visible on mobile - Fixed centering */}
@@ -359,14 +434,22 @@ const HoroscopeApp = () => {
359
 
360
  {/* Gender Selection - Toggle style on mobile, tabs on desktop */}
361
  <button
362
- onClick={() => setSelectedGender(selectedGender === 'male' ? 'female' : 'male')}
 
 
363
  className={`flex items-center justify-center w-12 h-12 rounded-full font-medium transition-all duration-300 shadow-lg hover:scale-105 sm:hidden ${
364
  isDarkMode
365
  ? "bg-white bg-opacity-10 text-white hover:bg-opacity-20"
366
  : "bg-white bg-opacity-90 text-gray-700 hover:bg-opacity-100"
367
  }`}
368
  >
369
- <i className={selectedGender === 'male' ? 'ri-men-line text-xl' : 'ri-women-line text-xl'}></i>
 
 
 
 
 
 
370
  </button>
371
 
372
  {/* Gender Selection - Desktop tabs */}
@@ -411,11 +494,15 @@ const HoroscopeApp = () => {
411
  </div>
412
 
413
  {/* Zodiac Signs Grid - Single Row */}
414
- <div className="w-full overflow-x-auto mb-6 md:mb-10">
 
 
 
415
  <div className="flex justify-start md:justify-center gap-2 md:gap-3 pb-4 px-4 min-w-max py-2">
416
  {zodiacSigns.map((sign) => (
417
  <div
418
  key={sign.id}
 
419
  onClick={() => setSelectedSign(sign.id)}
420
  className="flex flex-col items-center cursor-pointer transition-all duration-300 hover:scale-105 flex-shrink-0 py-1"
421
  >
@@ -604,79 +691,22 @@ const HoroscopeApp = () => {
604
  </p>
605
 
606
  <p className="text-lg leading-relaxed mb-8">{getHoroscopeText()}</p>
607
-
608
- {/* Lucky Elements */}
609
- <div
610
- className={`grid grid-cols-2 md:grid-cols-4 gap-6 pt-6 border-t ${
611
- isDarkMode ? "border-gray-700" : "border-gray-200"
612
- }`}
613
- >
614
- <div className="text-center">
615
- <i className="ri-palette-line text-3xl mb-3 text-green-500"></i>
616
- <p
617
- className={`text-xs uppercase tracking-wider mb-2 ${
618
- isDarkMode ? "text-gray-400" : "text-gray-500"
619
- }`}
620
- >
621
- Lucky Color
622
- </p>
623
- <p className="font-bold text-green-500">
624
- {getLuckyElement("colors")}
625
- </p>
626
- </div>
627
- <div className="text-center">
628
- <i className="ri-hashtag text-3xl mb-3 text-blue-500"></i>
629
- <p
630
- className={`text-xs uppercase tracking-wider mb-2 ${
631
- isDarkMode ? "text-gray-400" : "text-gray-500"
632
- }`}
633
- >
634
- Lucky Number
635
- </p>
636
- <p className="font-bold text-blue-500">
637
- {getLuckyElement("numbers")}
638
- </p>
639
- </div>
640
- <div className="text-center">
641
- <i className="ri-vip-diamond-line text-3xl mb-3 text-purple-500"></i>
642
- <p
643
- className={`text-xs uppercase tracking-wider mb-2 ${
644
- isDarkMode ? "text-gray-400" : "text-gray-500"
645
- }`}
646
- >
647
- Lucky Stone
648
- </p>
649
- <p className="font-bold text-purple-500">
650
- {getLuckyElement("stones")}
651
- </p>
652
- </div>
653
- <div className="text-center">
654
- <i className="ri-star-line text-3xl mb-3 text-yellow-500"></i>
655
- <p
656
- className={`text-xs uppercase tracking-wider mb-2 ${
657
- isDarkMode ? "text-gray-400" : "text-gray-500"
658
- }`}
659
- >
660
- Mood
661
- </p>
662
- <p className="font-bold text-yellow-500">
663
- {getLuckyElement("moods")}
664
- </p>
665
- </div>
666
- </div>
667
  </div>
668
 
669
  {/* Footer */}
670
- <div className="text-center text-sm opacity-70 mt-4">
671
  <p className="flex items-center justify-center gap-2">
672
  <i className="ri-sparkling-line"></i>
673
  Discover your daily horoscope and unlock the secrets of the stars
674
  <i className="ri-sparkling-line"></i>
675
  </p>
 
 
 
676
  </div>
677
  </div>
678
  </div>
679
  );
680
  };
681
 
682
- export default HoroscopeApp;
 
1
+ import React, { useState, useEffect, useRef } from "react";
2
 
3
  // Zodiac Icon Components using Tabler Icons SVGs
4
  const ZodiacIcon = ({ sign, size = 24, className = "" }) => {
 
75
  };
76
 
77
  const HoroscopeApp = () => {
78
+ const [selectedSign, setSelectedSign] = useState("virgo");
79
  const [selectedGender, setSelectedGender] = useState("female");
80
  const [selectedPeriod, setSelectedPeriod] = useState("today");
81
+ const [selectedCategory, setSelectedCategory] = useState("overall");
82
  const [isDarkMode, setIsDarkMode] = useState(false);
83
+ const zodiacScrollRef = useRef(null);
84
 
85
  const zodiacSigns = [
86
  {
 
189
  ];
190
 
191
  const categories = [
192
+ {
193
+ id: "overall",
194
+ name: "Overall",
195
+ icon: (
196
+ <svg
197
+ width="20"
198
+ height="20"
199
+ viewBox="0 0 24 24"
200
+ fill="none"
201
+ stroke="currentColor"
202
+ strokeWidth="2"
203
+ strokeLinecap="round"
204
+ strokeLinejoin="round"
205
+ >
206
+ <path d="M3 4l18 0" />
207
+ <path d="M4 4v10a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-10" />
208
+ <path d="M12 16l0 4" />
209
+ <path d="M9 20l6 0" />
210
+ <path d="M8 12l3 -3l2 2l3 -3" />
211
+ </svg>
212
+ ),
213
+ },
214
+ {
215
+ id: "fortune",
216
+ name: "Fortune",
217
+ icon: (
218
+ <svg
219
+ width="20"
220
+ height="20"
221
+ viewBox="0 0 24 24"
222
+ fill="none"
223
+ stroke="currentColor"
224
+ strokeWidth="2"
225
+ strokeLinecap="round"
226
+ strokeLinejoin="round"
227
+ >
228
+ <path d="M6.73 17.018a8 8 0 1 1 10.54 0" />
229
+ <path d="M5 19a2 2 0 0 0 2 2h10a2 2 0 1 0 0 -4h-10a2 2 0 0 0 -2 2z" />
230
+ <path d="M11 7a3 3 0 0 0 -3 3" />
231
+ </svg>
232
+ ),
233
+ },
234
  {
235
  id: "health",
236
  name: "Health",
237
  icon: <i className="ri-open-arm-line"></i>,
238
  },
239
+ { id: "love", name: "Love", icon: <i className="ri-hearts-line"></i> },
 
 
 
 
240
  {
241
  id: "finance",
242
  name: "Finance",
243
  icon: <i className="ri-wallet-3-line"></i>,
244
  },
245
+ {
246
+ id: "relationship",
247
+ name: "Relationship",
248
+ icon: <i className="ri-team-line"></i>,
249
+ },
250
  ];
251
 
252
  const horoscopeContent = {
253
+ overall: {
254
+ today:
255
+ "Today brings a harmonious blend of opportunities and challenges across all aspects of your life. Your natural instincts will guide you well.",
256
+ week: "This week promises balanced growth in multiple areas. Trust your intuition as you navigate new experiences.",
257
+ month:
258
+ "A month of significant personal development awaits. Embrace change and new perspectives with confidence.",
259
+ year: "This year marks a transformative period of growth, bringing profound insights and meaningful achievements.",
260
+ },
261
  love: {
262
  today:
263
  "Love is in the air today! Your romantic side is highlighted, making it a perfect day for expressing your feelings.",
 
290
  "Money matters require attention this month. Budget wisely for future security.",
291
  year: "Financial growth and stability are highlighted throughout this year.",
292
  },
293
+ fortune: {
294
+ today:
295
+ "Lucky energies surround you today. Trust your instincts and take calculated risks for unexpected rewards.",
296
+ week: "Fortune favors the bold this week. Positive surprises and serendipitous encounters await.",
297
+ month:
298
+ "A month of abundance and good fortune unfolds. Opportunities align perfectly with your goals.",
299
+ year: "This year brings remarkable luck and prosperity. Your efforts will be rewarded beyond expectations.",
300
+ },
301
  };
302
 
303
  const luckyData = {
 
379
  setIsDarkMode(!isDarkMode);
380
  };
381
 
382
+ // Scroll to selected zodiac sign on mount
383
+ useEffect(() => {
384
+ if (zodiacScrollRef.current) {
385
+ const selectedElement = zodiacScrollRef.current.querySelector(
386
+ `[data-sign="${selectedSign}"]`
387
+ );
388
+ if (selectedElement) {
389
+ selectedElement.scrollIntoView({
390
+ behavior: "smooth",
391
+ block: "nearest",
392
+ inline: "center",
393
+ });
394
+ }
395
+ }
396
+ }, []);
397
+
398
  return (
399
  <div
400
  className={`min-h-screen transition-all duration-500 ${
401
+ isDarkMode ? "text-white" : "text-gray-800"
 
 
402
  }`}
403
+ style={{
404
+ background: isDarkMode
405
+ ? "linear-gradient(135deg, #7E437B 0%, #0B194A 50%, #221C96 100%)"
406
+ : "linear-gradient(135deg, #A19BFF 0%, #FCC6EA 50%, #BADCFF 100%)",
407
+ }}
408
  >
409
  <div className="max-w-6xl mx-auto p-5">
410
  {/* Header Controls */}
411
  <div className="flex justify-between items-center mb-6 md:mb-8">
412
+ {/* Theme Toggle - Icon only for all screen sizes */}
413
  <button
414
  onClick={toggleTheme}
415
+ className={`flex items-center justify-center w-12 h-12 rounded-full font-medium transition-all duration-300 shadow-lg hover:scale-105 ${
416
  isDarkMode
417
  ? "bg-white bg-opacity-10 text-white hover:bg-opacity-20"
418
  : "bg-white bg-opacity-90 text-gray-700 hover:bg-opacity-100"
419
+ }`}
420
  >
421
  <i
422
  className={`text-xl ${
423
  isDarkMode ? "ri-sun-line" : "ri-moon-line"
424
  }`}
425
  ></i>
 
 
 
426
  </button>
427
 
428
  {/* App Icon - Visible on mobile - Fixed centering */}
 
434
 
435
  {/* Gender Selection - Toggle style on mobile, tabs on desktop */}
436
  <button
437
+ onClick={() =>
438
+ setSelectedGender(selectedGender === "male" ? "female" : "male")
439
+ }
440
  className={`flex items-center justify-center w-12 h-12 rounded-full font-medium transition-all duration-300 shadow-lg hover:scale-105 sm:hidden ${
441
  isDarkMode
442
  ? "bg-white bg-opacity-10 text-white hover:bg-opacity-20"
443
  : "bg-white bg-opacity-90 text-gray-700 hover:bg-opacity-100"
444
  }`}
445
  >
446
+ <i
447
+ className={
448
+ selectedGender === "male"
449
+ ? "ri-women-line text-xl"
450
+ : "ri-men-line text-xl"
451
+ }
452
+ ></i>
453
  </button>
454
 
455
  {/* Gender Selection - Desktop tabs */}
 
494
  </div>
495
 
496
  {/* Zodiac Signs Grid - Single Row */}
497
+ <div
498
+ className="w-full overflow-x-auto mb-6 md:mb-10"
499
+ ref={zodiacScrollRef}
500
+ >
501
  <div className="flex justify-start md:justify-center gap-2 md:gap-3 pb-4 px-4 min-w-max py-2">
502
  {zodiacSigns.map((sign) => (
503
  <div
504
  key={sign.id}
505
+ data-sign={sign.id}
506
  onClick={() => setSelectedSign(sign.id)}
507
  className="flex flex-col items-center cursor-pointer transition-all duration-300 hover:scale-105 flex-shrink-0 py-1"
508
  >
 
691
  </p>
692
 
693
  <p className="text-lg leading-relaxed mb-8">{getHoroscopeText()}</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
694
  </div>
695
 
696
  {/* Footer */}
697
+ <div className="text-center text-sm opacity-70 mt-4 space-y-2">
698
  <p className="flex items-center justify-center gap-2">
699
  <i className="ri-sparkling-line"></i>
700
  Discover your daily horoscope and unlock the secrets of the stars
701
  <i className="ri-sparkling-line"></i>
702
  </p>
703
+ <p className="text-xs opacity-60">
704
+ © 2025 AstroLens Horoscope - All rights reserved.
705
+ </p>
706
  </div>
707
  </div>
708
  </div>
709
  );
710
  };
711
 
712
+ export default HoroscopeApp;