ActivityModal.jsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. import React, { useState, useEffect } from "react";
  2. import { X } from "lucide-react";
  3. const ActivityModal = () => {
  4. const [isOpen, setIsOpen] = useState(false);
  5. const [activityContent, setActivityContent] = useState(null);
  6. const [isLoading, setIsLoading] = useState(true);
  7. useEffect(() => {
  8. const fetchActivityContent = async () => {
  9. try {
  10. setIsLoading(true);
  11. const response = await fetch("/api/activity", {
  12. headers: {
  13. "x-from-frontend": "true",
  14. },
  15. });
  16. if (!response.ok) {
  17. throw new Error("Failed to fetch activity content");
  18. }
  19. const data = await response.json();
  20. console.log("data", data);
  21. if (data.success && data.data) {
  22. setActivityContent(data.data[0]);
  23. setIsOpen(true);
  24. } else {
  25. console.log(data.message || "No active activity");
  26. setActivityContent(null);
  27. }
  28. } catch (error) {
  29. console.error("Error fetching activity content:", error);
  30. setActivityContent(null);
  31. } finally {
  32. setIsLoading(false);
  33. }
  34. };
  35. fetchActivityContent();
  36. }, []);
  37. if (!isOpen || !activityContent || isLoading) return null;
  38. console.log("activityContent", activityContent);
  39. const hasBackgroundImage = !!activityContent?.backgroundImage;
  40. const hasBackgroundImageLink = !!activityContent?.backgroundImageLink;
  41. const CardContent = () => (
  42. <div
  43. className="bg-cover bg-center rounded-lg px-6 pb-6 pt-16 max-w-sm w-full mx-4 overflow-hidden"
  44. style={{
  45. backgroundImage: `url('${activityContent.backgroundImage}')`,
  46. width: "80vw",
  47. minHeight: "50vh",
  48. backgroundPosition: "top center",
  49. }}
  50. >
  51. <div className="relative z-10 text-white">
  52. <div className="flex flex-col items-center mb-4 relative w-full">
  53. <div
  54. className="text-xl font-bold w-full text-center"
  55. dangerouslySetInnerHTML={{ __html: activityContent.title }}
  56. />
  57. </div>
  58. <div
  59. className="overflow-y-auto"
  60. style={{ maxHeight: "calc(50vh - 100px)" }}
  61. dangerouslySetInnerHTML={{ __html: activityContent.content }}
  62. />
  63. </div>
  64. </div>
  65. );
  66. return (
  67. <>
  68. {hasBackgroundImage ? (
  69. <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
  70. <div className="relative">
  71. <button
  72. onClick={() => setIsOpen(false)}
  73. className="absolute -top-16 right-3 text-white hover:text-gray-300 z-20 p-2 rounded-full bg-gray-500 hover:bg-opacity-70 transition-all duration-300"
  74. >
  75. <X size={24} />
  76. </button>
  77. {hasBackgroundImageLink ? (
  78. <a
  79. href={activityContent.backgroundImageLink}
  80. target="_blank"
  81. rel="noopener noreferrer"
  82. >
  83. <CardContent />
  84. </a>
  85. ) : (
  86. <CardContent />
  87. )}
  88. </div>
  89. </div>
  90. ) : (
  91. <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
  92. <div className="bg-white rounded-lg p-6 max-w-sm w-full mx-4">
  93. <div className="flex flex-col items-center mb-4 relative w-full">
  94. <div
  95. className="text-xl font-bold text-black w-full"
  96. dangerouslySetInnerHTML={{ __html: activityContent.title }}
  97. ></div>
  98. <button
  99. onClick={() => setIsOpen(false)}
  100. className="text-gray-500 hover:text-gray-700 absolute right-0 top-0"
  101. >
  102. <X size={24} />
  103. </button>
  104. </div>
  105. <div
  106. className="text-gray-700"
  107. dangerouslySetInnerHTML={{ __html: activityContent.content }}
  108. />
  109. </div>
  110. </div>
  111. )}
  112. </>
  113. );
  114. };
  115. export default ActivityModal;