@titas_mallick/wedding-site-gen 1.1.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/README.md +104 -170
  2. package/app/api/email-reminders/route.ts +240 -0
  3. package/app/couple/page.tsx +4 -4
  4. package/app/game/page.tsx +298 -0
  5. package/app/guestbook/page.tsx +270 -152
  6. package/app/invitation/[slug]/layout.tsx +4 -2
  7. package/app/invitation/[slug]/page.tsx +303 -84
  8. package/app/invitation/actions.ts +49 -0
  9. package/app/invitation/maker/auth.js +1 -1
  10. package/app/invitation/maker/guestAdder.js +4 -0
  11. package/app/invitation/maker/guestShower.js +39 -8
  12. package/app/invitation/maker/layout.tsx +1 -1
  13. package/app/invitation/maker/page.js +9 -7
  14. package/app/invitation/maker/rsvpViewer.js +90 -8
  15. package/app/layout.tsx +40 -14
  16. package/app/mark-the-dates/page.tsx +8 -2
  17. package/app/page.tsx +7 -1
  18. package/app/providers.tsx +1 -1
  19. package/app/sagun/page.tsx +224 -76
  20. package/app/song-requests/page.tsx +242 -105
  21. package/app/sukanya/page.tsx +9 -13
  22. package/app/titas/page.tsx +8 -24
  23. package/app/travel-guide/page.tsx +361 -120
  24. package/app/updates/maker/page.js +2 -2
  25. package/app/updates/overlay/page.tsx +65 -30
  26. package/app/updates/page.js +3 -3
  27. package/cli.mjs +26 -15
  28. package/components/AdminAuth.tsx +145 -0
  29. package/components/AdminLinks.tsx +120 -0
  30. package/components/ConciergeBot.tsx +104 -44
  31. package/components/CountdownTimer.tsx +37 -15
  32. package/components/Gallery.tsx +1 -1
  33. package/components/LiveVideos.tsx +27 -15
  34. package/components/OurStory.tsx +1 -1
  35. package/components/SchemaMarkup.tsx +74 -0
  36. package/components/certificate.jsx +287 -300
  37. package/components/footer.tsx +2 -0
  38. package/components/hero.tsx +47 -4
  39. package/components/icons.tsx +45 -0
  40. package/components/importantNews.js +168 -168
  41. package/components/navbar.tsx +113 -18
  42. package/components/updates.tsx +36 -26
  43. package/config/firebase-admin.js +14 -17
  44. package/config/firebase.ts +4 -2
  45. package/config/site.ts +10 -2
  46. package/firestore.rules +6 -1
  47. package/next-sitemap.config.js +21 -0
  48. package/package.json +4 -3
  49. package/public/corner1-01.svg +0 -0
  50. package/public/love-birds.png +0 -0
  51. package/public/next.svg +0 -0
  52. package/public/pubqr.png +0 -0
  53. package/public/pw/sample.jpg +0 -0
  54. package/public/qr.png +0 -0
  55. package/public/sample.jpg +0 -0
  56. package/public/vercel.svg +0 -0
  57. package/vercel.json +1 -0
  58. package/.recover +0 -9
  59. package/next-env.d.ts +0 -6
  60. package/public/DCV.gif +0 -0
  61. package/public/DCV2.gif +0 -0
  62. package/public/DCV3.gif +0 -0
  63. package/public/Images/1.jpg +0 -0
  64. package/public/Images/11.jpg +0 -0
  65. package/public/Images/12.jpg +0 -0
  66. package/public/Images/13.jpg +0 -0
  67. package/public/Images/14.jpg +0 -0
  68. package/public/Images/15.jpg +0 -0
  69. package/public/Images/16.jpg +0 -0
  70. package/public/Images/17.jpg +0 -0
  71. package/public/Images/18.jpg +0 -0
  72. package/public/Images/19.jpg +0 -0
  73. package/public/Images/2.jpg +0 -0
  74. package/public/Images/21.jpg +0 -0
  75. package/public/Images/22.jpg +0 -0
  76. package/public/Images/3.jpg +0 -0
  77. package/public/Images/4.jpg +0 -0
  78. package/public/Images/5.jpg +0 -0
  79. package/public/Images/6.jpg +0 -0
  80. package/public/Images/7.jpg +0 -0
  81. package/public/Images/8.jpg +0 -0
  82. package/public/Images/9.jpg +0 -0
  83. package/public/Images/9b.jpg +0 -0
  84. package/public/Images/Patipatra.jpeg +0 -0
  85. package/public/audio (1).mp3 +0 -0
  86. package/public/audio (2).mp3 +0 -0
  87. package/public/bride.jpg +0 -0
  88. package/public/groom.jpg +0 -0
  89. package/public/invite.png +0 -0
  90. package/public/pw/001.jpg +0 -0
  91. package/public/pw/002.jpg +0 -0
  92. package/public/pw/003.jpg +0 -0
  93. package/public/pw/004.jpg +0 -0
  94. package/public/pw/005.jpg +0 -0
  95. package/public/pw/006.jpg +0 -0
  96. package/public/pw/007.jpg +0 -0
  97. package/public/pw/008.jpg +0 -0
  98. package/public/pw/009.jpg +0 -0
  99. package/public/pw/010.jpg +0 -0
  100. package/public/pw/011.jpg +0 -0
  101. package/public/pw/012.jpg +0 -0
  102. package/public/pw/013.jpg +0 -0
  103. package/public/pw/014.jpg +0 -0
  104. package/public/pw/015.jpg +0 -0
  105. package/public/pw/016.jpg +0 -0
  106. package/public/pw/017.jpg +0 -0
  107. package/public/pw/018.jpg +0 -0
  108. package/public/pw/019.jpg +0 -0
  109. package/public/pw/020.jpg +0 -0
  110. package/public/pw/021.jpg +0 -0
  111. package/public/pw/022.jpg +0 -0
  112. package/public/pw/023.jpg +0 -0
  113. package/public/pw/024.jpg +0 -0
  114. package/public/pw/025.jpg +0 -0
  115. package/public/pw/026.jpg +0 -0
  116. package/public/pw/027.jpg +0 -0
  117. package/public/pw/028.jpg +0 -0
  118. package/public/pw/029.jpg +0 -0
  119. package/public/pw/030.jpg +0 -0
  120. package/public/pw/031.jpg +0 -0
  121. package/public/pw/032.jpg +0 -0
  122. package/tsconfig.tsbuildinfo +0 -1
  123. /package/public/Images/{20.jpg → sample.jpg} +0 -0
@@ -2,37 +2,41 @@
2
2
 
3
3
  import { useState } from "react";
4
4
  import { motion } from "framer-motion";
5
- import {
6
- Card,
7
- CardBody,
8
- Divider,
9
- Button,
10
- Link,
11
- Image,
12
- Tabs,
13
- Tab,
14
- Accordion,
15
- AccordionItem
5
+ import {
6
+ Card,
7
+ CardBody,
8
+ Divider,
9
+ Button,
10
+ Link,
11
+ Image,
12
+ Tabs,
13
+ Tab,
14
+ Accordion,
15
+ AccordionItem,
16
16
  } from "@heroui/react";
17
- import { fontCursive, fontSans, fontMono } from "@/config/fonts";
18
- import { MapPinIcon, ClockIcon } from "@/components/icons";
17
+
18
+ import { fontCursive, fontSans } from "@/config/fonts";
19
+ import { MapPinIcon } from "@/components/icons";
19
20
 
20
21
  const transportHubs = [
21
22
  {
22
23
  name: "From Howrah Station",
23
- details: "Take any 'Bandel Local' or 'Burdwan Local' from Howrah Station. Serampore is about a 30-40 minute journey.",
24
- icon: "🚆"
24
+ details:
25
+ "Take any 'Bandel Local' or 'Burdwan Local' from Howrah Station. Serampore is about a 30-40 minute journey.",
26
+ icon: "🚆",
25
27
  },
26
28
  {
27
29
  name: "By Road (Kolkata)",
28
- details: "Serampore is roughly 25km from Central Kolkata via the Grand Trunk (GT) Road or the Delhi Road.",
29
- icon: "🚗"
30
+ details:
31
+ "Serampore is roughly 25km from Central Kolkata via the Grand Trunk (GT) Road or the Delhi Road.",
32
+ icon: "🚗",
30
33
  },
31
34
  {
32
35
  name: "Local Transport",
33
- details: "Auto-rickshaws and Totomod (E-rickshaws) are the lifeline here. They are available 24/7 at the stations.",
34
- icon: "🛺"
35
- }
36
+ details:
37
+ "Auto-rickshaws and Totomod (E-rickshaws) are the lifeline here. They are available 24/7 at the stations.",
38
+ icon: "🛺",
39
+ },
36
40
  ];
37
41
 
38
42
  const stayOptions = [
@@ -56,25 +60,25 @@ const stayOptions = [
56
60
  type: "Luxury",
57
61
  desc: "If you prefer staying in the heart of Kolkata and traveling for the events.",
58
62
  href: "https://www.peerlesshotels.com/",
59
- }
63
+ },
60
64
  ];
61
65
 
62
66
  const highlights = [
63
67
  {
64
68
  title: "St. Olav's Church",
65
69
  desc: "A stunning piece of Danish architecture from 1800, restored to its former glory.",
66
- img: "https://static.toiimg.com/photo/52947147/.jpg"
70
+ img: "https://static.toiimg.com/photo/52947147/.jpg",
67
71
  },
68
72
  {
69
73
  title: "Serampore College",
70
74
  desc: "One of the oldest Western university institutions in Asia, established in 1818.",
71
- img: "https://images.unsplash.com/photo-1562774053-701939374585?auto=format&fit=crop&q=80&w=600"
75
+ img: "https://images.unsplash.com/photo-1562774053-701939374585?auto=format&fit=crop&q=80&w=600",
72
76
  },
73
77
  {
74
78
  title: "The Riverfront",
75
79
  desc: "Take a peaceful walk along the Hooghly river during sunset for a magical view.",
76
- img: "https://images.unsplash.com/photo-1582510003544-4d00b7f74220?auto=format&fit=crop&q=80&w=600"
77
- }
80
+ img: "https://images.unsplash.com/photo-1582510003544-4d00b7f74220?auto=format&fit=crop&q=80&w=600",
81
+ },
78
82
  ];
79
83
 
80
84
  const foodSpots = [
@@ -82,20 +86,20 @@ const foodSpots = [
82
86
  name: "Mahesh Chandra Dutta",
83
87
  special: "Gutka Sandesh",
84
88
  type: "Legendary Sweets",
85
- desc: "Over 160 years old! You must try their signature Gutka Sandesh."
89
+ desc: "Over 160 years old! You must try their signature Gutka Sandesh.",
86
90
  },
87
91
  {
88
92
  name: "Denmark Tavern",
89
93
  special: "Heritage Dining",
90
94
  type: "Restaurant",
91
- desc: "Great for a colonial-style lunch by the river."
95
+ desc: "Great for a colonial-style lunch by the river.",
92
96
  },
93
97
  {
94
98
  name: "Mukherjee's",
95
99
  special: "Fish Fry & Mughlai",
96
100
  type: "Bengali Cuisine",
97
- desc: "A local favorite for authentic Bengali snacks and meals."
98
- }
101
+ desc: "A local favorite for authentic Bengali snacks and meals.",
102
+ },
99
103
  ];
100
104
 
101
105
  export default function TravelGuidePage() {
@@ -107,34 +111,76 @@ export default function TravelGuidePage() {
107
111
  location: "Serampore",
108
112
  address: "54A, G.T. Road, Serampore, W.B.",
109
113
  transport: [
110
- { name: "Serampore Station", details: "3 mins by Auto/Toto from the station. Located on the main G.T. Road.", icon: "🚆" },
111
- { name: "Parking", details: "Limited parking available near the banquet hall. We recommend using local transport.", icon: "🅿️" },
112
- { name: "Landmark", details: "Near Belting Bazar / Serampore Court area.", icon: "📍" }
114
+ {
115
+ name: "Serampore Station",
116
+ details:
117
+ "3 mins by Auto/Toto from the station. Located on the main G.T. Road.",
118
+ icon: "🚆",
119
+ },
120
+ {
121
+ name: "Parking",
122
+ details:
123
+ "Limited parking available near the banquet hall. We recommend using local transport.",
124
+ icon: "🅿️",
125
+ },
126
+ {
127
+ name: "Landmark",
128
+ details: "Near Belting Bazar / Serampore Court area.",
129
+ icon: "📍",
130
+ },
113
131
  ],
114
- stay: stayOptions.filter(s => s.name !== "The Peerless Inn"),
115
- map: "https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3679.3779465759876!2d88.33077587399126!3d22.75135112639763!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x39f89b287ddfb39b%3A0xc67348083f7cea9d!2sAnandamayee%20Bhawan!5e0!3m2!1sen!2sin!4v1765848206729!5m2!1sen!2sin"
132
+ stay: stayOptions.filter((s) => s.name !== "The Peerless Inn"),
133
+ map: "https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3679.3779465759876!2d88.33077587399126!3d22.75135112639763!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x39f89b287ddfb39b%3A0xc67348083f7cea9d!2sAnandamayee%20Bhawan!5e0!3m2!1sen!2sin!4v1765848206729!5m2!1sen!2sin",
116
134
  },
117
135
  reception: {
118
136
  name: "Friends Union Club",
119
137
  location: "Konnagar",
120
138
  address: "Gangadhar Chatterjee Bhaban, Konnagar, W.B.",
121
139
  transport: [
122
- { name: "Konnagar Station", details: "5-7 mins by Toto from Konnagar station (East side).", icon: "🚆" },
123
- { name: "By Road", details: "Accessible via G.T. Road. Look for the Friends Union Club signage.", icon: "🚗" },
124
- { name: "Landmark", details: "Near Konnagar Ferry Ghat / G.T. Road junction.", icon: "📍" }
140
+ {
141
+ name: "Konnagar Station",
142
+ details: "5-7 mins by Toto from Konnagar station (East side).",
143
+ icon: "🚆",
144
+ },
145
+ {
146
+ name: "By Road",
147
+ details:
148
+ "Accessible via G.T. Road. Look for the Friends Union Club signage.",
149
+ icon: "🚗",
150
+ },
151
+ {
152
+ name: "Landmark",
153
+ details: "Near Konnagar Ferry Ghat / G.T. Road junction.",
154
+ icon: "📍",
155
+ },
156
+ ],
157
+ stay: [
158
+ stayOptions[2],
159
+ {
160
+ name: "Konnagar Guest Houses",
161
+ distance: "Local",
162
+ type: "Budget",
163
+ desc: "Basic local stays available nearby.",
164
+ },
125
165
  ],
126
- stay: [stayOptions[2], { name: "Konnagar Guest Houses", distance: "Local", type: "Budget", desc: "Basic local stays available nearby." }],
127
- map: "https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3680.8284397695707!2d88.35295167398938!3d22.697429628386114!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x39f89c85a91d38fd%3A0x19dcd2c61895f79f!2sKonnagar%20Friends%20Union%20Club%20Community%20Centre%2FGangadhar%20Chatterjee%20Bhaban!5e0!3m2!1sen!2sin!4v1765848530552!5m2!1sen!2sin"
128
- }
166
+ map: "https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3680.8284397695707!2d88.35295167398938!3d22.697429628386114!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x39f89c85a91d38fd%3A0x19dcd2c61895f79f!2sKonnagar%20Friends%20Union%20Club%20Community%20Centre%2FGangadhar%20Chatterjee%20Bhaban!5e0!3m2!1sen!2sin!4v1765848530552!5m2!1sen!2sin",
167
+ },
129
168
  };
130
169
 
131
170
  const renderTransport = () => (
132
171
  <div className="grid md:grid-cols-3 gap-6 md:gap-8 py-4 px-1">
133
172
  {venueData[activeVenue].transport.map((hub: any, i: number) => (
134
- <Card key={i} className="bg-white/50 dark:bg-zinc-900/50 backdrop-blur-md border border-default-100 dark:border-default-800 p-5 md:p-6 shadow-sm">
173
+ <Card
174
+ key={i}
175
+ className="bg-white/50 dark:bg-zinc-900/50 backdrop-blur-md border border-default-100 dark:border-default-800 p-5 md:p-6 shadow-sm"
176
+ >
135
177
  <div className="text-3xl md:text-4xl mb-3 md:mb-4">{hub.icon}</div>
136
- <h3 className="text-lg md:text-xl font-bold text-default-900 dark:text-white mb-2">{hub.name}</h3>
137
- <p className="text-default-500 text-xs md:text-sm leading-relaxed">{hub.details}</p>
178
+ <h3 className="text-lg md:text-xl font-bold text-default-900 dark:text-white mb-2">
179
+ {hub.name}
180
+ </h3>
181
+ <p className="text-default-500 text-xs md:text-sm leading-relaxed">
182
+ {hub.details}
183
+ </p>
138
184
  </Card>
139
185
  ))}
140
186
  </div>
@@ -143,14 +189,37 @@ export default function TravelGuidePage() {
143
189
  const renderStay = () => (
144
190
  <div className="grid md:grid-cols-3 gap-6 md:gap-8 py-4 px-1">
145
191
  {venueData[activeVenue].stay.map((stay: any, i: number) => (
146
- <Card key={i} className="bg-white/50 dark:bg-zinc-900/50 backdrop-blur-md border border-wedding-gold-200/50 dark:border-wedding-gold-800/50 p-5 md:p-6 shadow-md hover:border-wedding-pink-400 transition-colors">
192
+ <Card
193
+ key={i}
194
+ className="bg-white/50 dark:bg-zinc-900/50 backdrop-blur-md border border-wedding-gold-200/50 dark:border-wedding-gold-800/50 p-5 md:p-6 shadow-md hover:border-wedding-pink-400 transition-colors"
195
+ >
147
196
  <div className="flex justify-between items-start mb-3 md:mb-4">
148
- <span className="bg-wedding-gold-100 dark:bg-wedding-gold-900/30 text-wedding-gold-700 text-[8px] md:text-[10px] px-2 py-1 rounded-full font-black uppercase">{stay.type}</span>
149
- <span className="text-[8px] md:text-[10px] text-default-400 font-mono italic">{stay.distance}</span>
197
+ <span className="bg-wedding-gold-100 dark:bg-wedding-gold-900/30 text-wedding-gold-700 text-[8px] md:text-[10px] px-2 py-1 rounded-full font-black uppercase">
198
+ {stay.type}
199
+ </span>
200
+ <span className="text-[8px] md:text-[10px] text-default-400 font-mono italic">
201
+ {stay.distance}
202
+ </span>
150
203
  </div>
151
- <h3 className="text-lg md:text-xl font-bold text-default-900 dark:text-white mb-2">{stay.name}</h3>
152
- <p className="text-xs md:text-sm text-default-500 mb-4 md:mb-6 flex-grow">{stay.desc}</p>
153
- {stay.href && <Button as={Link} href={stay.href} isExternal color="danger" variant="flat" size="sm" className="w-full font-bold">Book Now</Button>}
204
+ <h3 className="text-lg md:text-xl font-bold text-default-900 dark:text-white mb-2">
205
+ {stay.name}
206
+ </h3>
207
+ <p className="text-xs md:text-sm text-default-500 mb-4 md:mb-6 flex-grow">
208
+ {stay.desc}
209
+ </p>
210
+ {stay.href && (
211
+ <Button
212
+ isExternal
213
+ as={Link}
214
+ className="w-full font-bold"
215
+ color="danger"
216
+ href={stay.href}
217
+ size="sm"
218
+ variant="flat"
219
+ >
220
+ Book Now
221
+ </Button>
222
+ )}
154
223
  </Card>
155
224
  ))}
156
225
  </div>
@@ -159,14 +228,26 @@ export default function TravelGuidePage() {
159
228
  const renderExplore = () => (
160
229
  <div className="grid md:grid-cols-3 gap-6 md:gap-8 py-4 px-1">
161
230
  {highlights.map((item, i) => (
162
- <Card key={i} className="h-full border-none shadow-xl overflow-hidden group">
231
+ <Card
232
+ key={i}
233
+ className="h-full border-none shadow-xl overflow-hidden group"
234
+ >
163
235
  <div className="relative h-40 md:h-48 overflow-hidden">
164
- <Image src={item.img} alt={item.title} removeWrapper className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700" />
236
+ <Image
237
+ removeWrapper
238
+ alt={item.title}
239
+ className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700"
240
+ src={item.img}
241
+ />
165
242
  <div className="absolute inset-0 bg-gradient-to-t from-black/60 to-transparent" />
166
- <h3 className="absolute bottom-3 left-3 text-white font-bold text-lg">{item.title}</h3>
243
+ <h3 className="absolute bottom-3 left-3 text-white font-bold text-lg">
244
+ {item.title}
245
+ </h3>
167
246
  </div>
168
247
  <CardBody className="p-4 bg-white dark:bg-zinc-900">
169
- <p className="text-default-500 text-xs md:text-sm italic leading-relaxed">{item.desc}</p>
248
+ <p className="text-default-500 text-xs md:text-sm italic leading-relaxed">
249
+ {item.desc}
250
+ </p>
170
251
  </CardBody>
171
252
  </Card>
172
253
  ))}
@@ -176,11 +257,22 @@ export default function TravelGuidePage() {
176
257
  const renderFood = () => (
177
258
  <div className="grid md:grid-cols-3 gap-6 md:gap-8 py-4 px-1">
178
259
  {foodSpots.map((spot, i) => (
179
- <Card key={i} className="bg-wedding-pink-50/30 dark:bg-wedding-pink-900/10 border-2 border-dashed border-wedding-pink-200 p-5 md:p-6">
180
- <span className="text-[8px] md:text-[9px] font-black bg-wedding-pink-500 text-white px-2 py-0.5 rounded-full w-fit mb-2 md:mb-3">{spot.type}</span>
181
- <h3 className="text-lg md:text-xl font-bold text-wedding-pink-700 dark:text-wedding-pink-300 mb-1">{spot.name}</h3>
182
- <p className="text-[10px] md:text-xs font-bold text-wedding-gold-600 mb-2 md:mb-3 underline decoration-wedding-gold-200">Try: {spot.special}</p>
183
- <p className="text-default-500 text-xs md:text-sm leading-relaxed">{spot.desc}</p>
260
+ <Card
261
+ key={i}
262
+ className="bg-wedding-pink-50/30 dark:bg-wedding-pink-900/10 border-2 border-dashed border-wedding-pink-200 p-5 md:p-6"
263
+ >
264
+ <span className="text-[8px] md:text-[9px] font-black bg-wedding-pink-500 text-white px-2 py-0.5 rounded-full w-fit mb-2 md:mb-3">
265
+ {spot.type}
266
+ </span>
267
+ <h3 className="text-lg md:text-xl font-bold text-wedding-pink-700 dark:text-wedding-pink-300 mb-1">
268
+ {spot.name}
269
+ </h3>
270
+ <p className="text-[10px] md:text-xs font-bold text-wedding-gold-600 mb-2 md:mb-3 underline decoration-wedding-gold-200">
271
+ Try: {spot.special}
272
+ </p>
273
+ <p className="text-default-500 text-xs md:text-sm leading-relaxed">
274
+ {spot.desc}
275
+ </p>
184
276
  </Card>
185
277
  ))}
186
278
  </div>
@@ -191,14 +283,20 @@ export default function TravelGuidePage() {
191
283
  <div className="flex flex-col lg:grid lg:grid-cols-2 gap-8 md:gap-10">
192
284
  <div className="space-y-6">
193
285
  <div className="bg-blue-50 dark:bg-blue-900/20 p-5 md:p-6 rounded-[24px] md:rounded-[32px] border border-blue-100 dark:border-blue-800">
194
- <h4 className="font-bold text-blue-700 dark:text-blue-300 mb-2 flex items-center gap-2 text-sm md:text-base">❄️ Winter in Bengal</h4>
286
+ <h4 className="font-bold text-blue-700 dark:text-blue-300 mb-2 flex items-center gap-2 text-sm md:text-base">
287
+ ❄️ Winter in Bengal
288
+ </h4>
195
289
  <p className="text-xs md:text-sm text-default-600 dark:text-gray-300 leading-relaxed">
196
- January is the peak of winter. Temperatures can drop to 12°C at night.
197
- <strong> We recommend packing light woolens</strong> for the evening ceremonies.
290
+ January is the peak of winter. Temperatures can drop to 12°C at
291
+ night.
292
+ <strong> We recommend packing light woolens</strong> for the
293
+ evening ceremonies.
198
294
  </p>
199
295
  </div>
200
296
  <div className="bg-amber-50 dark:bg-amber-900/20 p-5 md:p-6 rounded-[24px] md:rounded-[32px] border border-amber-100 dark:border-amber-800">
201
- <h4 className="font-bold text-amber-700 dark:text-amber-300 mb-2 flex items-center gap-2 text-sm md:text-base">🛺 Auto Estimates</h4>
297
+ <h4 className="font-bold text-amber-700 dark:text-amber-300 mb-2 flex items-center gap-2 text-sm md:text-base">
298
+ 🛺 Auto Estimates
299
+ </h4>
202
300
  <ul className="text-xs md:text-sm text-default-600 dark:text-gray-300 space-y-1">
203
301
  <li>• Station to Venue (Reserved): ₹40 - ₹60</li>
204
302
  <li>• Station to Venue (Shared): ₹10 - ₹15</li>
@@ -207,7 +305,9 @@ export default function TravelGuidePage() {
207
305
  </div>
208
306
 
209
307
  <div className="bg-zinc-50 dark:bg-zinc-900 p-6 md:p-8 rounded-[24px] md:rounded-[32px] border border-default-200">
210
- <h4 className="font-bold text-default-800 dark:text-white mb-4 flex items-center gap-2 text-sm md:text-base">🗣️ Bengali 101</h4>
308
+ <h4 className="font-bold text-default-800 dark:text-white mb-4 flex items-center gap-2 text-sm md:text-base">
309
+ 🗣️ Bengali 101
310
+ </h4>
211
311
  <div className="space-y-3 md:space-y-4">
212
312
  {[
213
313
  { en: "Hello/Greetings", bn: "Nomoshkar" },
@@ -215,9 +315,18 @@ export default function TravelGuidePage() {
215
315
  { en: "How are you?", bn: "Kemon achen?" },
216
316
  { en: "Very Good", bn: "Khub bhalo" },
217
317
  ].map((p, i) => (
218
- <div key={i} className="flex justify-between border-b border-default-100 pb-2 last:border-none">
219
- <span className="text-xs md:text-sm text-default-500">{p.en}</span>
220
- <span className={`${fontSans.className} font-bold text-wedding-pink-600 text-sm md:text-base`}>{p.bn}</span>
318
+ <div
319
+ key={i}
320
+ className="flex justify-between border-b border-default-100 pb-2 last:border-none"
321
+ >
322
+ <span className="text-xs md:text-sm text-default-500">
323
+ {p.en}
324
+ </span>
325
+ <span
326
+ className={`${fontSans.className} font-bold text-wedding-pink-600 text-sm md:text-base`}
327
+ >
328
+ {p.bn}
329
+ </span>
221
330
  </div>
222
331
  ))}
223
332
  </div>
@@ -227,14 +336,16 @@ export default function TravelGuidePage() {
227
336
  <Divider className="my-8 md:my-10 opacity-50" />
228
337
 
229
338
  {/* History, Legal & Bengal Context Section */}
230
- <motion.div
231
- initial={{ opacity: 0, y: 20 }}
232
- whileInView={{ opacity: 1, y: 0 }}
339
+ <motion.div
233
340
  className="bg-wedding-gold-50/50 dark:bg-wedding-gold-900/10 p-6 md:p-12 rounded-[32px] md:rounded-[40px] border border-wedding-gold-200/50"
341
+ initial={{ opacity: 0, y: 20 }}
342
+ whileInView={{ opacity: 1, y: 0 }}
234
343
  >
235
344
  <div className="max-w-4xl mx-auto space-y-6 md:space-y-8">
236
345
  <div className="text-center space-y-2">
237
- <h3 className={`${fontSans.className} text-2xl md:text-3xl font-black text-default-800 dark:text-white uppercase tracking-tight leading-tight`}>
346
+ <h3
347
+ className={`${fontSans.className} text-2xl md:text-3xl font-black text-default-800 dark:text-white uppercase tracking-tight leading-tight`}
348
+ >
238
349
  Our Union: A Secular & Social Milestone
239
350
  </h3>
240
351
  <p className="text-wedding-pink-600 dark:text-wedding-pink-400 font-mono text-[9px] md:text-xs uppercase tracking-widest font-bold">
@@ -247,10 +358,21 @@ export default function TravelGuidePage() {
247
358
  <span className="text-xl">⚖️</span> Legal Equality
248
359
  </h4>
249
360
  <p>
250
- Our marriage is solemnized under <strong>Section 13 of Act XLIII of 1954</strong>. In a country where marriage is often tied to religious conversion, the Special Marriage Act (SMA) provides a truly secular alternative. It allows individuals from different religious backgrounds—like ours—to unite as equal partners under the law, <strong>without the need for conversion or the renunciation of one's own faith.</strong>
361
+ Our marriage is solemnized under{" "}
362
+ <strong>Section 13 of Act XLIII of 1954</strong>. In a country
363
+ where marriage is often tied to religious conversion, the
364
+ Special Marriage Act (SMA) provides a truly secular alternative.
365
+ It allows individuals from different religious backgrounds—like
366
+ ours—to unite as equal partners under the law,{" "}
367
+ <strong>
368
+ without the need for conversion or the renunciation of
369
+ one&apos;s own faith.
370
+ </strong>
251
371
  </p>
252
372
  <p>
253
- This legal framework ensures that our 10-year journey of love is recognized by the state as a civil union, prioritizing mutual consent and individual rights above all else.
373
+ This legal framework ensures that our 10-year journey of love is
374
+ recognized by the state as a civil union, prioritizing mutual
375
+ consent and individual rights above all else.
254
376
  </p>
255
377
  </div>
256
378
  <div className="space-y-3 md:space-y-4">
@@ -258,16 +380,29 @@ export default function TravelGuidePage() {
258
380
  <span className="text-xl">🌾</span> The Bengal Legacy
259
381
  </h4>
260
382
  <p>
261
- West Bengal has long been a beacon of progressive thought and communal harmony in India. In the land of <strong>Rabindranath Tagore and Kazi Nazrul Islam</strong>, our union finds its natural home. Bengal's rich history of syncretism—often called the <em>Ganga-Jamuni Tehzeeb</em>—celebrates the beauty of diverse cultures coexisting.
383
+ West Bengal has long been a beacon of progressive thought and
384
+ communal harmony in India. In the land of{" "}
385
+ <strong>Rabindranath Tagore and Kazi Nazrul Islam</strong>, our
386
+ union finds its natural home. Bengal&apos;s rich history of
387
+ syncretism—often called the <em>Ganga-Jamuni Tehzeeb</em>
388
+ —celebrates the beauty of diverse cultures coexisting.
262
389
  </p>
263
390
  <p>
264
- A profound detail of our marriage is the role of our fathers—<strong>Hasir Mallick</strong> and <strong>Subhasis Saha</strong>—who stood together as legal witnesses. Their presence and signatures represent more than just a formality; they symbolize the inclusive and secular spirit of our families, proving that love and respect transcend all religious boundaries.
391
+ A profound detail of our marriage is the role of our fathers
392
+ <strong>Hasir Mallick</strong> and{" "}
393
+ <strong>Subhasis Saha</strong>—who stood together as legal
394
+ witnesses. Their presence and signatures represent more than
395
+ just a formality; they symbolize the inclusive and secular
396
+ spirit of our families, proving that love and respect transcend
397
+ all religious boundaries.
265
398
  </p>
266
399
  </div>
267
400
  </div>
268
401
  <div className="pt-4 md:pt-6 border-t border-wedding-gold-200/30 text-center">
269
402
  <p className="text-[10px] md:text-xs italic text-default-400">
270
- &quot;Our union is a small part of a larger story—one where modern India embraces love as the ultimate bridge between different worlds.&quot;
403
+ &quot;Our union is a small part of a larger story—one where modern
404
+ India embraces love as the ultimate bridge between different
405
+ worlds.&quot;
271
406
  </p>
272
407
  </div>
273
408
  </div>
@@ -280,13 +415,17 @@ export default function TravelGuidePage() {
280
415
  {/* Header */}
281
416
  <section className="text-center mb-10 md:mb-16 space-y-4 max-w-full">
282
417
  <motion.div
283
- initial={{ opacity: 0, scale: 0.9 }}
284
418
  animate={{ opacity: 1, scale: 1 }}
285
419
  className="bg-wedding-pink-50 dark:bg-wedding-pink-900/20 w-fit px-4 py-1 rounded-full mx-auto mb-2 border border-wedding-pink-200"
420
+ initial={{ opacity: 0, scale: 0.9 }}
286
421
  >
287
- <span className="text-[9px] md:text-[10px] font-black uppercase tracking-[0.3em] text-wedding-pink-600 dark:text-wedding-pink-400">Visitor's Companion</span>
422
+ <span className="text-[9px] md:text-[10px] font-black uppercase tracking-[0.3em] text-wedding-pink-600 dark:text-wedding-pink-400">
423
+ Visitor&apos;s Companion
424
+ </span>
288
425
  </motion.div>
289
- <h1 className={`${fontCursive.className} text-5xl md:text-8xl text-wedding-pink-600 dark:text-wedding-pink-400 py-2 leading-tight`}>
426
+ <h1
427
+ className={`${fontCursive.className} text-5xl md:text-8xl text-wedding-pink-600 dark:text-wedding-pink-400 py-2 leading-tight`}
428
+ >
290
429
  Travel Guide
291
430
  </h1>
292
431
  </section>
@@ -294,22 +433,30 @@ export default function TravelGuidePage() {
294
433
  {/* Venue Selector - High Level */}
295
434
  <div className="max-w-xl mx-auto mb-12">
296
435
  <div className="flex flex-col items-center mb-6 text-center space-y-2">
297
- <h2 className={`${fontSans.className} text-xl md:text-2xl font-black text-default-800 dark:text-white uppercase tracking-tight`}>Which event are you attending?</h2>
298
- <p className="text-xs text-default-400 italic">Information will update based on your selection</p>
436
+ <h2
437
+ className={`${fontSans.className} text-xl md:text-2xl font-black text-default-800 dark:text-white uppercase tracking-tight`}
438
+ >
439
+ Which event are you attending?
440
+ </h2>
441
+ <p className="text-xs text-default-400 italic">
442
+ Information will update based on your selection
443
+ </p>
299
444
  </div>
300
- <Tabs
301
- aria-label="Venue Selector"
302
- color="danger"
303
- variant="solid"
445
+ <Tabs
304
446
  fullWidth
305
- selectedKey={activeVenue}
306
- onSelectionChange={(key) => setActiveVenue(key as string)}
447
+ aria-label="Venue Selector"
307
448
  classNames={{
308
- tabList: "p-1 rounded-xl bg-default-100 dark:bg-zinc-900 border border-default-200 dark:border-zinc-800 shadow-sm",
449
+ tabList:
450
+ "p-1 rounded-xl bg-default-100 dark:bg-zinc-900 border border-default-200 dark:border-zinc-800 shadow-sm",
309
451
  cursor: "bg-white dark:bg-zinc-800 shadow-md rounded-lg",
310
452
  tab: "h-12",
311
- tabContent: "font-bold text-default-600 group-data-[selected=true]:text-wedding-pink-600"
453
+ tabContent:
454
+ "font-bold text-default-600 group-data-[selected=true]:text-wedding-pink-600",
312
455
  }}
456
+ color="danger"
457
+ selectedKey={activeVenue}
458
+ variant="solid"
459
+ onSelectionChange={(key) => setActiveVenue(key as string)}
313
460
  >
314
461
  <Tab key="wedding" title="Wedding Ceremony" />
315
462
  <Tab key="reception" title="Reception Party" />
@@ -318,63 +465,126 @@ export default function TravelGuidePage() {
318
465
 
319
466
  <motion.div
320
467
  key={activeVenue}
321
- initial={{ opacity: 0, x: 10 }}
322
468
  animate={{ opacity: 1, x: 0 }}
323
- transition={{ duration: 0.4 }}
324
469
  className="space-y-16"
470
+ initial={{ opacity: 0, x: 10 }}
471
+ transition={{ duration: 0.4 }}
325
472
  >
326
473
  {/* Map Section Integrated */}
327
474
  <section className="px-2 md:px-0">
328
475
  <Card className="w-full h-[350px] md:h-[500px] border-none shadow-2xl rounded-[32px] md:rounded-[40px] overflow-hidden relative">
329
- <div className="absolute top-4 left-4 z-10 bg-white/90 dark:bg-black/80 backdrop-blur-md px-4 py-2 rounded-xl border border-wedding-gold-200 flex items-center gap-2">
330
- <MapPinIcon size={16} className="text-wedding-pink-500" />
331
- <div className="flex flex-col">
332
- <span className="text-[10px] font-black uppercase text-wedding-gold-600 leading-none mb-1">Destination</span>
333
- <span className="text-xs font-bold text-default-800 dark:text-white leading-none">{venueData[activeVenue].name}</span>
334
- </div>
335
- </div>
336
- <iframe
337
- src={venueData[activeVenue].map}
338
- className="w-full h-full border-none"
476
+ <div className="absolute top-4 left-4 z-10 bg-white/90 dark:bg-black/80 backdrop-blur-md px-4 py-2 rounded-xl border border-wedding-gold-200 flex items-center gap-2">
477
+ <MapPinIcon className="text-wedding-pink-500" size={16} />
478
+ <div className="flex flex-col">
479
+ <span className="text-[10px] font-black uppercase text-wedding-gold-600 leading-none mb-1">
480
+ Destination
481
+ </span>
482
+ <span className="text-xs font-bold text-default-800 dark:text-white leading-none">
483
+ {venueData[activeVenue].name}
484
+ </span>
485
+ </div>
486
+ </div>
487
+ <iframe
339
488
  allowFullScreen
489
+ className="w-full h-full border-none"
340
490
  loading="lazy"
491
+ src={venueData[activeVenue].map}
492
+ title={`${venueData[activeVenue].name} Location Map`}
341
493
  />
342
494
  </Card>
343
495
  </section>
344
496
 
345
497
  {/* Dynamic Content: Tabs for Desktop, Accordion for Mobile */}
346
498
  <div className="hidden md:block">
347
- <Tabs aria-label="Guide Categories" color="danger" variant="underlined" fullWidth
499
+ <Tabs
500
+ fullWidth
501
+ aria-label="Guide Categories"
348
502
  classNames={{
349
- tabList: "gap-8 w-full relative rounded-none p-0 border-b border-divider mb-12",
503
+ tabList:
504
+ "gap-8 w-full relative rounded-none p-0 border-b border-divider mb-12",
350
505
  cursor: "w-full bg-wedding-pink-500",
351
506
  tab: "px-0 h-12",
352
- tabContent: "group-data-[selected=true]:text-wedding-pink-500 font-bold text-lg"
507
+ tabContent:
508
+ "group-data-[selected=true]:text-wedding-pink-500 font-bold text-lg",
353
509
  }}
510
+ color="danger"
511
+ variant="underlined"
354
512
  >
355
- <Tab key="transport" title="Travel Tips">{renderTransport()}</Tab>
356
- <Tab key="stay" title="Nearby Stay">{renderStay()}</Tab>
357
- <Tab key="explore" title="Highlights">{renderExplore()}</Tab>
358
- <Tab key="food" title="Food">{renderFood()}</Tab>
359
- <Tab key="tips" title="Other Tips">{renderTips()}</Tab>
513
+ <Tab key="transport" title="Travel Tips">
514
+ {renderTransport()}
515
+ </Tab>
516
+ <Tab key="stay" title="Nearby Stay">
517
+ {renderStay()}
518
+ </Tab>
519
+ <Tab key="explore" title="Highlights">
520
+ {renderExplore()}
521
+ </Tab>
522
+ <Tab key="food" title="Food">
523
+ {renderFood()}
524
+ </Tab>
525
+ <Tab key="tips" title="Other Tips">
526
+ {renderTips()}
527
+ </Tab>
360
528
  </Tabs>
361
529
  </div>
362
530
 
363
531
  <div className="md:hidden">
364
- <Accordion variant="splitted" selectionMode="multiple" defaultExpandedKeys={["transport"]}>
365
- <AccordionItem key="transport" aria-label="Travel Tips" title={<span className="font-bold text-wedding-pink-600">Travel Tips</span>}>
532
+ <Accordion
533
+ defaultExpandedKeys={["transport"]}
534
+ selectionMode="multiple"
535
+ variant="splitted"
536
+ >
537
+ <AccordionItem
538
+ key="transport"
539
+ aria-label="Travel Tips"
540
+ title={
541
+ <span className="font-bold text-wedding-pink-600">
542
+ Travel Tips
543
+ </span>
544
+ }
545
+ >
366
546
  {renderTransport()}
367
547
  </AccordionItem>
368
- <AccordionItem key="stay" aria-label="Nearby Stay" title={<span className="font-bold text-wedding-pink-600">Nearby Stay</span>}>
548
+ <AccordionItem
549
+ key="stay"
550
+ aria-label="Nearby Stay"
551
+ title={
552
+ <span className="font-bold text-wedding-pink-600">
553
+ Nearby Stay
554
+ </span>
555
+ }
556
+ >
369
557
  {renderStay()}
370
558
  </AccordionItem>
371
- <AccordionItem key="explore" aria-label="Highlights" title={<span className="font-bold text-wedding-pink-600">Highlights</span>}>
559
+ <AccordionItem
560
+ key="explore"
561
+ aria-label="Highlights"
562
+ title={
563
+ <span className="font-bold text-wedding-pink-600">
564
+ Highlights
565
+ </span>
566
+ }
567
+ >
372
568
  {renderExplore()}
373
569
  </AccordionItem>
374
- <AccordionItem key="food" aria-label="Food" title={<span className="font-bold text-wedding-pink-600">Food</span>}>
570
+ <AccordionItem
571
+ key="food"
572
+ aria-label="Food"
573
+ title={
574
+ <span className="font-bold text-wedding-pink-600">Food</span>
575
+ }
576
+ >
375
577
  {renderFood()}
376
578
  </AccordionItem>
377
- <AccordionItem key="tips" aria-label="Other Tips" title={<span className="font-bold text-wedding-pink-600">Other Tips</span>}>
579
+ <AccordionItem
580
+ key="tips"
581
+ aria-label="Other Tips"
582
+ title={
583
+ <span className="font-bold text-wedding-pink-600">
584
+ Other Tips
585
+ </span>
586
+ }
587
+ >
378
588
  {renderTips()}
379
589
  </AccordionItem>
380
590
  </Accordion>
@@ -382,16 +592,47 @@ export default function TravelGuidePage() {
382
592
  </motion.div>
383
593
 
384
594
  {/* Support Section */}
385
- <motion.div initial={{ opacity: 0 }} whileInView={{ opacity: 1 }} className="mt-20 md:mt-32 bg-gradient-to-r from-wedding-pink-500 to-wedding-gold-500 p-[1px] rounded-[32px] md:rounded-[40px] shadow-2xl shadow-wedding-pink-500/20">
595
+ <motion.div
596
+ className="mt-20 md:mt-32 bg-gradient-to-r from-wedding-pink-500 to-wedding-gold-500 p-[1px] rounded-[32px] md:rounded-[40px] shadow-2xl shadow-wedding-pink-500/20"
597
+ initial={{ opacity: 0 }}
598
+ whileInView={{ opacity: 1 }}
599
+ >
386
600
  <div className="bg-white dark:bg-zinc-950 p-8 md:p-16 rounded-[31px] md:rounded-[39px] text-center space-y-6">
387
601
  <div className="bg-wedding-pink-100 w-12 h-12 md:w-16 md:h-16 rounded-full flex items-center justify-center mx-auto mb-2">
388
- <MapPinIcon className="text-wedding-pink-500 w-6 h-6 md:w-8 md:h-8" />
602
+ <MapPinIcon className="text-wedding-pink-500 w-6 h-6 md:w-8 md:h-8" />
389
603
  </div>
390
- <h2 className={`${fontCursive.className} text-4xl md:text-5xl text-default-900 dark:text-white`}>Need a hand with your travel?</h2>
391
- <p className="text-default-500 max-w-xl mx-auto text-sm md:text-lg leading-relaxed">If you need any assistance with local bookings, station pickups, or have special requirements, Titas is just a message away.</p>
604
+ <h2
605
+ className={`${fontCursive.className} text-4xl md:text-5xl text-default-900 dark:text-white`}
606
+ >
607
+ Need a hand with your travel?
608
+ </h2>
609
+ <p className="text-default-500 max-w-xl mx-auto text-sm md:text-lg leading-relaxed">
610
+ If you need any assistance with local bookings, station pickups, or
611
+ have special requirements, the groom is just a message away.
612
+ </p>
392
613
  <div className="pt-4 md:pt-6 flex flex-col sm:flex-row justify-center gap-3 md:gap-4">
393
- <Button as={Link} href="https://wa.me/919123774239" color="success" variant="shadow" radius="full" size="lg" className="font-bold text-white px-8 md:px-10 h-12 md:h-14">WhatsApp Titas</Button>
394
- <Button as={Link} href="/" color="default" variant="flat" radius="full" size="lg" className="font-bold px-8 md:px-10 h-12 md:h-14">Return Home</Button>
614
+ <Button
615
+ as={Link}
616
+ className="font-bold text-white px-8 md:px-10 h-12 md:h-14"
617
+ color="success"
618
+ href="https://wa.me/91**********"
619
+ radius="full"
620
+ size="lg"
621
+ variant="shadow"
622
+ >
623
+ WhatsApp Groom
624
+ </Button>
625
+ <Button
626
+ as={Link}
627
+ className="font-bold px-8 md:px-10 h-12 md:h-14"
628
+ color="default"
629
+ href="/"
630
+ radius="full"
631
+ size="lg"
632
+ variant="flat"
633
+ >
634
+ Return Home
635
+ </Button>
395
636
  </div>
396
637
  </div>
397
638
  </motion.div>