diff --git a/src/app/about/page.tsx b/src/app/about/page.tsx index 2fb8a37..bc71512 100644 --- a/src/app/about/page.tsx +++ b/src/app/about/page.tsx @@ -1,11 +1,12 @@ import React from 'react' import About from '@/components/about/About' + const page = () => { - return ( -
- -
- ) + return ( +
+ +
+ ) } export default page diff --git a/src/app/api/auth/[...nextauth]/route.ts b/src/app/api/auth/[...nextauth]/route.ts index a3fe044..4270c10 100644 --- a/src/app/api/auth/[...nextauth]/route.ts +++ b/src/app/api/auth/[...nextauth]/route.ts @@ -1,2 +1,2 @@ -import { handlers } from "@/auth"; // Referring to the auth.ts we just created -export const { GET, POST } = handlers; \ No newline at end of file +import {handlers} from "@/auth"; // Referring to the auth.ts we just created +export const {GET, POST} = handlers; \ No newline at end of file diff --git a/src/app/api/auth/register/route.ts b/src/app/api/auth/register/route.ts index 8cb8c65..c68a75a 100644 --- a/src/app/api/auth/register/route.ts +++ b/src/app/api/auth/register/route.ts @@ -1,89 +1,84 @@ - -import { db } from "@/lib/drizzle"; -import { otps, users } from "@/lib/schema"; -import { signupSchema } from "@/lib/zod"; -import { hash } from "bcryptjs"; -import { NextRequest, NextResponse } from "next/server"; -import { z } from "zod"; +import {db} from "@/lib/drizzle"; +import {otps, users} from "@/lib/schema"; +import {signupSchema} from "@/lib/zod"; +import {hash} from "bcryptjs"; +import {NextRequest, NextResponse} from "next/server"; +import {z} from "zod"; import otpEmailTemplate from "@/lib/templates/otp-template"; import mailer from "@/lib/mailer"; - // `onboarding@uk-culture.org` email is for development only const senderEmail = process.env.SENDER_EMAIL || "onboarding@uk-culture.org"; - export async function POST(req: NextRequest) { - try { - const payload = await req.json(); - - const { email, name, password, username, alerts } = signupSchema.parse(payload) - if (!email || !name || !password || !username) { - return NextResponse.json( - { error: "name, username, email and password are required." }, - { status: 400 } - ); - } - - const userWithUsername = await db.query.users.findFirst({ - where: (users, { eq }) => eq(users.username, username), - }); - if (userWithUsername) throw new Error("User with username already exists."); - - const userWithEmail = await db.query.users.findFirst({ - where: (users, { eq }) => eq(users.email, email), - }); - - if (userWithEmail) throw new Error("User with email already exists."); - - const hashedPassword = await hash(password, 10); - - await db.insert(users).values({ - email, - name, - password: hashedPassword, - alerts, - username - }); - - - const otp = Math.floor(100000 + Math.random() * 900000).toString(); // 6-digit OTP - // Set expiration time (e.g., 10 minutes from now) - const expiresAt = new Date(Date.now() + 10 * 60 * 1000); // 10 minutes in the future - - const user = await db.query.users.findFirst({ - where: (users, { eq }) => eq(users.email, email), - }) - - await db.insert(otps).values({ - expiresAt, - otp, - userId: user!.id, - createdAt: new Date(), - }); - - - await mailer.sendMail({ - from: `Uttarakhand Culture <${senderEmail}>`, - to: [email], - subject: 'Verify you email with OTP', - html: otpEmailTemplate(name, otp), - }) - - - - - return NextResponse.json({ - message: `Registered. Now login!`, - }); - } catch (error: any) { - if (error instanceof z.ZodError) { - return NextResponse.json({ error: error.errors }, { status: 500 }); + try { + const payload = await req.json(); + + const {email, name, password, username, alerts} = signupSchema.parse(payload) + if (!email || !name || !password || !username) { + return NextResponse.json( + {error: "name, username, email and password are required."}, + {status: 400} + ); + } + + const userWithUsername = await db.query.users.findFirst({ + where: (users, {eq}) => eq(users.username, username), + }); + if (userWithUsername) throw new Error("User with username already exists."); + + const userWithEmail = await db.query.users.findFirst({ + where: (users, {eq}) => eq(users.email, email), + }); + + if (userWithEmail) throw new Error("User with email already exists."); + + const hashedPassword = await hash(password, 10); + + await db.insert(users).values({ + email, + name, + password: hashedPassword, + alerts, + username + }); + + + const otp = Math.floor(100000 + Math.random() * 900000).toString(); // 6-digit OTP + // Set expiration time (e.g., 10 minutes from now) + const expiresAt = new Date(Date.now() + 10 * 60 * 1000); // 10 minutes in the future + + const user = await db.query.users.findFirst({ + where: (users, {eq}) => eq(users.email, email), + }) + + await db.insert(otps).values({ + expiresAt, + otp, + userId: user!.id, + createdAt: new Date(), + }); + + + await mailer.sendMail({ + from: `Uttarakhand Culture <${senderEmail}>`, + to: [email], + subject: 'Verify you email with OTP', + html: otpEmailTemplate(name, otp), + }) + + + return NextResponse.json({ + message: `Registered. Now login!`, + }); + } catch (error: any) { + if (error instanceof z.ZodError) { + return NextResponse.json({error: error.errors}, {status: 500}); + } + console.log("[REGISTER_ERROR]: ", error); + return NextResponse.json({error: error.message}, {status: 500}); } - console.log("[REGISTER_ERROR]: ", error); - return NextResponse.json({ error: error.message }, { status: 500 }); - } } \ No newline at end of file diff --git a/src/app/api/auth/resend-otp/route.ts b/src/app/api/auth/resend-otp/route.ts index d6256bb..ba3f487 100644 --- a/src/app/api/auth/resend-otp/route.ts +++ b/src/app/api/auth/resend-otp/route.ts @@ -1,76 +1,76 @@ -import { db } from "@/lib/drizzle"; -import { otps } from "@/lib/schema"; -import { NextRequest, NextResponse } from "next/server"; -import { z } from "zod"; +import {db} from "@/lib/drizzle"; +import {otps} from "@/lib/schema"; +import {NextRequest, NextResponse} from "next/server"; +import {z} from "zod"; import otpEmailTemplate from "@/lib/templates/otp-template"; -import { auth } from "@/auth"; +import {auth} from "@/auth"; import mailer from "@/lib/mailer"; // `onboarding@uk-culture.org` email is for development only const senderEmail = process.env.SENDER_EMAIL || "onboarding@uk-culture.org"; export async function POST(req: NextRequest) { - try { - const session = await auth(); - if (!session) throw new Error("Login first to verify email"); + try { + const session = await auth(); + if (!session) throw new Error("Login first to verify email"); - const userWithEmail = await db.query.users.findFirst({ - where: (users, { eq }) => eq(users.email, session.user.email!), - }); + const userWithEmail = await db.query.users.findFirst({ + where: (users, {eq}) => eq(users.email, session.user.email!), + }); - if (!userWithEmail) throw new Error("User with email not exists."); + if (!userWithEmail) throw new Error("User with email not exists."); - const prevOtps = await db.query.otps.findMany({ - where: (otps, { eq }) => eq(otps.userId, userWithEmail.id), - orderBy: (otps, { desc }) => desc(otps.expiresAt), - }); + const prevOtps = await db.query.otps.findMany({ + where: (otps, {eq}) => eq(otps.userId, userWithEmail.id), + orderBy: (otps, {desc}) => desc(otps.expiresAt), + }); - // Check if there is a valid OTP - const now = new Date(); - const validOtp = prevOtps.find((otp) => otp.expiresAt > now); + // Check if there is a valid OTP + const now = new Date(); + const validOtp = prevOtps.find((otp) => otp.expiresAt > now); - if (validOtp) { - const remainingTimeInSeconds = Math.floor( - (validOtp.expiresAt.getTime() - now.getTime()) / 1000 - ); // Time in seconds - const minutes = Math.floor(remainingTimeInSeconds / 60); // Full minutes - const seconds = remainingTimeInSeconds % 60; // Remaining seconds + if (validOtp) { + const remainingTimeInSeconds = Math.floor( + (validOtp.expiresAt.getTime() - now.getTime()) / 1000 + ); // Time in seconds + const minutes = Math.floor(remainingTimeInSeconds / 60); // Full minutes + const seconds = remainingTimeInSeconds % 60; // Remaining seconds - return NextResponse.json( - { - message: `Please wait ${minutes} minutes and ${seconds} seconds before resending the OTP.`, - }, - { status: 429 } - ); - } + return NextResponse.json( + { + message: `Please wait ${minutes} minutes and ${seconds} seconds before resending the OTP.`, + }, + {status: 429} + ); + } - const otp = Math.floor(100000 + Math.random() * 900000).toString(); // 6-digit OTP - // Set expiration time (e.g., 10 minutes from now) - const expiresAt = new Date(Date.now() + 10 * 60 * 1000); // 10 minutes in the future + const otp = Math.floor(100000 + Math.random() * 900000).toString(); // 6-digit OTP + // Set expiration time (e.g., 10 minutes from now) + const expiresAt = new Date(Date.now() + 10 * 60 * 1000); // 10 minutes in the future - await db.insert(otps).values({ - expiresAt, - otp, - userId: userWithEmail.id, - createdAt: new Date(), - }); + await db.insert(otps).values({ + expiresAt, + otp, + userId: userWithEmail.id, + createdAt: new Date(), + }); - await mailer.sendMail({ - from: `Uttarakhand Culture <${senderEmail}>`, - to: [userWithEmail.email!], - subject: "Verify you email with OTP", - html: otpEmailTemplate(userWithEmail.name!, otp), - }); + await mailer.sendMail({ + from: `Uttarakhand Culture <${senderEmail}>`, + to: [userWithEmail.email!], + subject: "Verify you email with OTP", + html: otpEmailTemplate(userWithEmail.name!, otp), + }); - return NextResponse.json({ - message: `OTP has been resent to your email.`, - }); - } catch (error: any) { - if (error instanceof z.ZodError) { - return NextResponse.json({ error: error.errors }, { status: 500 }); + return NextResponse.json({ + message: `OTP has been resent to your email.`, + }); + } catch (error: any) { + if (error instanceof z.ZodError) { + return NextResponse.json({error: error.errors}, {status: 500}); + } + console.log("[OTP_RESEND_ERROR]: ", error); + return NextResponse.json({error: error.message}, {status: 500}); } - console.log("[OTP_RESEND_ERROR]: ", error); - return NextResponse.json({ error: error.message }, { status: 500 }); - } } diff --git a/src/app/api/auth/verify-otp/route.ts b/src/app/api/auth/verify-otp/route.ts index feb311e..082fe22 100644 --- a/src/app/api/auth/verify-otp/route.ts +++ b/src/app/api/auth/verify-otp/route.ts @@ -1,111 +1,110 @@ - -import { db } from "@/lib/drizzle"; -import { otps, users } from "@/lib/schema"; -import { NextRequest, NextResponse } from "next/server"; -import { z } from "zod"; -import { auth } from "@/auth"; -import { eq } from "drizzle-orm"; +import {db} from "@/lib/drizzle"; +import {otps, users} from "@/lib/schema"; +import {NextRequest, NextResponse} from "next/server"; +import {z} from "zod"; +import {auth} from "@/auth"; +import {eq} from "drizzle-orm"; // In-memory store for rate limiting -const rateLimit = new Map < string, { requests: number; lastRequestTime: number } >(); +const rateLimit = new Map(); // Rate limiting configuration const MAX_REQUESTS = 3; // Max requests per window const WINDOW_MS = 5 * 60 * 1000; // 5 minutes in milliseconds function checkRateLimit(userId: string): boolean { - const currentTime = Date.now(); - const userData = rateLimit.get(userId); - - if (userData) { - // Reset if the window has passed - if (currentTime - userData.lastRequestTime > WINDOW_MS) { - rateLimit.set(userId, { requests: 1, lastRequestTime: currentTime }); - return false; - } - // Increment request count if within window - if (userData.requests < MAX_REQUESTS) { - rateLimit.set(userId, { - requests: userData.requests + 1, - lastRequestTime: currentTime, - }); - return false; + const currentTime = Date.now(); + const userData = rateLimit.get(userId); + + if (userData) { + // Reset if the window has passed + if (currentTime - userData.lastRequestTime > WINDOW_MS) { + rateLimit.set(userId, {requests: 1, lastRequestTime: currentTime}); + return false; + } + // Increment request count if within window + if (userData.requests < MAX_REQUESTS) { + rateLimit.set(userId, { + requests: userData.requests + 1, + lastRequestTime: currentTime, + }); + return false; + } + // Rate limit exceeded + return true; + } else { + // Initialize user rate limit + rateLimit.set(userId, {requests: 1, lastRequestTime: currentTime}); + return false; } - // Rate limit exceeded - return true; - } else { - // Initialize user rate limit - rateLimit.set(userId, { requests: 1, lastRequestTime: currentTime }); - return false; - } } export async function POST(req: NextRequest) { - try { - const session = await auth(); - if (!session) throw new Error("Login first to verify email"); - - const userId = session.user.id; - - // Check rate limit - if (checkRateLimit(userId)) { - return NextResponse.json( - { error: "limit exceeded. Please try again after 5 minutes." }, - { status: 429 } - ); - } - - if (session.user.emailVerified) { - return NextResponse.json( - { message: "Email is already verified!" }, - { status: 200 } - ); - } - - const { otp } = await req.json(); - if (!otp) throw new Error("OTP is required"); - - const userWithEmail = await db.query.users.findFirst({ - where: (users, { eq }) => eq(users.email, session.user.email!), - }); - - if (!userWithEmail) throw new Error("User with email does not exist."); - - const latestOtp = await db.query.otps.findFirst({ - where: (otps, { eq }) => eq(otps.userId, userWithEmail.id), - orderBy: (otps, { desc }) => desc(otps.expiresAt), - }); - - if (!latestOtp) throw new Error("No OTP found for this user."); - - // Check if the OTP is valid (not expired) - const now = new Date(); - if (latestOtp.expiresAt < now) { - throw new Error("OTP has expired."); - } - - // Check if the provided OTP matches - if (latestOtp.otp !== otp) { - throw new Error("Invalid OTP."); - } - - // Mark email as verified - await db - .update(users) - .set({ emailVerified: new Date() }) - .where(eq(users.id, userWithEmail.id)); - - await db.delete(otps).where(eq(otps.userId, userWithEmail.id)); - - return NextResponse.json( - { message: "Email verified successfully!" }, - { status: 200 } - ); - } catch (error: any) { - if (error instanceof z.ZodError) { - return NextResponse.json({ error: error.errors }, { status: 500 }); + try { + const session = await auth(); + if (!session) throw new Error("Login first to verify email"); + + const userId = session.user.id; + + // Check rate limit + if (checkRateLimit(userId)) { + return NextResponse.json( + {error: "limit exceeded. Please try again after 5 minutes."}, + {status: 429} + ); + } + + if (session.user.emailVerified) { + return NextResponse.json( + {message: "Email is already verified!"}, + {status: 200} + ); + } + + const {otp} = await req.json(); + if (!otp) throw new Error("OTP is required"); + + const userWithEmail = await db.query.users.findFirst({ + where: (users, {eq}) => eq(users.email, session.user.email!), + }); + + if (!userWithEmail) throw new Error("User with email does not exist."); + + const latestOtp = await db.query.otps.findFirst({ + where: (otps, {eq}) => eq(otps.userId, userWithEmail.id), + orderBy: (otps, {desc}) => desc(otps.expiresAt), + }); + + if (!latestOtp) throw new Error("No OTP found for this user."); + + // Check if the OTP is valid (not expired) + const now = new Date(); + if (latestOtp.expiresAt < now) { + throw new Error("OTP has expired."); + } + + // Check if the provided OTP matches + if (latestOtp.otp !== otp) { + throw new Error("Invalid OTP."); + } + + // Mark email as verified + await db + .update(users) + .set({emailVerified: new Date()}) + .where(eq(users.id, userWithEmail.id)); + + await db.delete(otps).where(eq(otps.userId, userWithEmail.id)); + + return NextResponse.json( + {message: "Email verified successfully!"}, + {status: 200} + ); + } catch (error: any) { + if (error instanceof z.ZodError) { + return NextResponse.json({error: error.errors}, {status: 500}); + } + console.log("[OTP_ERROR]: ", error); + return NextResponse.json({error: error.message}, {status: 500}); } - console.log("[OTP_ERROR]: ", error); - return NextResponse.json({ error: error.message }, { status: 500 }); - } } diff --git a/src/app/auth/GoogleSignIn.css b/src/app/auth/GoogleSignIn.css index b971686..73cc60b 100644 --- a/src/app/auth/GoogleSignIn.css +++ b/src/app/auth/GoogleSignIn.css @@ -1,29 +1,29 @@ /* GoogleSignIn.css */ .google-sign-in-btn { - display: flex; - align-items: center; - justify-content: center; - gap: 8px; /* Space between icon and text */ - background-color: #4285f4; - color: white; - padding: 10px 20px; - border: none; - border-radius: 5px; - cursor: pointer; - font-weight: bold; - font-size: 16px; - transition: background-color 0.3s, box-shadow 0.3s; - box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2); + display: flex; + align-items: center; + justify-content: center; + gap: 8px; /* Space between icon and text */ + background-color: #4285f4; + color: white; + padding: 10px 20px; + border: none; + border-radius: 5px; + cursor: pointer; + font-weight: bold; + font-size: 16px; + transition: background-color 0.3s, box-shadow 0.3s; + box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2); } .google-sign-in-btn:hover { - background-color: #357ae8; - box-shadow: 0px 6px 12px rgba(0, 0, 0, 0.3); - transform: scale(1.02); /* Slight zoom effect */ + background-color: #357ae8; + box-shadow: 0px 6px 12px rgba(0, 0, 0, 0.3); + transform: scale(1.02); /* Slight zoom effect */ } .google-sign-in-btn:active { - background-color: #3367d6; - box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.2); - transform: scale(0.98); /* Slight shrink effect on click */ + background-color: #3367d6; + box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.2); + transform: scale(0.98); /* Slight shrink effect on click */ } diff --git a/src/app/auth/GoogleSignIn.tsx b/src/app/auth/GoogleSignIn.tsx index 75f19bf..64c40a2 100644 --- a/src/app/auth/GoogleSignIn.tsx +++ b/src/app/auth/GoogleSignIn.tsx @@ -1,40 +1,41 @@ -import React, { useEffect } from 'react'; -import { gapi } from 'gapi-script'; +import React, {useEffect} from 'react'; +import {gapi} from 'gapi-script'; import './GoogleSignIn.css'; const GoogleSignIn = () => { - useEffect(() => { - const start = () => { - gapi.client.init({ - clientId: '1060623493518-rnfa86uab5rrasuh2o7e82ufr34lg3s4.apps.googleusercontent.com', - scope: 'email', - }); - }; - gapi.load('client:auth2', start); - }, []); + useEffect(() => { + const start = () => { + gapi.client.init({ + clientId: '1060623493518-rnfa86uab5rrasuh2o7e82ufr34lg3s4.apps.googleusercontent.com', + scope: 'email', + }); + }; + gapi.load('client:auth2', start); + }, []); - const handleLogin = () => { - const auth2 = gapi.auth2.getAuthInstance(); - auth2.signIn().then((googleUser: { getBasicProfile: () => any; }) => { - const profile = googleUser.getBasicProfile(); - const userObj = { - name: profile.getName(), - email: profile.getEmail(), - imageUrl: profile.getImageUrl(), - }; - console.log('User data:', userObj); - // You can now send the user data to your backend for further processing - }); - }; + const handleLogin = () => { + const auth2 = gapi.auth2.getAuthInstance(); + auth2.signIn().then((googleUser: { getBasicProfile: () => any; }) => { + const profile = googleUser.getBasicProfile(); + const userObj = { + name: profile.getName(), + email: profile.getEmail(), + imageUrl: profile.getImageUrl(), + }; + console.log('User data:', userObj); + // You can now send the user data to your backend for further processing + }); + }; - return ( -
-

-

OR

-

- -
- ); + return ( +
+

+

OR

+

+ +
+ ); }; export default GoogleSignIn; diff --git a/src/app/auth/page.module.css b/src/app/auth/page.module.css index 05328ef..932218d 100644 --- a/src/app/auth/page.module.css +++ b/src/app/auth/page.module.css @@ -1,92 +1,93 @@ .container { - max-width: 400px; - margin: 0 auto; - padding: 20px; - border: 1px solid #ccc; - border-radius: 8px; - height: 100%; - width: 100%; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + max-width: 400px; + margin: 0 auto; + padding: 20px; + border: 1px solid #ccc; + border-radius: 8px; + height: 100%; + width: 100%; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); } .title { - text-align: center; - margin-bottom: 20px; - padding: 2px; + text-align: center; + margin-bottom: 20px; + padding: 2px; } .form { - display: flex; - flex-direction: column; + display: flex; + flex-direction: column; } + .errors { - color: red; - font-weight: 600; - padding: 2px; - margin-bottom: 10px; + color: red; + font-weight: 600; + padding: 2px; + margin-bottom: 10px; } .input { - width: 100%; - height: 3rem; - font-size: 1rem; - line-height: 1.5rem; - padding: 10px 18px 10px 18px; - border: 1px solid var(--line-grey); - border-radius: 5px; - outline: none; - border-radius: 4px; - margin: 4px; + width: 100%; + height: 3rem; + font-size: 1rem; + line-height: 1.5rem; + padding: 10px 18px 10px 18px; + border: 1px solid var(--line-grey); + border-radius: 5px; + outline: none; + border-radius: 4px; + margin: 4px; } .label { - padding: 2px; + padding: 2px; } .alerts { - margin: 4px; - margin-top: 10px; - margin-bottom: 10px; + margin: 4px; + margin-top: 10px; + margin-bottom: 10px; } .button { - color: white; - height: 3rem; - font-size: 1rem; - line-height: 1.5rem; - padding: 10px 18px 10px 18px; - border-radius: 5px; - background-color: var(--black); - transition: 0.2s ease-in-out; + color: white; + height: 3rem; + font-size: 1rem; + line-height: 1.5rem; + padding: 10px 18px 10px 18px; + border-radius: 5px; + background-color: var(--black); + transition: 0.2s ease-in-out; } .button:hover { - background-color: var(--slate-black); - cursor: pointer; + background-color: var(--slate-black); + cursor: pointer; } .toggle { - text-align: center; - margin-top: 10px; - cursor: pointer; - color: var(--slate-black); + text-align: center; + margin-top: 10px; + cursor: pointer; + color: var(--slate-black); } -.passwordContainer{ - position: relative; +.passwordContainer { + position: relative; } -.passwordToggle{ - position: absolute; - height: 100%; - display: flex; - top: 0; - align-items: center; - right: 1rem +.passwordToggle { + position: absolute; + height: 100%; + display: flex; + top: 0; + align-items: center; + right: 1rem } -.image{ - height: 25px; - width: 25px; +.image { + height: 25px; + width: 25px; } \ No newline at end of file diff --git a/src/app/auth/page.tsx b/src/app/auth/page.tsx index 9df963e..772e05e 100644 --- a/src/app/auth/page.tsx +++ b/src/app/auth/page.tsx @@ -1,284 +1,287 @@ "use client"; -import { useEffect, useState } from "react"; -import { useForm } from "react-hook-form"; -import { zodResolver } from "@hookform/resolvers/zod"; +import {useEffect, useState} from "react"; +import {useForm} from "react-hook-form"; +import {zodResolver} from "@hookform/resolvers/zod"; import styles from "./page.module.css"; -import { toast } from "sonner"; -import { loginSchema, signupSchema } from "@/lib/zod"; -import { signIn } from "next-auth/react"; -import { useRouter, useSearchParams } from "next/navigation"; +import {toast} from "sonner"; +import {loginSchema, signupSchema} from "@/lib/zod"; +import {signIn} from "next-auth/react"; +import {useRouter, useSearchParams} from "next/navigation"; import eye from "../../../public/eye.png"; import hide from "../../../public/eye-hide.png"; import Image from 'next/image'; import GoogleSignIn from './GoogleSignIn'; // import GoogleSignIn component export default function Auth() { - const [isSignup, setIsSignup] = useState(false); - const [isLoading, setIsLoading] = useState(false); - const [hidden, setHidden] = useState(true); - const [confirmHidden, setConfirmHidden] = useState(true); - const router = useRouter(); - const searchParams = useSearchParams(); - const callback = searchParams.get("callbackUrl"); + const [isSignup, setIsSignup] = useState(false); + const [isLoading, setIsLoading] = useState(false); + const [hidden, setHidden] = useState(true); + const [confirmHidden, setConfirmHidden] = useState(true); + const router = useRouter(); + const searchParams = useSearchParams(); + const callback = searchParams.get("callbackUrl"); - const { - register, - handleSubmit, - formState: { errors }, - reset, - } = useForm({ - resolver: zodResolver(isSignup ? signupSchema : loginSchema), - }); + const { + register, + handleSubmit, + formState: {errors}, + reset, + } = useForm({ + resolver: zodResolver(isSignup ? signupSchema : loginSchema), + }); - useEffect(() => { - reset(); - }, [isSignup, reset]); + useEffect(() => { + reset(); + }, [isSignup, reset]); - const onSubmit = async (data: any) => { - if (isSignup) { - try { - setIsLoading(true); + const onSubmit = async (data: any) => { + if (isSignup) { + try { + setIsLoading(true); - const handler = new Promise((resolve, reject) => { - fetch("/api/auth/register", { - method: "POST", - body: JSON.stringify(data), - }) - .then((res) => { - res - .json() - .then((ms) => { - if (res.status !== 200) { - reject(new Error(ms.error)); - } else { - signIn("credentials", { - loginIdentifier: data.email, - password: data.password, - redirect: false, + const handler = new Promise((resolve, reject) => { + fetch("/api/auth/register", { + method: "POST", + body: JSON.stringify(data), }) - .then((m) => { - if (m?.error) throw Error(); - router.push("/auth/verify"); - resolve(""); - }) - .catch(reject); - } - }) - .catch(reject); - }) - .catch(reject); - }); + .then((res) => { + res + .json() + .then((ms) => { + if (res.status !== 200) { + reject(new Error(ms.error)); + } else { + signIn("credentials", { + loginIdentifier: data.email, + password: data.password, + redirect: false, + }) + .then((m) => { + if (m?.error) throw Error(); + router.push("/auth/verify"); + resolve(""); + }) + .catch(reject); + } + }) + .catch(reject); + }) + .catch(reject); + }); - toast.promise(handler, { - loading: "Loading...", - success: () => { - return "User registered, Verify Email."; - }, - error: (err) => `${err}`, - }); - } catch (error: any) { - toast.error(error.message || "Failed to register. Try again"); - } finally { - setIsLoading(false); - } - } else { - try { - setIsLoading(true); - const handler = new Promise((resolve, reject) => { - setIsLoading(true); + toast.promise(handler, { + loading: "Loading...", + success: () => { + return "User registered, Verify Email."; + }, + error: (err) => `${err}`, + }); + } catch (error: any) { + toast.error(error.message || "Failed to register. Try again"); + } finally { + setIsLoading(false); + } + } else { + try { + setIsLoading(true); + const handler = new Promise((resolve, reject) => { + setIsLoading(true); - signIn("credentials", { - ...data, - redirect: false, - }) - .then((res) => { - if (res?.error) { - throw Error("Invalid credentials"); - } else { - if (callback) { - router.push(callback); - resolve(""); - } else { - router.push("/"); - resolve(""); - } - } - }) - .catch(reject); - }); + signIn("credentials", { + ...data, + redirect: false, + }) + .then((res) => { + if (res?.error) { + throw Error("Invalid credentials"); + } else { + if (callback) { + router.push(callback); + resolve(""); + } else { + router.push("/"); + resolve(""); + } + } + }) + .catch(reject); + }); - toast.promise(handler, { - loading: "Loading...", - success: () => { - return "Login success."; - }, - error: (err) => `${err}`, - }); - } catch (error) { - toast.error("Check your credentials and Try again"); - } finally { - setIsLoading(false); - } - } - }; + toast.promise(handler, { + loading: "Loading...", + success: () => { + return "Login success."; + }, + error: (err) => `${err}`, + }); + } catch (error) { + toast.error("Check your credentials and Try again"); + } finally { + setIsLoading(false); + } + } + }; - return ( -
-

{isSignup ? "Sign Up" : "Login"}

-
- {isSignup && ( - <> - {/* Signup fields */} - - {errors.username && ( -

- {errors.username.message?.toString()} -

- )} + return ( +
+

{isSignup ? "Sign Up" : "Login"}

+ + {isSignup && ( + <> + {/* Signup fields */} + + {errors.username && ( +

+ {errors.username.message?.toString()} +

+ )} - - {errors.name && ( -

{errors.name.message?.toString()}

- )} + + {errors.name && ( +

{errors.name.message?.toString()}

+ )} - - {errors.email && ( -

- {errors.email.message?.toString()} -

- )} -
- - -
- {errors.password && ( -

- {errors.password.message?.toString()} -

- )} + + {errors.email && ( +

+ {errors.email.message?.toString()} +

+ )} +
+ + +
+ {errors.password && ( +

+ {errors.password.message?.toString()} +

+ )} -
- - -
- {errors.confirmPassword && ( -

- {errors.confirmPassword.message?.toString()} -

- )} +
+ + +
+ {errors.confirmPassword && ( +

+ {errors.confirmPassword.message?.toString()} +

+ )} -
- - -
- - )} +
+ + +
+ + )} - {/* Login fields */} - {!isSignup && ( - <> - - {errors.loginIdentifier && ( -

- {errors.loginIdentifier.message?.toString()} -

- )} -
- - -
- {errors.password && ( -

- {errors.password.message?.toString()} -

- )} - - )} + {/* Login fields */} + {!isSignup && ( + <> + + {errors.loginIdentifier && ( +

+ {errors.loginIdentifier.message?.toString()} +

+ )} +
+ + +
+ {errors.password && ( +

+ {errors.password.message?.toString()} +

+ )} + + )} - - + + - {/* Google Sign-In */} - + {/* Google Sign-In */} + -

{ - if (!isLoading) { - setIsSignup(!isSignup); - } - setHidden(true); - }} - className={styles.toggle} - > - {isSignup - ? "Already have an account? Login" - : "Don't have an account? Sign Up"} -

-
- ); +

{ + if (!isLoading) { + setIsSignup(!isSignup); + } + setHidden(true); + }} + className={styles.toggle} + > + {isSignup + ? "Already have an account? Login" + : "Don't have an account? Sign Up"} +

+
+ ); } diff --git a/src/app/auth/verify/page.module.css b/src/app/auth/verify/page.module.css index 8accf4b..34638a7 100644 --- a/src/app/auth/verify/page.module.css +++ b/src/app/auth/verify/page.module.css @@ -1,82 +1,82 @@ .container { - max-width: 400px; - margin: 0 auto; - padding: 20px; - border: 1px solid #ccc; - border-radius: 8px; - height: 100%; - width: 100%; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + max-width: 400px; + margin: 0 auto; + padding: 20px; + border: 1px solid #ccc; + border-radius: 8px; + height: 100%; + width: 100%; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); } .title { - text-align: center; - margin-bottom: 20px; - padding: 2px; + text-align: center; + margin-bottom: 20px; + padding: 2px; } .errors { - color: red; - font-weight: 600; - padding: 2px; - margin-bottom: 10px; + color: red; + font-weight: 600; + padding: 2px; + margin-bottom: 10px; } .button { - color: white; - height: 3rem; - font-size: 1rem; - line-height: 1.5rem; - padding: 10px 18px 10px 18px; - border-radius: 5px; - background-color: var(--black); - transition: 0.2s ease-in-out; - width: 100%; + color: white; + height: 3rem; + font-size: 1rem; + line-height: 1.5rem; + padding: 10px 18px 10px 18px; + border-radius: 5px; + background-color: var(--black); + transition: 0.2s ease-in-out; + width: 100%; } .button:hover { - background-color: var(--slate-black); - cursor: pointer; + background-color: var(--slate-black); + cursor: pointer; } .form { - display: flex; - flex-direction: column; - justify-content: center; - width: 100%; - align-items: center; + display: flex; + flex-direction: column; + justify-content: center; + width: 100%; + align-items: center; } .form > div > input { - -moz-appearance: textfield; + -moz-appearance: textfield; } .form > div > input::-webkit-outer-spin-button, .form > div > input::-webkit-inner-spin-button { - -webkit-appearance: none; - margin: 0; + -webkit-appearance: none; + margin: 0; } .errors { - color: red; - font-weight: 600; - padding: 2px; - margin-bottom: 10px; + color: red; + font-weight: 600; + padding: 2px; + margin-bottom: 10px; } .input { - width: 100%; - max-width: 250px; - height: 3rem; - font-size: 1rem; - line-height: 1.5rem; - padding: 10px 18px 10px 18px; - border: 1px solid var(--line-grey); - border-radius: 5px; - outline: none; + width: 100%; + max-width: 250px; + height: 3rem; + font-size: 1rem; + line-height: 1.5rem; + padding: 10px 18px 10px 18px; + border: 1px solid var(--line-grey); + border-radius: 5px; + outline: none; } .label { - margin-top: 10px; - margin-bottom: 10px; + margin-top: 10px; + margin-bottom: 10px; } diff --git a/src/app/auth/verify/page.tsx b/src/app/auth/verify/page.tsx index 594a8fc..7759950 100644 --- a/src/app/auth/verify/page.tsx +++ b/src/app/auth/verify/page.tsx @@ -1,122 +1,123 @@ "use client"; import styles from "./page.module.css"; -import React, { useEffect, useState } from "react"; +import React, {useEffect, useState} from "react"; import OtpInput from "react-otp-input"; -import { toast } from "sonner"; -import { useRouter, useSearchParams } from "next/navigation"; +import {toast} from "sonner"; +import {useRouter, useSearchParams} from "next/navigation"; + const OtpPage: React.FC = () => { - const [otp, setOtp] = useState(""); - const [isResending, setIsResending] = useState(false); - const [countdown, setCountdown] = useState(30); // 30 seconds timer - const [isLoading, setIsLoading] = useState(false); - const router = useRouter(); - const handleChange = (otp: string) => { - setOtp(otp); - }; + const [otp, setOtp] = useState(""); + const [isResending, setIsResending] = useState(false); + const [countdown, setCountdown] = useState(30); // 30 seconds timer + const [isLoading, setIsLoading] = useState(false); + const router = useRouter(); + const handleChange = (otp: string) => { + setOtp(otp); + }; - const searchParams = useSearchParams(); - const callback = searchParams.get("callbackUrl"); + const searchParams = useSearchParams(); + const callback = searchParams.get("callbackUrl"); - const onSubmit = async (e: any) => { - e.preventDefault(); - if (otp.length != 6) { - toast.error("Please fill OTP wisely."); - return; - } - try { - setIsLoading(true); - const response = await fetch("/api/auth/verify-otp", { - method: "POST", - body: JSON.stringify({ otp }), - }); + const onSubmit = async (e: any) => { + e.preventDefault(); + if (otp.length != 6) { + toast.error("Please fill OTP wisely."); + return; + } + try { + setIsLoading(true); + const response = await fetch("/api/auth/verify-otp", { + method: "POST", + body: JSON.stringify({otp}), + }); - const data = await response.json(); + const data = await response.json(); - if (response.status != 200) throw new Error(data.error); + if (response.status != 200) throw new Error(data.error); - toast.success("Email Verified!"); + toast.success("Email Verified!"); - if (callback) { - router.push(`${callback}`); - } else { - router.push("/"); - } - } catch (error: any) { - console.log(error); - toast.error(error.message); - } finally { - setIsLoading(false); - } - }; + if (callback) { + router.push(`${callback}`); + } else { + router.push("/"); + } + } catch (error: any) { + console.log(error); + toast.error(error.message); + } finally { + setIsLoading(false); + } + }; - const handleResendOtp = async () => { - if (isResending) return; + const handleResendOtp = async () => { + if (isResending) return; - setIsResending(true); - setCountdown(30); - try { - setIsLoading(true); - const response = await fetch("/api/auth/resend-otp", { - method: "POST", - }); + setIsResending(true); + setCountdown(30); + try { + setIsLoading(true); + const response = await fetch("/api/auth/resend-otp", { + method: "POST", + }); - const data = await response.json(); + const data = await response.json(); - if (response.status != 200) throw new Error(data.message); - setOtp(""); - toast.success("OTP has been resent to your email."); - } catch (error: any) { - toast.error(error.message); - } finally { - setIsLoading(false); - } - }; + if (response.status != 200) throw new Error(data.message); + setOtp(""); + toast.success("OTP has been resent to your email."); + } catch (error: any) { + toast.error(error.message); + } finally { + setIsLoading(false); + } + }; - useEffect(() => { - if (isResending && countdown > 0) { - const timer = setInterval(() => { - setCountdown((prev) => prev - 1); - }, 1000); - return () => clearInterval(timer); - } else if (countdown === 0) { - setIsResending(false); // Allow resend after countdown - } - }, [isResending, countdown]); - return ( -
-

Enter OTP

-
- } - shouldAutoFocus - inputType="number" - /> + useEffect(() => { + if (isResending && countdown > 0) { + const timer = setInterval(() => { + setCountdown((prev) => prev - 1); + }, 1000); + return () => clearInterval(timer); + } else if (countdown === 0) { + setIsResending(false); // Allow resend after countdown + } + }, [isResending, countdown]); + return ( +
+

Enter OTP

+ + } + shouldAutoFocus + inputType="number" + /> - - - -
- ); + + + +
+ ); }; export default OtpPage; diff --git a/src/app/explore/page.module.css b/src/app/explore/page.module.css index 7165e34..62851c2 100644 --- a/src/app/explore/page.module.css +++ b/src/app/explore/page.module.css @@ -1,4 +1,4 @@ -.pageHeader{ +.pageHeader { display: flex; flex-direction: column-reverse; justify-content: center; @@ -11,6 +11,7 @@ font-weight: bold; color: var(--green); } + .pageHeader > img { position: relative; filter: drop-shadow(0 0 0.40rem #A0A5AC); @@ -30,13 +31,14 @@ .pageHeader > h1 { font-size: 1.9rem; } + /*.pageHeader > img {*/ /* margin-top: -15vh;*/ /*}*/ } -.text-container{ +.text-container { display: flex; flex-direction: column; align-items: center; @@ -47,13 +49,13 @@ } -.text-container > p{ +.text-container > p { color: var(--black); text-align: center; margin: 5px; } -.links-container{ +.links-container { display: flex; flex-direction: column; align-items: center; @@ -62,15 +64,16 @@ } -.div{ +.div { width: max-content; border: 1px solid red; - padding: 0.8rem 1rem; + padding: 0.8rem 1rem; border-radius: 5px; float: right; transition-duration: 1s; } -.div:hover{ + +.div:hover { background-color: dodgerblue; text-decoration-line: underline; cursor: pointer; diff --git a/src/app/globals.css b/src/app/globals.css index ab2a6da..1d31878 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1,120 +1,122 @@ :root { - /*--max-width: 110px;*/ - /*--border-radius: 12px;*/ - /*--font-mono: ui-monospace, Menlo, Monaco, "Cascadia Mono", "Segoe UI Mono",*/ - /*"Roboto Mono", "Oxygen Mono", "Ubuntu Monospace", "Source Code Pro",*/ - /*"Fira Mono", "Droid Sans Mono", "Courier New", monospace;*/ - - --black: #3b3d41; - --grey: #a0a5ac; - --line-grey: #e1e4e8; - --slate-black: #667085; - --mist-grey: #f2f2f2; - - --light-green: #22c55e; - --light-yellow: #ffc107; - --light-blue: #3b82f6; - --light-red: #ff3737; - --light-red2: #ff69b4; - - --green: #2e865f; - --soil: #eeb27b; + /*--max-width: 110px;*/ + /*--border-radius: 12px;*/ + /*--font-mono: ui-monospace, Menlo, Monaco, "Cascadia Mono", "Segoe UI Mono",*/ + /*"Roboto Mono", "Oxygen Mono", "Ubuntu Monospace", "Source Code Pro",*/ + /*"Fira Mono", "Droid Sans Mono", "Courier New", monospace;*/ + + --black: #3b3d41; + --grey: #a0a5ac; + --line-grey: #e1e4e8; + --slate-black: #667085; + --mist-grey: #f2f2f2; + + --light-green: #22c55e; + --light-yellow: #ffc107; + --light-blue: #3b82f6; + --light-red: #ff3737; + --light-red2: #ff69b4; + + --green: #2e865f; + --soil: #eeb27b; } /* reset everything*/ *, *::before, *::after { - box-sizing: border-box; + box-sizing: border-box; } + * { - margin: 0; - padding: 0; - border: 0 solid transparent; + margin: 0; + padding: 0; + border: 0 solid transparent; } /* prevent iOS font size change*/ html { - -webkit-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; } /* reset body line-height*/ body { - background-color: rgb(255, 255, 255); - /*font-family: "SF Pro Display", system-ui, -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Helvetica", "Arial",sans-serif;*/ - line-height: 1; - /*text-rendering: optimizeSpeed;*/ - text-rendering: optimizeLegibility; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - /*max-width: 1440px;*/ + background-color: rgb(255, 255, 255); + /*font-family: "SF Pro Display", system-ui, -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Helvetica", "Arial",sans-serif;*/ + line-height: 1; + /*text-rendering: optimizeSpeed;*/ + text-rendering: optimizeLegibility; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + /*max-width: 1440px;*/ } /* assign button hover state*/ button, [role="button"] { - cursor: pointer; - background-color: transparent; - -webkit-tap-highlight-color: transparent; - &:focus { - outline: 0; - } + cursor: pointer; + background-color: transparent; + -webkit-tap-highlight-color: transparent; + + &:focus { + outline: 0; + } } /* reset anchor style*/ p { - font-family: --myCustomFont, "system-ui", "-apple-system", + font-family: --myCustomFont, "system-ui", "-apple-system", "BlinkMacSystemFont", sans-serif; - font-size: 14px; - font-style: normal; - font-weight: 300; - letter-spacing: 1px; - color: var(--grey); - text-decoration: none; - text-transform: none; - line-height: 20px; + font-size: 14px; + font-style: normal; + font-weight: 300; + letter-spacing: 1px; + color: var(--grey); + text-decoration: none; + text-transform: none; + line-height: 20px; } main { - width: 95%; - max-width: 1440px; /* Fixed maximum width */ - height: 100%; - display: flex; - flex-direction: column; - align-items: center; - margin: 0 auto; /* Centering main element */ - overflow: hidden; + width: 95%; + max-width: 1440px; /* Fixed maximum width */ + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + margin: 0 auto; /* Centering main element */ + overflow: hidden; } h1 { - font-size: 60px; - font-style: normal; - font-weight: 350; - letter-spacing: 2px; - color: var(--black); - text-decoration: none; - text-transform: none; + font-size: 60px; + font-style: normal; + font-weight: 350; + letter-spacing: 2px; + color: var(--black); + text-decoration: none; + text-transform: none; } a { - cursor: pointer; - color: inherit; - text-decoration: none; - -webkit-tap-highlight-color: transparent; + cursor: pointer; + color: inherit; + text-decoration: none; + -webkit-tap-highlight-color: transparent; } /* globals.css */ html, body { - overflow: hidden; /* Hide overflow initially */ - overflow-y: scroll; /* Enable vertical scrolling */ - scrollbar-width: none; /* Firefox */ - -ms-overflow-style: none; /* IE 10+ */ + overflow: hidden; /* Hide overflow initially */ + overflow-y: scroll; /* Enable vertical scrolling */ + scrollbar-width: none; /* Firefox */ + -ms-overflow-style: none; /* IE 10+ */ } /* Hide scrollbar for Chrome, Safari, and Edge */ html::-webkit-scrollbar, body::-webkit-scrollbar { - display: none; + display: none; } diff --git a/src/app/language/page.module.css b/src/app/language/page.module.css index 574d0ad..bb8e1cb 100644 --- a/src/app/language/page.module.css +++ b/src/app/language/page.module.css @@ -1,4 +1,4 @@ -.language-hero-container{ +.language-hero-container { margin-top: 5rem; display: flex; flex-direction: row; @@ -9,7 +9,7 @@ } -.language-text-container{ +.language-text-container { display: flex; flex-direction: column; justify-content: center; @@ -19,28 +19,31 @@ width: 100%; } + .language-text-container > p { letter-spacing: 1px; text-transform: uppercase; margin-top: 1rem; } -.language-img-container{ + +.language-img-container { overflow: hidden; max-width: 600px; width: 100%; } -.language-img-container > img{ +.language-img-container > img { filter: drop-shadow(0 0 0.40rem #A0A5AC); } -.language-importance-container{ +.language-importance-container { margin-top: 10rem; border-top: 1px solid var(--line-grey); width: 100%; } -.language-importance-title-container > p{ + +.language-importance-title-container > p { text-transform: uppercase; margin-top: 0.3rem; margin-left: 2px; @@ -48,7 +51,8 @@ font-size: 12px; } -.language-importance-item-container{ + +.language-importance-item-container { display: flex; flex-direction: row; /*align-items: center;*/ @@ -58,21 +62,21 @@ margin-top: 1.5rem; } -.uttarakhand-language-title-container{ +.uttarakhand-language-title-container { width: 100%; border-top: 1px solid var(--line-grey); margin-top: 5rem; margin-bottom: -6rem; } -.uttarakhand-language-title-container > p{ +.uttarakhand-language-title-container > p { text-transform: uppercase; font-size: 12px; letter-spacing: 1px; } -.uttarakhand-language-container{ +.uttarakhand-language-container { width: 95%; } @@ -86,47 +90,53 @@ font-size: 45px; letter-spacing: 2px; } - .language-img-container > img{ + + .language-img-container > img { width: 430px; height: 400px; } - .language-hero-container{ + + .language-hero-container { padding: 0 2rem 0 2rem; } } @media (max-width: 1000px) { - .language-hero-container{ + .language-hero-container { padding: 0 1.5rem 0 1.5rem; } + .language-text-container > p { font-size: 12px; letter-spacing: 1px; text-align: center; } + .language-text-container > h1 { font-size: 30px; letter-spacing: 1px; } - .language-img-container > img{ + + .language-img-container > img { width: 323px; height: 300px; } } @media (max-width: 700px) { - .language-hero-container{ + .language-hero-container { flex-direction: column-reverse; padding: 0 0 0 0; margin-top: 2.5rem; } - .language-img-container{ + + .language-img-container { width: 100%; text-align: center; } - .language-img-container > img{ + .language-img-container > img { rotate: -30deg; width: 300px; height: 278px; @@ -134,14 +144,15 @@ /*padding-left: 15px;*/ } - .uttarakhand-language-container{ + .uttarakhand-language-container { margin-top: 3rem; position: relative; width: 100%; } } + @media (max-width: 500px) { - .language-importance-title-container > p{ + .language-importance-title-container > p { text-align: center; } } \ No newline at end of file diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 3e2b5f9..0762565 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,93 +1,93 @@ -import type { Metadata } from "next"; +import type {Metadata} from "next"; import "./globals.css"; import React from "react"; import localFont from "next/font/local"; import Navbar from "@/components/ui/Navbar"; import Footer from "@/components/ui/Footer"; -import { Toaster } from "sonner"; -import { auth } from "@/auth"; -import { redirect } from "next/navigation"; -import { headers } from "next/headers"; -import { SessionProvider } from "next-auth/react"; -import { SpeedInsights } from '@vercel/speed-insights/next'; +import {Toaster} from "sonner"; +import {auth} from "@/auth"; +import {redirect} from "next/navigation"; +import {headers} from "next/headers"; +import {SessionProvider} from "next-auth/react"; +import {SpeedInsights} from '@vercel/speed-insights/next'; const customFont = localFont({ - src: "../font/customFont.otf", - variable: "--myCustomFont", + src: "../font/customFont.otf", + variable: "--myCustomFont", }); export const metadata: Metadata = { - title: - "Uttarakhand Culture - Explore Devbhoomi's Heritage, Traditions, and Natural Beauty", - description: - "Explore the rich cultural heritage of Uttarakhand, Devbhoomi's vibrant festivals, traditions, folklore, and breathtaking landscapes. Join our mission to preserve and celebrate the heritage of Manaskhand and Kedarkhand for future generations.", - keywords: - "Uttarakhand, culture, Devbhoomi, Uttarakhand culture, Pahadi culture, Uttarakhand heritage, Manaskhand, Kedarkhand, traditions, festivals, folk music, folk dances, digital preservation, Pahad, Pahadi, Pahadi traditions, Garhwali, Kumaoni, Himalayan culture, Uttarakhand tourism, cultural preservation, spiritual Uttarakhand, pilgrimage, Uttarakhand cuisine, Uttarakhand art, Uttarakhand history, Nanda Devi, Chhota Kailash, Ganga, Yamuna, Himalayan rivers, Uttarakhand flora fauna, mountain culture", - openGraph: { title: - "Uttarakhand Culture - Explore Devbhoomi's Heritage, Traditions, and Natural Beauty", + "Uttarakhand Culture - Explore Devbhoomi's Heritage, Traditions, and Natural Beauty", description: - "Discover Uttarakhand's cultural heritage, festivals, traditions, folklore, and stunning natural beauty. Join our mission to digitally preserve and celebrate the vibrant legacy of Devbhoomi for future generations.", - url: "https://uttarakhand-culture.vercel.app", - siteName: "Uttarakhand Culture", - images: [ - { - url: "/SEOIMAGE.webp", - alt: "Cultural Heritage of Uttarakhand - Traditions, Festivals, and Natural Beauty", - }, - ], - locale: "en_US", - type: "website", - }, - twitter: { - card: "summary_large_image", - site: "https://uttarakhand-culture.vercel.app", - creator: "@UttarakhandCulture", - title: - "Uttarakhand Culture - Explore Devbhoomi's Heritage, Traditions, and Natural Beauty", - description: - "Discover Uttarakhand's cultural legacy, rich history, festivals, and natural beauty. Help us preserve the traditions of Devbhoomi for future generations.", - images: "/SEOIMAGE.webp", - }, - robots: { - index: true, - follow: true, - }, + "Explore the rich cultural heritage of Uttarakhand, Devbhoomi's vibrant festivals, traditions, folklore, and breathtaking landscapes. Join our mission to preserve and celebrate the heritage of Manaskhand and Kedarkhand for future generations.", + keywords: + "Uttarakhand, culture, Devbhoomi, Uttarakhand culture, Pahadi culture, Uttarakhand heritage, Manaskhand, Kedarkhand, traditions, festivals, folk music, folk dances, digital preservation, Pahad, Pahadi, Pahadi traditions, Garhwali, Kumaoni, Himalayan culture, Uttarakhand tourism, cultural preservation, spiritual Uttarakhand, pilgrimage, Uttarakhand cuisine, Uttarakhand art, Uttarakhand history, Nanda Devi, Chhota Kailash, Ganga, Yamuna, Himalayan rivers, Uttarakhand flora fauna, mountain culture", + openGraph: { + title: + "Uttarakhand Culture - Explore Devbhoomi's Heritage, Traditions, and Natural Beauty", + description: + "Discover Uttarakhand's cultural heritage, festivals, traditions, folklore, and stunning natural beauty. Join our mission to digitally preserve and celebrate the vibrant legacy of Devbhoomi for future generations.", + url: "https://uttarakhand-culture.vercel.app", + siteName: "Uttarakhand Culture", + images: [ + { + url: "/SEOIMAGE.webp", + alt: "Cultural Heritage of Uttarakhand - Traditions, Festivals, and Natural Beauty", + }, + ], + locale: "en_US", + type: "website", + }, + twitter: { + card: "summary_large_image", + site: "https://uttarakhand-culture.vercel.app", + creator: "@UttarakhandCulture", + title: + "Uttarakhand Culture - Explore Devbhoomi's Heritage, Traditions, and Natural Beauty", + description: + "Discover Uttarakhand's cultural legacy, rich history, festivals, and natural beauty. Help us preserve the traditions of Devbhoomi for future generations.", + images: "/SEOIMAGE.webp", + }, + robots: { + index: true, + follow: true, + }, }; export default async function RootLayout({ - children, -}: Readonly<{ - children: React.ReactNode; + children, + }: Readonly<{ + children: React.ReactNode; }>) { - const session = await auth(); - const h = headers(); - const pathname = h.get("x-current-path"); + const session = await auth(); + const h = headers(); + const pathname = h.get("x-current-path"); - if (session) { - if (!session.user?.emailVerified) { - if (!pathname!.includes("/auth")) { - redirect("/auth/verify"); - } + if (session) { + if (!session.user?.emailVerified) { + if (!pathname!.includes("/auth")) { + redirect("/auth/verify"); + } + } } - } - return ( - - - - - - -
- - {children} - - -
-
- -
- - ); + return ( + + + + + + +
+ + {children} + + +
+
+ +
+ + ); } diff --git a/src/app/map/page.module.css b/src/app/map/page.module.css index 15f2c97..b7fb146 100644 --- a/src/app/map/page.module.css +++ b/src/app/map/page.module.css @@ -1,10 +1,12 @@ -.uttarakhand-map{ - margin: 8em 0; +.uttarakhand-map { + margin: 8em 0; } -.uttarakhand-map-heading{ + +.uttarakhand-map-heading { text-align: center; color: #FF9800; } + .uttarakhand-map-container { background: white; padding: 0; @@ -20,9 +22,10 @@ -ms-transform: translateZ(0); -o-transform: translateZ(0); transform: translateZ(0); - transform: transale3d(0,0,0); + transform: transale3d(0, 0, 0); /* will-change: transform; */ } + .uttarakhand-map-container > img { width: 100%; height: auto; @@ -39,46 +42,51 @@ -ms-transform: translateZ(0); -o-transform: translateZ(0); transform: translateZ(0); - transform: transale3d(0,0,0); + transform: transale3d(0, 0, 0); /* will-change: transform; */ } @keyframes fade-in { - from{ + from { scale: 0; } - to{ + to { scale: 1; } } -.zoom-button-container{ + +.zoom-button-container { display: flex; justify-content: center; gap: 2em; margin: 1em 0 1em 0; } + .zoom-level-button { color: var(--black); padding: 5px 10px; border-radius: 3px; border: 2px solid var(--green); } -.zoom-level-button:hover{ + +.zoom-level-button:hover { background-color: var(--green); color: var(--light-yellow); cursor: pointer; } -.uttarakhand-map > p{ + +.uttarakhand-map > p { font-weight: bold; text-align: center; color: grey; } @media only screen and (max-width: 500px) { - .uttarakhand-map-container{ + .uttarakhand-map-container { margin: 0.1em; } - .uttarakhand-map > p{ + + .uttarakhand-map > p { margin-top: 0.5em; font-size: 0.8em; font-weight: bold; @@ -88,14 +96,6 @@ } - - - - - - - - .uttarakhand-map-container { width: 100%; overflow-x: scroll; @@ -116,58 +116,6 @@ } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /*** New Code ***/ diff --git a/src/app/map/page.tsx b/src/app/map/page.tsx index 9c1c6ea..692e5da 100644 --- a/src/app/map/page.tsx +++ b/src/app/map/page.tsx @@ -60,7 +60,7 @@ const Map = () => { {/*
*/} {/* {""}*/} {/*
*/} - +

Map of Uttarakhand

diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx index 8db5808..2efa7ec 100644 --- a/src/app/not-found.tsx +++ b/src/app/not-found.tsx @@ -8,17 +8,17 @@ const Custom404 = () => { alignItems: 'center', justifyContent: 'center', height: '70vh', - backgroundColor: 'rgba(255, 255, 255, 0.8)', + backgroundColor: 'rgba(255, 255, 255, 0.8)', color: '#000000', fontFamily: 'Arial, sans-serif', textAlign: 'center', padding: '40px', boxSizing: 'border-box', - borderRadius: '10px', - backdropFilter: 'blur(10px)', + borderRadius: '10px', + backdropFilter: 'blur(10px)', width: '90%', maxWidth: '900px', - margin: '0 auto', + margin: '0 auto', }}>

img{ +.headerLeftImageContainer > img { width: auto; transform: rotateY(180deg); filter: drop-shadow(0 0 0.40rem #A0A5AC); } -.headerCenterImageContainer > img{ + +.headerCenterImageContainer > img { width: auto; filter: drop-shadow(0 0 0.40rem #A0A5AC); } -.headerRightImageContainer > img{ + +.headerRightImageContainer > img { width: auto; filter: drop-shadow(0 0 0.40rem #A0A5AC); } -.headerTextContainer{ +.headerTextContainer { margin-top: 1rem; width: 100%; display: flex; @@ -36,8 +39,9 @@ justify-content: center; text-align: center; } + .headerTextContainer > h1 { - font-family: "-apple-system","system-ui"; + font-family: "-apple-system", "system-ui"; font-size: 5vw; font-weight: bolder; } @@ -55,7 +59,7 @@ background-color: var(--black); padding: 12px 20px; border-radius: 5px; - box-shadow: 0 .7065919983928324px .7065919983928324px -.625px #00000026,0 1.8065619053231785px 1.8065619053231785px -1.25px #00000025,0 3.6217592146567767px 3.6217592146567767px -1.875px #00000023,0 6.8655999097303715px 6.8655999097303715px -2.5px #00000020,0 13.646761411524492px 13.646761411524492px -3.125px #0000001b,0 30px 30px -3.75px #0000000d; + box-shadow: 0 .7065919983928324px .7065919983928324px -.625px #00000026, 0 1.8065619053231785px 1.8065619053231785px -1.25px #00000025, 0 3.6217592146567767px 3.6217592146567767px -1.875px #00000023, 0 6.8655999097303715px 6.8655999097303715px -2.5px #00000020, 0 13.646761411524492px 13.646761411524492px -3.125px #0000001b, 0 30px 30px -3.75px #0000000d; } .headerTextContainer > .headerbuttonLink:hover { @@ -69,78 +73,97 @@ font-size: 60px; } } + @media (max-width: 950px) { - .headerLeftImageContainer > img{ + .headerLeftImageContainer > img { height: 400px; } - .headerCenterImageContainer > img{ + + .headerCenterImageContainer > img { height: 250px; } - .headerRightImageContainer > img{ + + .headerRightImageContainer > img { height: 400px; } } @media (max-width: 700px) { - .headerLeftImageContainer > img{ + .headerLeftImageContainer > img { height: 300px; } - .headerCenterImageContainer > img{ + + .headerCenterImageContainer > img { height: 150px; } - .headerRightImageContainer > img{ + + .headerRightImageContainer > img { height: 300px; } + .headerTextContainer > h1 { font-size: 4.8vw; } + .headerTextContainer > p { font-size: 14px; } + .headerTextContainer > .headerbuttonLink { font-size: 14px; padding: 12px 20px; } } + @media (max-width: 500px) { - .headerLeftImageContainer > img{ + .headerLeftImageContainer > img { height: 210px; } - .headerCenterImageContainer > img{ + + .headerCenterImageContainer > img { height: 135px; } - .headerRightImageContainer > img{ + + .headerRightImageContainer > img { height: 210px; } + .headerTextContainer > h1 { font-size: 4.47vw; } + .headerTextContainer > p { font-size: 12px; margin-top: 1rem; } + .headerTextContainer > .headerbuttonLink { margin-top: 2rem; } } @media (max-width: 374px) { - .headerLeftImageContainer > img{ + .headerLeftImageContainer > img { height: 170px; } - .headerCenterImageContainer > img{ + + .headerCenterImageContainer > img { height: 120px; } - .headerRightImageContainer > img{ + + .headerRightImageContainer > img { height: 170px; } + .headerTextContainer > h1 { font-size: 4vw; } + .headerTextContainer > p { font-size: 10px; margin-top: 1rem; } + .headerTextContainer > .headerbuttonLink { font-size: 11px; margin-top: 2rem; @@ -149,25 +172,22 @@ } - - - - /* Why we Build it */ -.home-story-container{ +.home-story-container { width: 95%; margin-top: 2rem; /*border-top: 1px solid var(--cloud-grey)*/ } -.why-built-it-title{ +.why-built-it-title { font-size: 12px; margin-bottom: 2.2rem; } -.built-image-container{ + +.built-image-container { width: 100%; max-width: 40vw; margin-top: 8rem; @@ -177,47 +197,50 @@ justify-content: center; align-items: center; } + .built-image-container > img { filter: drop-shadow(0 0 0.40rem #A0A5AC); } -.built-image-container > p{ + +.built-image-container > p { margin-top: 5px; width: 300px; } -.built-text-container{ +.built-text-container { width: 100%; max-width: 60vw; } -.why-built-it-container{ +.why-built-it-container { display: flex; flex-direction: row; align-items: center; gap: 1rem; } -.built-description-container{ +.built-description-container { color: var(--black); } - /* Explore Uttarakhand */ -.journey-container{ +.journey-container { border-top: 1px solid var(--line-grey); padding-top: 1rem; margin-top: 3rem; } -.journey-container > p{ + +.journey-container > p { text-transform: uppercase; font-size: 12px; margin-top: -0.8rem; margin-bottom: 1rem; width: 100vw; } -.journey-container > div{ + +.journey-container > div { display: flex; flex-direction: row; gap: 1rem; @@ -225,7 +248,7 @@ } -.journey-left-container{ +.journey-left-container { display: flex; flex-direction: column; gap: 2rem; @@ -235,10 +258,11 @@ max-width: 70vw; } -.journey-right-container{ +.journey-right-container { width: 100%; max-width: 30vw; } + .journey-left-container > div > h3 { font-size: 1.5rem; width: max-content; @@ -297,55 +321,60 @@ } -@media (max-width: 1350px) { +@media (max-width: 1350px) { .text-container > h1 { font-size: 45px; letter-spacing: 2px; } - .img-container > img{ + + .img-container > img { width: 430px; height: 400px; } - .hero-container{ + + .hero-container { padding: 0 2rem 0 2rem; } } @media (max-width: 1000px) { - .hero-container{ + .hero-container { padding: 0 1.5rem 0 1.5rem; } + .text-container > p { font-size: 12px; letter-spacing: 1px; text-align: center; } + .text-container > h1 { font-size: 30px; letter-spacing: 1px; } - .img-container > img{ + + .img-container > img { width: 323px; height: 300px; } } @media (max-width: 800px) { - .why-built-it-container{ + .why-built-it-container { flex-direction: column; gap: 4rem; } - .built-image-container{ + .built-image-container { width: 100%; margin-top: 3.5rem; } - .home-story-container{ + .home-story-container { margin-top: 5rem; } - .built-text-container{ + .built-text-container { width: 100%; max-width: 100%; } @@ -355,22 +384,22 @@ margin-top: 1.5rem; } - .why-built-it-title{ + .why-built-it-title { margin-bottom: 1rem; } - .journey-left-container{ + .journey-left-container { max-width: 100vw; } - .journey-container > div{ + .journey-container > div { flex-direction: column-reverse; gap: 2rem; margin-top: 2rem; } - .journey-right-container{ + .journey-right-container { max-width: 100vw; } @@ -383,12 +412,13 @@ padding: 0 0 0 0; margin-top: 2.5rem; } - .img-container{ + + .img-container { width: 100%; text-align: center; } - .img-container > img{ + .img-container > img { rotate: -30deg; width: 300px; height: 278px; @@ -400,8 +430,6 @@ /* flex-direction: column-reverse;*/ /* gap: 2rem;*/ /*}*/ - - .journey-right-container > img { width: 100%; height: auto; @@ -409,21 +437,22 @@ } - } - @media (max-width: 500px) { - .journey-container > p{ + .journey-container > p { font-size: 10px; } - .built-image-container{ + + .built-image-container { max-width: 100%; } - .built-image-container > p{ + + .built-image-container > p { width: 100%; } + .built-image-container > img { width: 100%; height: auto; @@ -431,7 +460,7 @@ .journey-left-container > div > h3 { width: 100%; - text-align: center; + text-align: center; } .journey-left-container > a { @@ -444,8 +473,6 @@ } - - /* Notify Banner */ .notifyBannerContainer { @@ -458,7 +485,8 @@ min-width: 100%; height: auto; } -.colorBlend{ + +.colorBlend { position: absolute; background: linear-gradient(to bottom, #ffffff, #E9F4F6); background-size: cover; @@ -523,41 +551,34 @@ font-weight: normal; - box-shadow: 0 .7065919983928324px .7065919983928324px -.625px #00000026,0 1.8065619053231785px 1.8065619053231785px -1.25px #00000025,0 3.6217592146567767px 3.6217592146567767px -1.875px #00000023,0 6.8655999097303715px 6.8655999097303715px -2.5px #00000020,0 13.646761411524492px 13.646761411524492px -3.125px #0000001b,0 30px 30px -3.75px #0000000d; + box-shadow: 0 .7065919983928324px .7065919983928324px -.625px #00000026, 0 1.8065619053231785px 1.8065619053231785px -1.25px #00000025, 0 3.6217592146567767px 3.6217592146567767px -1.875px #00000023, 0 6.8655999097303715px 6.8655999097303715px -2.5px #00000020, 0 13.646761411524492px 13.646761411524492px -3.125px #0000001b, 0 30px 30px -3.75px #0000000d; } - .notifyBannerButtonText:hover { background-color: var(--green); box-shadow: none; } -.greenText{ +.greenText { color: var(--green); } -.soilText{ +.soilText { color: var(--soil); } - - - - - - @media (max-width: 1300px) { .notifyBannerTextContainer { gap: 0; - top: 40% ; + top: 40%; } - .colorBlend{ + .colorBlend { height: 60px; top: -10px; } @@ -582,7 +603,7 @@ margin-bottom: 0; } - .colorBlend{ + .colorBlend { height: 50px; top: -30px; } @@ -623,12 +644,13 @@ .notifyBannerMessage { font-size: 13.5px; } + .notifyBannerImageContainer img { scale: 1.5; height: 160px; } - .colorBlend{ + .colorBlend { height: 50px; top: -50px; } @@ -648,42 +670,21 @@ .notifyBannerMessage { font-size: 13px; } + .notifyBannerImageContainer img { scale: 1.5; height: 160px; } - .colorBlend{ + .colorBlend { height: 50px; top: -50px; } - } - - - - - - - - - - - - - - - - - - - - - /*!* Enable hover only on non-touch devices *!*/ /*@media (hover: hover) and (pointer: fine) {*/ /*}*/ diff --git a/src/app/page.tsx b/src/app/page.tsx index f6d6306..15adca7 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -7,14 +7,12 @@ import Srinagar from "/public/Srinagar.webp" import GoriGanga from "/public/goriGanga.webp" import SectionCard from "@/components/ui/SectionCard"; import GheeSankranti from "/public/Ghee_Sankranti.jpeg"; -import Bagwal from "/public/bagwal.jpg"; import Nanda_Sunanda from "/public/Nanda-Sunanda.webp"; import Notify_Banner from "/public/notify-early-banner.jpg" import PahadiWomen from "/public/bhotiaWoman.webp" -import Screen from "@/components/Screen"; -import Festivals from "@/components/Festivals"; import Faq from "@/components/Faq"; import Proverbs from "@/components/ui/Proverbs"; + export default function Home() { return ( <> @@ -24,15 +22,15 @@ export default function Home() {
{"Image + priority={true} placeholder={"blur"}/>
{"Image + priority={true} placeholder={"blur"}/>
{"Image + priority={true} placeholder={"blur"}/>
@@ -47,7 +45,7 @@ export default function Home() { {/**/} - +
@@ -55,7 +53,7 @@ export default function Home() {
TREKKING + priority={true} placeholder={"blur"}/>

A Painting of a Rope bridge across Alaknanda River, Srinagar, in the times of Garhwal Kingdom, 1784-94. Photo Src: British Library

@@ -94,7 +92,7 @@ export default function Home() {
TREKKING + priority={true} placeholder={"blur"}/>

Water-colour painting of the River Gori in Uttar Pradesh by James Manson (1791-1862), c.1826.

@@ -132,7 +130,7 @@ export default function Home() {
{"notify-early-banner-image"} + placeholder={"blur"}/>
diff --git a/src/app/profile/page.tsx b/src/app/profile/page.tsx index 217667c..76bea80 100644 --- a/src/app/profile/page.tsx +++ b/src/app/profile/page.tsx @@ -1,46 +1,46 @@ "use client"; -import { useSession, signOut } from "next-auth/react"; -import { useRouter } from "next/navigation"; +import {signOut, useSession} from "next-auth/react"; +import {useRouter} from "next/navigation"; import styles from "./profile.module.css"; import Image from "next/image"; export default function Profile() { - const { data: session, status } = useSession(); - const router = useRouter(); + const {data: session, status} = useSession(); + const router = useRouter(); - if (status === "loading") { - return

Loading...

; - } + if (status === "loading") { + return

Loading...

; + } - if (status === "unauthenticated") { - router.push("/"); // Redirect to login if unauthenticated - return null; - } + if (status === "unauthenticated") { + router.push("/"); // Redirect to login if unauthenticated + return null; + } - return ( -
-

User Profile

-
- User Avatar -

- Name: {session?.user?.name || "N/A"} -

-

- Email: {session?.user?.email || "N/A"} -

-
- -
- ); + return ( +
+

User Profile

+
+ User Avatar +

+ Name: {session?.user?.name || "N/A"} +

+

+ Email: {session?.user?.email || "N/A"} +

+
+ +
+ ); } diff --git a/src/app/profile/profile.module.css b/src/app/profile/profile.module.css index 4462a4e..2491e43 100644 --- a/src/app/profile/profile.module.css +++ b/src/app/profile/profile.module.css @@ -1,37 +1,37 @@ .profile-container { - max-width: 600px; - margin: 0 auto; - padding: 20px; - text-align: center; + max-width: 600px; + margin: 0 auto; + padding: 20px; + text-align: center; } .profile-heading { - font-size: 2rem; - margin-bottom: 20px; + font-size: 2rem; + margin-bottom: 20px; } .profile-details { - margin-bottom: 20px; + margin-bottom: 20px; } .profile-avatar { - width: 100px; - height: 100px; - border-radius: 50%; - object-fit: cover; - margin-bottom: 10px; + width: 100px; + height: 100px; + border-radius: 50%; + object-fit: cover; + margin-bottom: 10px; } .logout-button { - background-color: #ff5a5a; - color: white; - border: none; - padding: 10px 20px; - border-radius: 5px; - cursor: pointer; - font-size: 1rem; + background-color: #ff5a5a; + color: white; + border: none; + padding: 10px 20px; + border-radius: 5px; + cursor: pointer; + font-size: 1rem; } .logout-button:hover { - background-color: #ff2a2a; + background-color: #ff2a2a; } diff --git a/src/app/trekking/location-detail.js b/src/app/trekking/location-detail.js index b8b026d..e2ab358 100644 --- a/src/app/trekking/location-detail.js +++ b/src/app/trekking/location-detail.js @@ -1,677 +1,677 @@ export const trekDetails = [ - { - title: "ROOPKUND TREK", - difficultyLevel: "DIFFICULT", - altitude: 4536, - district: "CHAMOLI", - address: "Roopkund Lake, Chamoli, Uttarakhand, India", - coordinates: [30.3440, 80.0940], - introduction: - "The Roopkund Trek is a mesmerizing journey through the pristine wilderness of the Himalayas, famously known as the 'Skeleton Lake.' This trek is shrouded in mystery and folklore, as the lake is home to human skeletal remains that date back centuries. Surrounded by majestic mountains and verdant meadows, the trek offers not just adventure but also a unique glimpse into the region's rich history and culture. As you traverse the rugged terrain, you'll encounter breathtaking landscapes that change with every turn, making this an unforgettable experience for every nature enthusiast.", - overview: - "Covering approximately 53 kilometers, the Roopkund Trek leads you to an altitude of 16,470 feet. This trek takes you through dense forests of oak and rhododendron, high-altitude meadows, and rugged mountain trails. The journey begins at Lohajung, where trekkers are greeted by the serene beauty of the Himalayas. As you ascend, witness the stunning views of snow-capped peaks like Trishul and Nanda Ghunti. The final destination, Roopkund Lake, is an enchanting glacial lake that lies at the heart of this trek, offering stunning reflections of the surrounding mountains. The area is rich in biodiversity, making it a perfect location for wildlife enthusiasts. This trek not only tests your physical limits but also fills your spirit with the tranquility of the Himalayas.", - route: [ - "Day 1: Drive to Lohajung (7,700 feet), where the journey begins, and enjoy the breathtaking views during the drive.", - "Day 2: Trek to Bekhal Tal (9,800 feet), where you can enjoy the serene surroundings and observe local flora and fauna.", - "Day 3: Ascend to Roopkund (16,470 feet), visit the lake, and explore the nearby ancient ruins while immersing yourself in local legends.", - "Day 4: Trek to Patar Nachauni (12,500 feet), where you can enjoy panoramic views and the stunning beauty of alpine meadows, taking in the essence of the Himalayas.", - "Day 5: Return trek to Lohajung, reflecting on the experiences and memories made along the way, with plenty of opportunities for photography.", - ], - attractions: [ - "The mysterious Roopkund Lake, often shrouded in mist and mystery, presenting an eerie yet captivating atmosphere.", - "Spectacular views of the Trishul and Nanda Ghunti peaks, providing a stunning backdrop for your trek.", - "Unique flora and fauna of the region, including rare Himalayan species, enhancing the biodiversity experience.", - "Cultural insights from local villages, where traditional lifestyles are preserved, offering a glimpse into the local way of life.", - ], - culturalInsights: [ - "Engage with local communities and learn about their customs and traditions, enriching your understanding of the region.", - "Experience the rich folklore surrounding the lake and the tales of the skeletal remains, deepening your connection to local history.", - "Visit local temples and understand the spiritual significance of the region, enhancing your cultural immersion.", - ], - physicalChallenges: [ - "Steep ascents and descents requiring good stamina and acclimatization, essential for tackling high-altitude treks.", - "Unpredictable weather conditions, particularly in the high-altitude sections, which can affect trekking plans.", - "Navigating rocky terrains that require careful footing and balance, adding an element of adventure and challenge.", - ], - recommendedGear: [ - "Trekking boots with good ankle support and grip, essential for navigating varied terrains safely.", - "Warm clothing and waterproof jackets to handle sudden weather changes, ensuring comfort during the trek.", - "Sleeping bags suitable for cold temperatures and a sturdy backpack, essential for overnight camping and day treks.", - ], - bestTimeToVisit: - "The ideal months for the Roopkund Trek are May to June and September to October, when the weather is relatively stable, and the trails are accessible.", - image: - "https://upload.wikimedia.org/wikipedia/commons/2/24/Roopkund_Lake.jpg", - }, - { - title: "VALLEY OF FLOWERS TREK", - difficultyLevel: "MODERATE", - altitude: 3658, - district: "CHAMOLI", - address: "Nanda Devi National Park, Joshimath, Uttarakhand, India", - coordinates: [30.3954, 79.6613], - introduction: - "The Valley of Flowers Trek is a breathtaking expedition into one of India's most spectacular national parks. Known for its vibrant meadows filled with a stunning array of endemic flowers, this UNESCO World Heritage site is a paradise for nature lovers and photographers alike. As you trek through the valley, you’ll be greeted by a colorful landscape that comes alive during the monsoon season. The blend of beautiful flora and the majestic backdrop of snow-capped mountains creates a visual feast that captivates all who visit. The Valley of Flowers is not just a visual delight; it’s an opportunity to connect with nature at its most vibrant and enchanting.", - overview: - "This trek spans approximately 38 kilometers and reaches an altitude of 14,197 feet. The journey begins in the quaint village of Govindghat, followed by a trek through lush forests and picturesque landscapes to reach Ghangaria, the base camp for the valley. From Ghangaria, you’ll embark on a day trek to the Valley of Flowers, surrounded by alpine meadows and vibrant blooms of diverse species. The valley is also home to a rich variety of wildlife, including the elusive snow leopard. Each step of the trek reveals stunning vistas, including views of the Zanskar Range and the nearby Nanda Devi peak. This trek is not only a visual delight but also a wonderful opportunity to reconnect with nature in its most pristine form, allowing trekkers to appreciate the beauty of biodiversity.", - route: [ - "Day 1: Drive to Joshimath, then trek to Govindghat, passing scenic landscapes and local culture, immersing yourself in the environment.", - "Day 2: Trek to Ghangaria (9,800 feet), surrounded by lush forests and gushing streams, providing a refreshing experience.", - "Day 3: Visit the Valley of Flowers and immerse yourself in its beauty, capturing stunning photographs of vibrant blooms and the surrounding mountains.", - "Day 4: Explore more of the valley before returning to Ghangaria, taking time to appreciate the serene surroundings and diverse flora.", - "Day 5: Return trek to Govindghat, followed by a drive back to Joshimath, reflecting on the enchanting experience.", - ], - attractions: [ - "Vibrant meadows of endemic flowers like Brahmakamal and Blue Poppy, providing a colorful spectacle during the blooming season.", - "Stunning mountain views, particularly of the Zanskar Range, enhancing the trekking experience with breathtaking scenery.", - "Rich biodiversity of flora and fauna, including rare wildlife species, making it a haven for nature lovers.", - "Serenity of nature and tranquil surroundings, perfect for meditation and reflection amidst the stunning landscapes.", - ], - culturalInsights: [ - "Interact with local communities, learning about their traditions and ways of life, enriching your cultural experience.", - "Explore the spiritual significance of the region, with several temples along the way that tell stories of local beliefs.", - "Understand the conservation efforts in place to preserve the unique ecosystem of the valley, contributing to sustainable tourism.", - ], - physicalChallenges: [ - "Moderate trek suitable for beginners but requires good physical fitness to handle altitude and distance.", - "Variable weather conditions that can change rapidly, especially in the high-altitude sections, requiring preparedness.", - "Some sections may involve steep ascents and rocky trails requiring caution, adding to the adventure.", - ], - recommendedGear: [ - "Comfortable trekking shoes with good grip for diverse terrains, essential for a safe trekking experience.", - "Layered clothing to adapt to varying temperatures and conditions, ensuring comfort throughout the trek.", - "A reliable daypack for carrying essentials, including water, snacks, and a first-aid kit for emergencies.", - ], - bestTimeToVisit: - "The best time to visit the Valley of Flowers is between late June and early September, when the flowers are in full bloom and the weather is pleasant.", - image: - "https://upload.wikimedia.org/wikipedia/commons/6/63/Valley_of_flowers_uttaranchal_full_view.JPG", - - }, - { - title: "HAR KI DUN TREK", - difficultyLevel: "MODERATE", - altitude: 3566, - district: "UTTARKASHI", - address: "Har Ki Dun Valley, Uttarkashi, Uttarakhand, India", - coordinates: [30.6764, 78.4260], - introduction: - "The Har Ki Dun Trek offers a mesmerizing blend of natural beauty and rich cultural heritage, often referred to as the 'Valley of Gods.' This picturesque valley is steeped in mythological significance and is surrounded by magnificent snow-capped peaks, dense forests, and lush meadows. The trek is an ideal escape for those looking to immerse themselves in the tranquility of nature while exploring the rich history and traditions of the local people. Trekking in Har Ki Dun allows you to connect with the serene landscapes and delve into the stories that the mountains hold.", - overview: - "Spanning approximately 47 kilometers, the Har Ki Dun Trek ascends to an altitude of 11,675 feet. The journey begins in Sankri, where trekkers are greeted by the serene beauty of the Himalayas. As you trek through charming villages and dense forests, you'll encounter diverse wildlife and a variety of flora. The trek culminates in the stunning Har Ki Dun valley, offering breathtaking views of the Swargarohini peaks. This trek is not just about the stunning scenery; it also provides an opportunity to engage with the local culture, with traditional wooden houses and warm hospitality from the villagers. The journey through Har Ki Dun is a blend of adventure and serenity, making it a favorite among trekkers, with opportunities for reflection and exploration.", - route: [ - "Day 1: Drive to Sankri (6,400 feet), your starting point, through scenic landscapes that set the stage for your adventure.", - "Day 2: Trek to Taluka (8,500 feet), exploring local culture and enjoying the beauty of nature along the way.", - "Day 3: Continue to Har Ki Dun (11,675 feet), taking in the stunning views of the surrounding peaks and meadows.", - "Day 4: Explore the valley and the nearby villages, gaining insights into local customs and traditions.", - "Day 5: Return trek to Sankri, reflecting on the beauty and culture experienced throughout the journey.", - ], - attractions: [ - "The breathtaking beauty of Har Ki Dun valley, surrounded by majestic peaks and lush meadows, offering a picturesque landscape.", - "Traditional villages and local culture, providing a glimpse into the life of the people living in the Himalayas.", - "Rich biodiversity, with opportunities to spot rare wildlife and unique plant species along the trekking route.", - "Stunning views of the Swargarohini peaks, especially at sunrise and sunset, creating breathtaking photo opportunities.", - ], - culturalInsights: [ - "Engage with the local community and learn about their traditions, enhancing your cultural understanding of the region.", - "Explore the mythology associated with the valley, deepening your appreciation of its historical significance.", - "Discover the local cuisine and hospitality, providing a unique culinary experience that reflects the region's culture.", - ], - physicalChallenges: [ - "Moderate trek with steep sections, requiring good physical fitness and acclimatization to altitude.", - "Weather conditions can change rapidly, especially in the higher altitudes, demanding preparedness and flexibility.", - "Rocky and uneven terrain in certain sections that require careful navigation and balance.", - ], - recommendedGear: [ - "Sturdy trekking boots for comfort and support on rugged terrains, essential for a safe trekking experience.", - "Warm layers and waterproof clothing to handle variable weather conditions effectively.", - "A durable backpack to carry essential items, including a water bottle, snacks, and a first-aid kit.", - ], - bestTimeToVisit: - "The ideal time to trek Har Ki Dun is from April to June and September to November, when the weather is pleasant and the trails are accessible.", - image: - "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a2/Har_Ki_Dun.jpg/1200px-Har_Ki_Dun.jpg", - }, - { - title: "KEDARKANTHA TREK", - difficultyLevel: "MODERATE", - altitude: 3810, - district: "UTTARKASHI", - address: "Kedarkantha, Uttarkashi, Uttarakhand, India", - coordinates: [31.0262, 78.5506], + { + title: "ROOPKUND TREK", + difficultyLevel: "DIFFICULT", + altitude: 4536, + district: "CHAMOLI", + address: "Roopkund Lake, Chamoli, Uttarakhand, India", + coordinates: [30.3440, 80.0940], + introduction: + "The Roopkund Trek is a mesmerizing journey through the pristine wilderness of the Himalayas, famously known as the 'Skeleton Lake.' This trek is shrouded in mystery and folklore, as the lake is home to human skeletal remains that date back centuries. Surrounded by majestic mountains and verdant meadows, the trek offers not just adventure but also a unique glimpse into the region's rich history and culture. As you traverse the rugged terrain, you'll encounter breathtaking landscapes that change with every turn, making this an unforgettable experience for every nature enthusiast.", + overview: + "Covering approximately 53 kilometers, the Roopkund Trek leads you to an altitude of 16,470 feet. This trek takes you through dense forests of oak and rhododendron, high-altitude meadows, and rugged mountain trails. The journey begins at Lohajung, where trekkers are greeted by the serene beauty of the Himalayas. As you ascend, witness the stunning views of snow-capped peaks like Trishul and Nanda Ghunti. The final destination, Roopkund Lake, is an enchanting glacial lake that lies at the heart of this trek, offering stunning reflections of the surrounding mountains. The area is rich in biodiversity, making it a perfect location for wildlife enthusiasts. This trek not only tests your physical limits but also fills your spirit with the tranquility of the Himalayas.", + route: [ + "Day 1: Drive to Lohajung (7,700 feet), where the journey begins, and enjoy the breathtaking views during the drive.", + "Day 2: Trek to Bekhal Tal (9,800 feet), where you can enjoy the serene surroundings and observe local flora and fauna.", + "Day 3: Ascend to Roopkund (16,470 feet), visit the lake, and explore the nearby ancient ruins while immersing yourself in local legends.", + "Day 4: Trek to Patar Nachauni (12,500 feet), where you can enjoy panoramic views and the stunning beauty of alpine meadows, taking in the essence of the Himalayas.", + "Day 5: Return trek to Lohajung, reflecting on the experiences and memories made along the way, with plenty of opportunities for photography.", + ], + attractions: [ + "The mysterious Roopkund Lake, often shrouded in mist and mystery, presenting an eerie yet captivating atmosphere.", + "Spectacular views of the Trishul and Nanda Ghunti peaks, providing a stunning backdrop for your trek.", + "Unique flora and fauna of the region, including rare Himalayan species, enhancing the biodiversity experience.", + "Cultural insights from local villages, where traditional lifestyles are preserved, offering a glimpse into the local way of life.", + ], + culturalInsights: [ + "Engage with local communities and learn about their customs and traditions, enriching your understanding of the region.", + "Experience the rich folklore surrounding the lake and the tales of the skeletal remains, deepening your connection to local history.", + "Visit local temples and understand the spiritual significance of the region, enhancing your cultural immersion.", + ], + physicalChallenges: [ + "Steep ascents and descents requiring good stamina and acclimatization, essential for tackling high-altitude treks.", + "Unpredictable weather conditions, particularly in the high-altitude sections, which can affect trekking plans.", + "Navigating rocky terrains that require careful footing and balance, adding an element of adventure and challenge.", + ], + recommendedGear: [ + "Trekking boots with good ankle support and grip, essential for navigating varied terrains safely.", + "Warm clothing and waterproof jackets to handle sudden weather changes, ensuring comfort during the trek.", + "Sleeping bags suitable for cold temperatures and a sturdy backpack, essential for overnight camping and day treks.", + ], + bestTimeToVisit: + "The ideal months for the Roopkund Trek are May to June and September to October, when the weather is relatively stable, and the trails are accessible.", + image: + "https://upload.wikimedia.org/wikipedia/commons/2/24/Roopkund_Lake.jpg", + }, + { + title: "VALLEY OF FLOWERS TREK", + difficultyLevel: "MODERATE", + altitude: 3658, + district: "CHAMOLI", + address: "Nanda Devi National Park, Joshimath, Uttarakhand, India", + coordinates: [30.3954, 79.6613], + introduction: + "The Valley of Flowers Trek is a breathtaking expedition into one of India's most spectacular national parks. Known for its vibrant meadows filled with a stunning array of endemic flowers, this UNESCO World Heritage site is a paradise for nature lovers and photographers alike. As you trek through the valley, you’ll be greeted by a colorful landscape that comes alive during the monsoon season. The blend of beautiful flora and the majestic backdrop of snow-capped mountains creates a visual feast that captivates all who visit. The Valley of Flowers is not just a visual delight; it’s an opportunity to connect with nature at its most vibrant and enchanting.", + overview: + "This trek spans approximately 38 kilometers and reaches an altitude of 14,197 feet. The journey begins in the quaint village of Govindghat, followed by a trek through lush forests and picturesque landscapes to reach Ghangaria, the base camp for the valley. From Ghangaria, you’ll embark on a day trek to the Valley of Flowers, surrounded by alpine meadows and vibrant blooms of diverse species. The valley is also home to a rich variety of wildlife, including the elusive snow leopard. Each step of the trek reveals stunning vistas, including views of the Zanskar Range and the nearby Nanda Devi peak. This trek is not only a visual delight but also a wonderful opportunity to reconnect with nature in its most pristine form, allowing trekkers to appreciate the beauty of biodiversity.", + route: [ + "Day 1: Drive to Joshimath, then trek to Govindghat, passing scenic landscapes and local culture, immersing yourself in the environment.", + "Day 2: Trek to Ghangaria (9,800 feet), surrounded by lush forests and gushing streams, providing a refreshing experience.", + "Day 3: Visit the Valley of Flowers and immerse yourself in its beauty, capturing stunning photographs of vibrant blooms and the surrounding mountains.", + "Day 4: Explore more of the valley before returning to Ghangaria, taking time to appreciate the serene surroundings and diverse flora.", + "Day 5: Return trek to Govindghat, followed by a drive back to Joshimath, reflecting on the enchanting experience.", + ], + attractions: [ + "Vibrant meadows of endemic flowers like Brahmakamal and Blue Poppy, providing a colorful spectacle during the blooming season.", + "Stunning mountain views, particularly of the Zanskar Range, enhancing the trekking experience with breathtaking scenery.", + "Rich biodiversity of flora and fauna, including rare wildlife species, making it a haven for nature lovers.", + "Serenity of nature and tranquil surroundings, perfect for meditation and reflection amidst the stunning landscapes.", + ], + culturalInsights: [ + "Interact with local communities, learning about their traditions and ways of life, enriching your cultural experience.", + "Explore the spiritual significance of the region, with several temples along the way that tell stories of local beliefs.", + "Understand the conservation efforts in place to preserve the unique ecosystem of the valley, contributing to sustainable tourism.", + ], + physicalChallenges: [ + "Moderate trek suitable for beginners but requires good physical fitness to handle altitude and distance.", + "Variable weather conditions that can change rapidly, especially in the high-altitude sections, requiring preparedness.", + "Some sections may involve steep ascents and rocky trails requiring caution, adding to the adventure.", + ], + recommendedGear: [ + "Comfortable trekking shoes with good grip for diverse terrains, essential for a safe trekking experience.", + "Layered clothing to adapt to varying temperatures and conditions, ensuring comfort throughout the trek.", + "A reliable daypack for carrying essentials, including water, snacks, and a first-aid kit for emergencies.", + ], + bestTimeToVisit: + "The best time to visit the Valley of Flowers is between late June and early September, when the flowers are in full bloom and the weather is pleasant.", + image: + "https://upload.wikimedia.org/wikipedia/commons/6/63/Valley_of_flowers_uttaranchal_full_view.JPG", + + }, + { + title: "HAR KI DUN TREK", + difficultyLevel: "MODERATE", + altitude: 3566, + district: "UTTARKASHI", + address: "Har Ki Dun Valley, Uttarkashi, Uttarakhand, India", + coordinates: [30.6764, 78.4260], + introduction: + "The Har Ki Dun Trek offers a mesmerizing blend of natural beauty and rich cultural heritage, often referred to as the 'Valley of Gods.' This picturesque valley is steeped in mythological significance and is surrounded by magnificent snow-capped peaks, dense forests, and lush meadows. The trek is an ideal escape for those looking to immerse themselves in the tranquility of nature while exploring the rich history and traditions of the local people. Trekking in Har Ki Dun allows you to connect with the serene landscapes and delve into the stories that the mountains hold.", + overview: + "Spanning approximately 47 kilometers, the Har Ki Dun Trek ascends to an altitude of 11,675 feet. The journey begins in Sankri, where trekkers are greeted by the serene beauty of the Himalayas. As you trek through charming villages and dense forests, you'll encounter diverse wildlife and a variety of flora. The trek culminates in the stunning Har Ki Dun valley, offering breathtaking views of the Swargarohini peaks. This trek is not just about the stunning scenery; it also provides an opportunity to engage with the local culture, with traditional wooden houses and warm hospitality from the villagers. The journey through Har Ki Dun is a blend of adventure and serenity, making it a favorite among trekkers, with opportunities for reflection and exploration.", + route: [ + "Day 1: Drive to Sankri (6,400 feet), your starting point, through scenic landscapes that set the stage for your adventure.", + "Day 2: Trek to Taluka (8,500 feet), exploring local culture and enjoying the beauty of nature along the way.", + "Day 3: Continue to Har Ki Dun (11,675 feet), taking in the stunning views of the surrounding peaks and meadows.", + "Day 4: Explore the valley and the nearby villages, gaining insights into local customs and traditions.", + "Day 5: Return trek to Sankri, reflecting on the beauty and culture experienced throughout the journey.", + ], + attractions: [ + "The breathtaking beauty of Har Ki Dun valley, surrounded by majestic peaks and lush meadows, offering a picturesque landscape.", + "Traditional villages and local culture, providing a glimpse into the life of the people living in the Himalayas.", + "Rich biodiversity, with opportunities to spot rare wildlife and unique plant species along the trekking route.", + "Stunning views of the Swargarohini peaks, especially at sunrise and sunset, creating breathtaking photo opportunities.", + ], + culturalInsights: [ + "Engage with the local community and learn about their traditions, enhancing your cultural understanding of the region.", + "Explore the mythology associated with the valley, deepening your appreciation of its historical significance.", + "Discover the local cuisine and hospitality, providing a unique culinary experience that reflects the region's culture.", + ], + physicalChallenges: [ + "Moderate trek with steep sections, requiring good physical fitness and acclimatization to altitude.", + "Weather conditions can change rapidly, especially in the higher altitudes, demanding preparedness and flexibility.", + "Rocky and uneven terrain in certain sections that require careful navigation and balance.", + ], + recommendedGear: [ + "Sturdy trekking boots for comfort and support on rugged terrains, essential for a safe trekking experience.", + "Warm layers and waterproof clothing to handle variable weather conditions effectively.", + "A durable backpack to carry essential items, including a water bottle, snacks, and a first-aid kit.", + ], + bestTimeToVisit: + "The ideal time to trek Har Ki Dun is from April to June and September to November, when the weather is pleasant and the trails are accessible.", + image: + "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a2/Har_Ki_Dun.jpg/1200px-Har_Ki_Dun.jpg", + }, + { + title: "KEDARKANTHA TREK", + difficultyLevel: "MODERATE", + altitude: 3810, + district: "UTTARKASHI", + address: "Kedarkantha, Uttarkashi, Uttarakhand, India", + coordinates: [31.0262, 78.5506], - introduction: - "Experience the thrilling Kedarkantha Trek, renowned for its stunning winter landscapes and breathtaking summit views. This trek is especially popular during the winter months when the entire region is blanketed in snow, creating a picturesque setting for adventure seekers.", - overview: - "The Kedarkantha Trek offers a unique combination of snow-covered trails and mesmerizing vistas, perfect for both beginners and seasoned trekkers. Spanning approximately 20 kilometers, this trek takes you through charming villages, dense pine forests, and open meadows, leading up to the magnificent Kedarkantha summit at 12,500 feet. The trail is well-defined and presents a blend of moderate to challenging sections, making it an ideal choice for those looking to experience the raw beauty of the Himalayas while pushing their limits.", - route: [ - "Day 1: Drive to Sankri (6,400 feet), followed by a scenic trek to Juda Ka Talab (9,100 feet), a beautiful alpine lake perfect for camping.", - "Day 2: Trek to Kedarkantha base (11,250 feet), surrounded by snow-clad peaks, where you can enjoy the stunning vistas and prepare for the summit.", - "Day 3: Early morning summit trek to Kedarkantha (12,500 feet) for breathtaking sunrise views over the Himalayas, then descend back to Juda Ka Talab for an overnight stay.", - "Day 4: Return to Sankri, celebrating your achievements and soaking in the beautiful landscape one last time.", - ], - attractions: [ - "Magnificent views from the summit, offering panoramic vistas of the surrounding peaks, including Swargarohini, Black Peak, and the Yamunotri range.", - "Picturesque Juda Ka Talab, a serene campsite known for its crystal-clear waters and surrounding snow-draped landscapes.", - "Snow-covered trails and forests, providing a magical winter experience that captures the essence of the Himalayas.", - "Rich Himalayan flora and fauna, including a chance to spot wildlife such as the Himalayan black bear, snow leopard, and various bird species.", - ], - culturalInsights: [ - "Engage with the local communities in Sankri and surrounding villages, learning about their traditions and lifestyle.", - "Explore the folklore associated with Kedarkantha, enhancing your appreciation of the region's cultural significance.", - "Sample local cuisine, offering a taste of the unique flavors and hospitality of the Himachali people.", - ], - physicalChallenges: [ - "Moderate difficulty with steep sections and snow-covered trails, requiring good physical fitness and acclimatization to altitude.", - "Weather conditions can change rapidly, so trekkers should be prepared for cold temperatures and snow.", - "Navigating through uneven terrain and maintaining balance on snowy paths may pose challenges.", - ], - recommendedGear: [ - "Sturdy, waterproof trekking boots with good grip to handle snow and icy conditions.", - "Warm layers, including thermal wear, insulated jackets, and waterproof clothing to combat the cold.", - "Essential gear such as trekking poles, a good-quality backpack, and a first-aid kit for safety.", - ], - bestTimeToVisit: - "The best time for the Kedarkantha Trek is from December to April, when the region is covered in snow, providing an ideal winter trekking experience.", - image: - "https://upload.wikimedia.org/wikipedia/commons/6/68/Kedarkantha_Peak.jpg", - }, + introduction: + "Experience the thrilling Kedarkantha Trek, renowned for its stunning winter landscapes and breathtaking summit views. This trek is especially popular during the winter months when the entire region is blanketed in snow, creating a picturesque setting for adventure seekers.", + overview: + "The Kedarkantha Trek offers a unique combination of snow-covered trails and mesmerizing vistas, perfect for both beginners and seasoned trekkers. Spanning approximately 20 kilometers, this trek takes you through charming villages, dense pine forests, and open meadows, leading up to the magnificent Kedarkantha summit at 12,500 feet. The trail is well-defined and presents a blend of moderate to challenging sections, making it an ideal choice for those looking to experience the raw beauty of the Himalayas while pushing their limits.", + route: [ + "Day 1: Drive to Sankri (6,400 feet), followed by a scenic trek to Juda Ka Talab (9,100 feet), a beautiful alpine lake perfect for camping.", + "Day 2: Trek to Kedarkantha base (11,250 feet), surrounded by snow-clad peaks, where you can enjoy the stunning vistas and prepare for the summit.", + "Day 3: Early morning summit trek to Kedarkantha (12,500 feet) for breathtaking sunrise views over the Himalayas, then descend back to Juda Ka Talab for an overnight stay.", + "Day 4: Return to Sankri, celebrating your achievements and soaking in the beautiful landscape one last time.", + ], + attractions: [ + "Magnificent views from the summit, offering panoramic vistas of the surrounding peaks, including Swargarohini, Black Peak, and the Yamunotri range.", + "Picturesque Juda Ka Talab, a serene campsite known for its crystal-clear waters and surrounding snow-draped landscapes.", + "Snow-covered trails and forests, providing a magical winter experience that captures the essence of the Himalayas.", + "Rich Himalayan flora and fauna, including a chance to spot wildlife such as the Himalayan black bear, snow leopard, and various bird species.", + ], + culturalInsights: [ + "Engage with the local communities in Sankri and surrounding villages, learning about their traditions and lifestyle.", + "Explore the folklore associated with Kedarkantha, enhancing your appreciation of the region's cultural significance.", + "Sample local cuisine, offering a taste of the unique flavors and hospitality of the Himachali people.", + ], + physicalChallenges: [ + "Moderate difficulty with steep sections and snow-covered trails, requiring good physical fitness and acclimatization to altitude.", + "Weather conditions can change rapidly, so trekkers should be prepared for cold temperatures and snow.", + "Navigating through uneven terrain and maintaining balance on snowy paths may pose challenges.", + ], + recommendedGear: [ + "Sturdy, waterproof trekking boots with good grip to handle snow and icy conditions.", + "Warm layers, including thermal wear, insulated jackets, and waterproof clothing to combat the cold.", + "Essential gear such as trekking poles, a good-quality backpack, and a first-aid kit for safety.", + ], + bestTimeToVisit: + "The best time for the Kedarkantha Trek is from December to April, when the region is covered in snow, providing an ideal winter trekking experience.", + image: + "https://upload.wikimedia.org/wikipedia/commons/6/68/Kedarkantha_Peak.jpg", + }, - { - title: "NANDA DEVI BASE CAMP TREK", - difficultyLevel: "DIFFICULT", - altitude: 4000, - district: "CHAMOLI", - address: "Nanda Devi National Park, Uttarakhand, India", - coordinates: [30.3896, 79.7160], + { + title: "NANDA DEVI BASE CAMP TREK", + difficultyLevel: "DIFFICULT", + altitude: 4000, + district: "CHAMOLI", + address: "Nanda Devi National Park, Uttarakhand, India", + coordinates: [30.3896, 79.7160], - introduction: - "Discover the untouched beauty of Nanda Devi Base Camp, a majestic trek that offers a glimpse into the heart of the Himalayas. This trek is an adventure through one of India's most scenic and lesser-known trails, perfect for nature lovers and adventure seekers alike.", - overview: - "This trek leads you through lush forests and alpine meadows, culminating at the base of Nanda Devi, the second highest peak in India. With a combination of challenging terrains and breathtaking views, trekkers will experience the serenity of remote Himalayan landscapes and the rich biodiversity of the region.", - route: [ - "Day 1: Drive to Munsiari, your starting point, where you can enjoy the scenic views of the surrounding mountains.", - "Day 2: Trek to Lilam (6,600 feet), passing through scenic landscapes dotted with charming villages and vibrant flora.", - "Day 3: Continue to Pachu (8,000 feet), surrounded by pristine nature and breathtaking mountain vistas.", - "Day 4: Reach Nanda Devi Base Camp (13,120 feet) and soak in the stunning views of the towering peaks that surround you.", - "Day 5: Descend back to Pachu, followed by a return trek to Munsiari, reflecting on the unforgettable journey.", - ], - attractions: [ - "Spectacular views of Nanda Devi and surrounding peaks, including Nanda Kot and other majestic summits.", - "Rich biodiversity and unique flora, including rare Himalayan herbs and flowers.", - "Cultural insights from local villages, where you can interact with the inhabitants and learn about their traditional lifestyle.", - "Tranquility of the Himalayan wilderness, offering a peaceful retreat away from the hustle and bustle of everyday life.", - ], - culturalInsights: [ - "Engage with local communities, learning about their traditions and customs.", - "Experience the local cuisine, which often includes freshly prepared dishes using local ingredients.", - "Participate in traditional festivities if your trek coincides with local celebrations.", - ], - physicalChallenges: [ - "Moderate to challenging sections of the trek that require good physical fitness and acclimatization to high altitudes.", - "Unpredictable weather conditions, necessitating preparation for rain, snow, and cold temperatures.", - ], - recommendedGear: [ - "Sturdy trekking boots with good ankle support for navigating varied terrains.", - "Warm layers, including thermal wear and waterproof clothing, to keep you comfortable.", - "Essential gear such as trekking poles, a high-quality backpack, and a first-aid kit.", - ], - bestTimeToVisit: - "The best time for the Nanda Devi Base Camp Trek is from May to October when the weather is relatively stable and the trails are clear.", - image: - "https://upload.wikimedia.org/wikipedia/commons/d/d2/Mt._Nanda_Devi.jpg", - }, - { - title: "PINDARI GLACIER TREK", - difficultyLevel: "MODERATE", - altitude: 3660, - district: "BAGESHWAR", - address: "Pindari Glacier, Bageshwar, Uttarakhand, India", - coordinates: [30.2546, 80.0155], + introduction: + "Discover the untouched beauty of Nanda Devi Base Camp, a majestic trek that offers a glimpse into the heart of the Himalayas. This trek is an adventure through one of India's most scenic and lesser-known trails, perfect for nature lovers and adventure seekers alike.", + overview: + "This trek leads you through lush forests and alpine meadows, culminating at the base of Nanda Devi, the second highest peak in India. With a combination of challenging terrains and breathtaking views, trekkers will experience the serenity of remote Himalayan landscapes and the rich biodiversity of the region.", + route: [ + "Day 1: Drive to Munsiari, your starting point, where you can enjoy the scenic views of the surrounding mountains.", + "Day 2: Trek to Lilam (6,600 feet), passing through scenic landscapes dotted with charming villages and vibrant flora.", + "Day 3: Continue to Pachu (8,000 feet), surrounded by pristine nature and breathtaking mountain vistas.", + "Day 4: Reach Nanda Devi Base Camp (13,120 feet) and soak in the stunning views of the towering peaks that surround you.", + "Day 5: Descend back to Pachu, followed by a return trek to Munsiari, reflecting on the unforgettable journey.", + ], + attractions: [ + "Spectacular views of Nanda Devi and surrounding peaks, including Nanda Kot and other majestic summits.", + "Rich biodiversity and unique flora, including rare Himalayan herbs and flowers.", + "Cultural insights from local villages, where you can interact with the inhabitants and learn about their traditional lifestyle.", + "Tranquility of the Himalayan wilderness, offering a peaceful retreat away from the hustle and bustle of everyday life.", + ], + culturalInsights: [ + "Engage with local communities, learning about their traditions and customs.", + "Experience the local cuisine, which often includes freshly prepared dishes using local ingredients.", + "Participate in traditional festivities if your trek coincides with local celebrations.", + ], + physicalChallenges: [ + "Moderate to challenging sections of the trek that require good physical fitness and acclimatization to high altitudes.", + "Unpredictable weather conditions, necessitating preparation for rain, snow, and cold temperatures.", + ], + recommendedGear: [ + "Sturdy trekking boots with good ankle support for navigating varied terrains.", + "Warm layers, including thermal wear and waterproof clothing, to keep you comfortable.", + "Essential gear such as trekking poles, a high-quality backpack, and a first-aid kit.", + ], + bestTimeToVisit: + "The best time for the Nanda Devi Base Camp Trek is from May to October when the weather is relatively stable and the trails are clear.", + image: + "https://upload.wikimedia.org/wikipedia/commons/d/d2/Mt._Nanda_Devi.jpg", + }, + { + title: "PINDARI GLACIER TREK", + difficultyLevel: "MODERATE", + altitude: 3660, + district: "BAGESHWAR", + address: "Pindari Glacier, Bageshwar, Uttarakhand, India", + coordinates: [30.2546, 80.0155], - introduction: - "Venture to the Pindari Glacier, a mesmerizing trek that offers breathtaking views of the majestic glacier and surrounding peaks. This trek is renowned for its pristine natural beauty and serene atmosphere.", - overview: - "This trek takes you through quaint villages and lush landscapes, culminating at the Pindari Glacier, a true gem of the Kumaon Himalayas. The route is dotted with vibrant meadows and majestic pine forests, providing a rich tapestry of experiences along the way.", - route: [ - "Day 1: Drive to Khati (7,600 feet), your base camp, enjoying the scenic vistas along the way.", - "Day 2: Trek to Pindari Glacier (12,400 feet), enjoying the stunning scenery as you make your way to the glacier.", - "Day 3: Explore the glacier and its mesmerizing beauty, capturing moments with photography and reflection.", - "Day 4: Return trek to Khati, reflecting on your adventure and the breathtaking views encountered.", - ], - attractions: [ - "Stunning views of Pindari Glacier, with the impressive backdrop of Nanda Devi and other peaks.", - "Charming villages along the route, providing a glimpse into the local lifestyle.", - "Lush meadows and serene landscapes, ideal for nature walks and photography.", - "Unique opportunities for photography and exploration of the glacial landscape.", - ], - culturalInsights: [ - "Discover the local culture of the Kumaon region through interactions with villagers.", - "Taste local dishes that highlight the unique flavors of the region.", - ], - physicalChallenges: [ - "Moderate difficulty, with sections that may require stamina due to altitude.", - "Variable weather conditions, so trekkers should be prepared for sudden changes.", - ], - recommendedGear: [ - "Good-quality trekking boots with excellent grip and waterproofing.", - "Warm clothing layers, including down jackets and thermal innerwear.", - "Essential gear such as a daypack, hydration system, and a basic first-aid kit.", - ], - bestTimeToVisit: - "The ideal time for the Pindari Glacier Trek is from May to October when the weather is stable and the trails are clear.", - image: - "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c9/Pindari_glacier%2C_Uttarakhand%2C_India.jpg/1200px-Pindari_glacier%2C_Uttarakhand%2C_India.jpg", - }, - { - title: "BALI PASS TREK", - difficultyLevel: "DIFFICULT", - altitude: 4950, - district: "UTTARKASHI", - address: "Bali Pass, Yamunotri, Uttarkashi, Uttarakhand, India", - coordinates: [31.0597, 78.4649] , + introduction: + "Venture to the Pindari Glacier, a mesmerizing trek that offers breathtaking views of the majestic glacier and surrounding peaks. This trek is renowned for its pristine natural beauty and serene atmosphere.", + overview: + "This trek takes you through quaint villages and lush landscapes, culminating at the Pindari Glacier, a true gem of the Kumaon Himalayas. The route is dotted with vibrant meadows and majestic pine forests, providing a rich tapestry of experiences along the way.", + route: [ + "Day 1: Drive to Khati (7,600 feet), your base camp, enjoying the scenic vistas along the way.", + "Day 2: Trek to Pindari Glacier (12,400 feet), enjoying the stunning scenery as you make your way to the glacier.", + "Day 3: Explore the glacier and its mesmerizing beauty, capturing moments with photography and reflection.", + "Day 4: Return trek to Khati, reflecting on your adventure and the breathtaking views encountered.", + ], + attractions: [ + "Stunning views of Pindari Glacier, with the impressive backdrop of Nanda Devi and other peaks.", + "Charming villages along the route, providing a glimpse into the local lifestyle.", + "Lush meadows and serene landscapes, ideal for nature walks and photography.", + "Unique opportunities for photography and exploration of the glacial landscape.", + ], + culturalInsights: [ + "Discover the local culture of the Kumaon region through interactions with villagers.", + "Taste local dishes that highlight the unique flavors of the region.", + ], + physicalChallenges: [ + "Moderate difficulty, with sections that may require stamina due to altitude.", + "Variable weather conditions, so trekkers should be prepared for sudden changes.", + ], + recommendedGear: [ + "Good-quality trekking boots with excellent grip and waterproofing.", + "Warm clothing layers, including down jackets and thermal innerwear.", + "Essential gear such as a daypack, hydration system, and a basic first-aid kit.", + ], + bestTimeToVisit: + "The ideal time for the Pindari Glacier Trek is from May to October when the weather is stable and the trails are clear.", + image: + "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c9/Pindari_glacier%2C_Uttarakhand%2C_India.jpg/1200px-Pindari_glacier%2C_Uttarakhand%2C_India.jpg", + }, + { + title: "BALI PASS TREK", + difficultyLevel: "DIFFICULT", + altitude: 4950, + district: "UTTARKASHI", + address: "Bali Pass, Yamunotri, Uttarkashi, Uttarakhand, India", + coordinates: [31.0597, 78.4649], - introduction: - "Embark on an extraordinary journey through the Bali Pass, a high-altitude trek that connects the Har Ki Dun and Yamunotri valleys. This trek offers a perfect blend of adventure and breathtaking natural beauty.", - overview: - "The Bali Pass Trek offers a rich tapestry of natural beauty, cultural experiences, and thrilling challenges, perfect for adventure enthusiasts. This trek is not only about the stunning landscapes but also about immersing yourself in the rich cultural heritage of the region.", - route: [ - "Day 1: Drive to Sankri (6,400 feet), the starting point, where you can admire the lush surroundings.", - "Day 2: Trek to Juda Ka Talab (9,100 feet), a serene campsite by an alpine lake.", - "Day 3: Continue to Bali Pass (16,200 feet), surrounded by stunning landscapes and glaciers.", - "Day 4: Descend to the beautiful Yamunotri valley, where hot springs and scenic beauty await.", - "Day 5: Return trek to Sankri, cherishing your journey and experiences.", - ], - attractions: [ - "Spectacular views from Bali Pass, providing panoramic vistas of the surrounding peaks and valleys.", - "Diverse landscapes from meadows to glaciers, showcasing the region's natural variety.", - "Cultural insights from local villages, offering a chance to learn about traditional customs and lifestyles.", - "Unique flora and fauna in the region, including rare and endemic species.", - ], - culturalInsights: [ - "Engage with local communities to understand their traditions and ways of life.", - "Explore local cuisine, which includes a mix of simple yet flavorful dishes.", - ], - physicalChallenges: [ - "High-altitude trek requiring good physical fitness and acclimatization.", - "Steep ascents and descents that demand endurance and stamina.", - ], - recommendedGear: [ - "Robust trekking boots suitable for varied terrains.", - "Warm clothing, including insulated jackets and moisture-wicking layers.", - "Essential gear such as a hydration system, trekking poles, and a first-aid kit.", - ], - bestTimeToVisit: - "The best time for the Bali Pass Trek is from May to October when the weather is favorable and the trails are accessible.", - image: - "https://himalayashelter.com/wp-content/uploads/2021/08/bali-pass-top-1024x576.webp", - }, + introduction: + "Embark on an extraordinary journey through the Bali Pass, a high-altitude trek that connects the Har Ki Dun and Yamunotri valleys. This trek offers a perfect blend of adventure and breathtaking natural beauty.", + overview: + "The Bali Pass Trek offers a rich tapestry of natural beauty, cultural experiences, and thrilling challenges, perfect for adventure enthusiasts. This trek is not only about the stunning landscapes but also about immersing yourself in the rich cultural heritage of the region.", + route: [ + "Day 1: Drive to Sankri (6,400 feet), the starting point, where you can admire the lush surroundings.", + "Day 2: Trek to Juda Ka Talab (9,100 feet), a serene campsite by an alpine lake.", + "Day 3: Continue to Bali Pass (16,200 feet), surrounded by stunning landscapes and glaciers.", + "Day 4: Descend to the beautiful Yamunotri valley, where hot springs and scenic beauty await.", + "Day 5: Return trek to Sankri, cherishing your journey and experiences.", + ], + attractions: [ + "Spectacular views from Bali Pass, providing panoramic vistas of the surrounding peaks and valleys.", + "Diverse landscapes from meadows to glaciers, showcasing the region's natural variety.", + "Cultural insights from local villages, offering a chance to learn about traditional customs and lifestyles.", + "Unique flora and fauna in the region, including rare and endemic species.", + ], + culturalInsights: [ + "Engage with local communities to understand their traditions and ways of life.", + "Explore local cuisine, which includes a mix of simple yet flavorful dishes.", + ], + physicalChallenges: [ + "High-altitude trek requiring good physical fitness and acclimatization.", + "Steep ascents and descents that demand endurance and stamina.", + ], + recommendedGear: [ + "Robust trekking boots suitable for varied terrains.", + "Warm clothing, including insulated jackets and moisture-wicking layers.", + "Essential gear such as a hydration system, trekking poles, and a first-aid kit.", + ], + bestTimeToVisit: + "The best time for the Bali Pass Trek is from May to October when the weather is favorable and the trails are accessible.", + image: + "https://himalayashelter.com/wp-content/uploads/2021/08/bali-pass-top-1024x576.webp", + }, - { - title: "KUMAON HIMALAYAS TREK", - difficultyLevel: "MODERATE", - altitude: 4200, - district: "ALMORA", - address: "Kumaon Region, Uttarakhand, India", - coordinates: [29.4440, 79.5500] , - introduction: - "Explore the pristine beauty of the Kumaon Himalayas, where adventure and nature come together in perfect harmony. This trek promises an unforgettable experience for nature lovers and adventure seekers, offering an immersive journey through one of India's most scenic regions.", - overview: - "This trek offers a variety of landscapes, from lush forests to serene lakes, and showcases the rich biodiversity of the region. As you traverse through charming villages and vibrant meadows, you'll witness the majestic peaks of the Himalayas, making this trek a feast for the eyes and soul.", - route: [ - "Day 1: Drive to Munsiari (7,600 feet), your base camp, where you can acclimatize and soak in the stunning surroundings.", - "Day 2: Trek to Khaliya Top (11,500 feet) for panoramic views of the surrounding peaks, including Nanda Devi and Panchachuli.", - "Day 3: Explore the surrounding lakes and meadows, including the pristine Khaliya Lake, where you can relax and enjoy nature's tranquility.", - "Day 4: Descend back to Munsiari, reflecting on your journey and the breathtaking landscapes you've encountered.", - ], - attractions: [ - "Breathtaking views of the Kumaon peaks, including the majestic Nanda Devi and the stunning Panchachuli range.", - "Serene lakes such as Khaliya Lake, known for its crystal-clear waters and serene atmosphere.", - "Rich cultural heritage and local traditions, offering insights into the lifestyle and customs of the Kumaon region.", - "Diverse wildlife and ecosystems, providing opportunities for bird watching and encountering unique flora.", - ], - culturalInsights: [ - "Interact with local communities to learn about their customs and traditional practices.", - "Savor local dishes that highlight the culinary heritage of the Kumaon region, such as 'Aloo Gutuk' and 'Bhatt ki churdkhani'.", - ], - physicalChallenges: [ - "Moderate difficulty, suitable for trekkers with a basic level of fitness; however, good acclimatization is essential.", - "Variable weather conditions may affect the trek, so preparedness for rain and cool temperatures is necessary.", - ], - recommendedGear: [ - "Sturdy trekking boots with good grip and support for the varied terrain.", - "Layered clothing, including thermal wear and a waterproof jacket, to stay comfortable.", - "Essential trekking gear such as a daypack, water bottle, and first-aid kit.", - ], - bestTimeToVisit: - "The best time for the Kumaon Himalayas Trek is from April to October when the weather is pleasant and the trails are clear.", - image: "https://cdn.britannica.com/23/120923-159-7ABAB87D/Nanga-Parbat.jpg", - }, + { + title: "KUMAON HIMALAYAS TREK", + difficultyLevel: "MODERATE", + altitude: 4200, + district: "ALMORA", + address: "Kumaon Region, Uttarakhand, India", + coordinates: [29.4440, 79.5500], + introduction: + "Explore the pristine beauty of the Kumaon Himalayas, where adventure and nature come together in perfect harmony. This trek promises an unforgettable experience for nature lovers and adventure seekers, offering an immersive journey through one of India's most scenic regions.", + overview: + "This trek offers a variety of landscapes, from lush forests to serene lakes, and showcases the rich biodiversity of the region. As you traverse through charming villages and vibrant meadows, you'll witness the majestic peaks of the Himalayas, making this trek a feast for the eyes and soul.", + route: [ + "Day 1: Drive to Munsiari (7,600 feet), your base camp, where you can acclimatize and soak in the stunning surroundings.", + "Day 2: Trek to Khaliya Top (11,500 feet) for panoramic views of the surrounding peaks, including Nanda Devi and Panchachuli.", + "Day 3: Explore the surrounding lakes and meadows, including the pristine Khaliya Lake, where you can relax and enjoy nature's tranquility.", + "Day 4: Descend back to Munsiari, reflecting on your journey and the breathtaking landscapes you've encountered.", + ], + attractions: [ + "Breathtaking views of the Kumaon peaks, including the majestic Nanda Devi and the stunning Panchachuli range.", + "Serene lakes such as Khaliya Lake, known for its crystal-clear waters and serene atmosphere.", + "Rich cultural heritage and local traditions, offering insights into the lifestyle and customs of the Kumaon region.", + "Diverse wildlife and ecosystems, providing opportunities for bird watching and encountering unique flora.", + ], + culturalInsights: [ + "Interact with local communities to learn about their customs and traditional practices.", + "Savor local dishes that highlight the culinary heritage of the Kumaon region, such as 'Aloo Gutuk' and 'Bhatt ki churdkhani'.", + ], + physicalChallenges: [ + "Moderate difficulty, suitable for trekkers with a basic level of fitness; however, good acclimatization is essential.", + "Variable weather conditions may affect the trek, so preparedness for rain and cool temperatures is necessary.", + ], + recommendedGear: [ + "Sturdy trekking boots with good grip and support for the varied terrain.", + "Layered clothing, including thermal wear and a waterproof jacket, to stay comfortable.", + "Essential trekking gear such as a daypack, water bottle, and first-aid kit.", + ], + bestTimeToVisit: + "The best time for the Kumaon Himalayas Trek is from April to October when the weather is pleasant and the trails are clear.", + image: "https://cdn.britannica.com/23/120923-159-7ABAB87D/Nanga-Parbat.jpg", + }, - { - title: "TUNGNATH CHOPTA TREK", - difficultyLevel: "EASY", - altitude: 3680, - district: "CHAMOLI", - address: "Tungnath, Chamoli, Uttarakhand, India", - coordinates: [30.3225, 79.0658], - introduction: - "Experience the breathtaking beauty of the Chopta Tungnath Trek, known for its stunning landscapes and rich cultural heritage. This trek, leading to the highest Shiva temple in the world, combines adventure with spiritual significance, making it a unique experience for trekkers. Nestled in the heart of the Himalayas, Chopta is often referred to as the 'Mini Switzerland of India' due to its picturesque meadows and panoramic views of the surrounding peaks. The trek not only offers mesmerizing views but also a deep connection to the spiritual essence of the region, making it a favorite among both adventure seekers and those seeking solace.", - overview: - "The Chopta Tungnath Trek spans approximately 18 kilometers, reaching an elevation of 13,106 feet at Tungnath. This trek is relatively short yet provides a satisfying experience for both beginners and seasoned trekkers. Starting from Chopta, the trail winds through lush forests filled with rhododendron and deodar trees, leading to the sacred temple of Tungnath. As you ascend, you’ll be treated to stunning views of the Chaukhamba and Neelkanth peaks, creating a backdrop that is nothing short of spectacular. The temple, dedicated to Lord Shiva, is an important pilgrimage site and attracts devotees and adventure enthusiasts alike. This trek combines natural beauty with cultural insights, making it a must-visit for those seeking both adventure and spirituality, while also providing an opportunity for meditation and reflection in a tranquil environment.", - route: [ - "Day 1: Drive to Chopta (8,790 feet), enjoying scenic views of the Himalayas.", - "Day 2: Trek to Tungnath (13,106 feet), visiting the ancient temple and soaking in the serene atmosphere.", - "Day 3: Optional trek to Chandrashila Peak for panoramic views of the Himalayas, followed by return trek to Chopta.", - "Day 4: Return journey to your starting point, reflecting on the beauty and spirituality experienced.", - ], - attractions: [ - "The sacred Tungnath temple, the highest Shiva temple in the world.", - "Stunning views of the surrounding Himalayan peaks, including Chaukhamba and Trishul.", - "Beautiful meadows and forests, particularly vibrant during the spring season.", - "Rich biodiversity, with a chance to spot various bird species and flora.", - ], - culturalInsights: [ - "Explore the religious significance of the Tungnath temple and local rituals.", - "Learn about the folklore associated with Lord Shiva and the region's mythology.", - "Experience local cuisine and hospitality from the villagers along the route.", - ], - physicalChallenges: [ - "Moderate difficulty with steep sections, suitable for most fitness levels.", - "Changing weather conditions that can impact trekking experience.", - "Some rocky and uneven terrain requiring caution and steady footing.", - ], - recommendedGear: [ - "Comfortable trekking shoes with good grip and ankle support.", - "Warm clothing layers for high-altitude temperatures.", - "A daypack for carrying essentials, including water, snacks, and a first-aid kit.", - ], - bestTimeToVisit: - "The best time for the Chopta Tungnath Trek is between March to June and September to November, when the weather is pleasant and the trails are clear.", - image: - "https://trisoj.com/travel-guide/wp-content/uploads/2022/11/Chandrashila.png", - }, - { - title: "RUPIN PASS TREK", - difficultyLevel: "DIFFICULT", - altitude: 4650, - district: "UTTARKASHI", - address: "Rupin Pass, Uttarakhand, India", - coordinates: [31.1414, 78.5780], - introduction: - "Challenge yourself with the Rupin Pass trek, a breathtaking adventure that showcases the stunning beauty of the Himalayas. Known for its dramatic landscapes, this trek offers a unique opportunity to explore the diverse terrains and experience the rich culture of the region.", - overview: - "This trek takes you through picturesque landscapes, charming villages, and vibrant meadows, culminating at the Rupin Pass, which stands at an elevation of 4,650 meters. The journey is filled with mesmerizing views of snow-capped peaks, gushing waterfalls, and lush green valleys, making it a must-do for every adventure enthusiast.", - route: [ - "Day 1: Drive to Dhaula, the starting point, and acclimatize to the altitude while soaking in the natural beauty.", - "Day 2: Trek to Sewa, immersing in local culture and enjoying the warm hospitality of the villagers.", - "Day 3: Continue to Rupin Pass base camp, surrounded by breathtaking views of the surrounding peaks.", - "Day 4: Summit Rupin Pass and enjoy the panoramic views of the majestic Himalayas before descending.", - "Day 5: Return trek to Sewa, reflecting on your journey and the unforgettable memories created.", - ], - attractions: [ - "Stunning views from Rupin Pass, offering a vantage point of the snow-clad peaks.", - "Charming villages along the route, providing insight into local traditions and lifestyles.", - "Rich biodiversity and unique landscapes, including lush meadows, dense forests, and gushing streams.", - "Cultural insights from local communities, enhancing the overall trekking experience.", - ], - physicalChallenges: [ - "Moderate to challenging trek, requiring good physical fitness and acclimatization due to the high altitude.", - "Weather conditions can change rapidly, so preparedness for snow and rain is essential.", - ], - recommendedGear: [ - "High-quality trekking boots with good ankle support for rough terrain.", - "Warm clothing layers and waterproof gear to stay comfortable in varying weather conditions.", - "Essential trekking equipment, including trekking poles, a hydration system, and a first-aid kit.", - ], - culturalInsights: [ - "Experience the hospitality of the local villagers, who provide insights into their daily lives and customs.", - "Learn about the traditional practices and folklore of the region during your trek.", - ], - bestTimeToVisit: - "The best time for the Rupin Pass Trek is from May to October, when the weather is clear and the trails are accessible.", - image: - "https://trekthehimalayas.com/images/RupinPassTrek/GalleryDesktop/Winter/625ce941-4dcc-46d4-a5b7-015e4d037005_Rupin-Pass-6.webp", - }, - { - title: "CHOPTA TO TUNGNATH AND BACK", - difficultyLevel: "EASY", - altitude: 3680, - district: "CHAMOLI", - address: "Chopta, Chamoli, Uttarakhand, India", - coordinates: [30.3158, 79.0962] , - introduction: - "Embark on a scenic trek from Chopta to Tungnath, a journey filled with natural beauty and spiritual significance. This trek not only offers stunning vistas but also allows you to connect with the sacred heritage of the region.", - overview: - "This trek offers a perfect blend of adventure and tranquility, showcasing the stunning landscapes of the region. As you ascend towards Tungnath, you’ll encounter lush green meadows, dense forests, and picturesque views of the surrounding Himalayan peaks, making it a rejuvenating experience.", - route: [ - "Day 1: Drive to Chopta (2,680 meters), your base camp, where you can relax and acclimatize to the altitude.", - "Day 2: Trek to Tungnath (3,680 meters), visiting the ancient Tungnath Temple, one of the highest Shiva temples in the world.", - "Day 3: Return trek to Chopta, with reflections on your experience and the serene beauty of the landscape.", - ], - attractions: [ - "Tungnath Temple, a significant pilgrimage site with deep spiritual resonance.", - "Mesmerizing views of the surrounding peaks, including Chaukamba and Neelkanth.", - "Lush green meadows and forests, providing a serene atmosphere for nature lovers.", - "Serenity and tranquility of the Himalayan landscape, perfect for meditation and relaxation.", - ], - culturalInsights: [ - "Learn about the local legends and traditions associated with the Tungnath Temple and its significance in Hindu mythology.", - "Interact with local villagers and experience their hospitality and unique way of life.", - ], - physicalChallenges: [ - "Moderate trek, suitable for beginners with a reasonable level of fitness; however, be prepared for steep sections.", - "Variable weather conditions, especially in early spring and late autumn, may require warm clothing and rain gear.", - ], - recommendedGear: [ - "Comfortable trekking shoes with good grip and support for the ascent.", - "Layered clothing to accommodate changes in temperature throughout the day.", - "Essential items like a daypack, water bottle, and a basic first-aid kit.", - ], - bestTimeToVisit: - "The best time for the Chopta to Tungnath trek is from April to June and September to November, when the weather is pleasant and the trails are clear.", - image: "https://trekiq.in/uploads/2021/04/Chandrashila-in-winters.jpg", - }, - { - title: "PANWALI KANTHA TREK", - difficultyLevel: "MODERATE", - altitude: 3075, - district: "TEHRI GARHWAL", - address: "Panwali Kantha, Tehri Garhwal, Uttarakhand, India", - coordinates: [30.7110, 78.6460], - introduction: - "The Panwali Kantha Trek is a serene journey that offers a perfect blend of lush greenery, stunning views, and rich cultural heritage. Nestled in the Garhwal Himalayas, this trek is ideal for beginners and nature lovers looking to escape into the wilderness. The path winds through quaint villages, dense forests, and breathtaking meadows, providing an immersive experience in the heart of Uttarakhand's natural beauty.", - overview: - "Covering approximately 36 kilometers, the Panwali Kantha Trek leads you to an altitude of 10,700 feet. The trek begins at the charming village of Kandikhal and ascends through thick oak forests and lush meadows. As you reach the summit, you are greeted with panoramic views of the Himalayan peaks and the enchanting landscapes of the region. The trek is dotted with local flora and fauna, making it a perfect spot for wildlife enthusiasts and photographers alike.", - route: [ - "Day 1: Drive to Kandikhal, the starting point, and acclimatize to the beautiful surroundings.", - "Day 2: Trek to Panwali Kantha (10,700 feet) through picturesque meadows and enjoy stunning views along the way.", - "Day 3: Explore the area, interact with local communities, and take in the serene beauty of the Himalayas before returning to Kandikhal.", - ], - attractions: [ - "Breathtaking views of the surrounding mountains and valleys, perfect for photography enthusiasts.", - "Rich biodiversity, including various species of flora and fauna unique to the region.", - "Cultural experiences with local villagers, offering insights into traditional Garhwali lifestyles.", - ], - culturalInsights: [ - "Engage with local families and learn about their daily lives, customs, and traditional practices.", - "Explore local temples and understand their significance in the cultural landscape of Uttarakhand.", - ], - physicalChallenges: [ - "Gentle ascents with some steep sections, making it suitable for beginner trekkers with moderate fitness levels.", - "Potentially unpredictable weather, especially in higher altitudes, necessitating preparedness.", - ], - recommendedGear: [ - "Comfortable trekking shoes, suitable for varied terrain and long walks.", - "Lightweight and breathable clothing for warm days, along with a warm jacket for cooler evenings.", - "A reliable backpack to carry essentials, along with a water bottle for hydration.", - ], - bestTimeToVisit: - "The best time to visit Panwali Kantha is from April to June and September to November, ensuring pleasant weather for trekking.", - image: - "https://uttarakhandtriptrek.com/wp-content/uploads/2019/03/Panwali-Kantha-Trek-Image.jpg", - }, - { - title: "DRONAGIRI TREK", - difficultyLevel: "MODERATE", - altitude: 6070, - district: "CHAMOLI", - address: "Dronagiri Peak, Chamoli, Uttarakhand, India", - coordinates: [30.3334, 80.1312] , + { + title: "TUNGNATH CHOPTA TREK", + difficultyLevel: "EASY", + altitude: 3680, + district: "CHAMOLI", + address: "Tungnath, Chamoli, Uttarakhand, India", + coordinates: [30.3225, 79.0658], + introduction: + "Experience the breathtaking beauty of the Chopta Tungnath Trek, known for its stunning landscapes and rich cultural heritage. This trek, leading to the highest Shiva temple in the world, combines adventure with spiritual significance, making it a unique experience for trekkers. Nestled in the heart of the Himalayas, Chopta is often referred to as the 'Mini Switzerland of India' due to its picturesque meadows and panoramic views of the surrounding peaks. The trek not only offers mesmerizing views but also a deep connection to the spiritual essence of the region, making it a favorite among both adventure seekers and those seeking solace.", + overview: + "The Chopta Tungnath Trek spans approximately 18 kilometers, reaching an elevation of 13,106 feet at Tungnath. This trek is relatively short yet provides a satisfying experience for both beginners and seasoned trekkers. Starting from Chopta, the trail winds through lush forests filled with rhododendron and deodar trees, leading to the sacred temple of Tungnath. As you ascend, you’ll be treated to stunning views of the Chaukhamba and Neelkanth peaks, creating a backdrop that is nothing short of spectacular. The temple, dedicated to Lord Shiva, is an important pilgrimage site and attracts devotees and adventure enthusiasts alike. This trek combines natural beauty with cultural insights, making it a must-visit for those seeking both adventure and spirituality, while also providing an opportunity for meditation and reflection in a tranquil environment.", + route: [ + "Day 1: Drive to Chopta (8,790 feet), enjoying scenic views of the Himalayas.", + "Day 2: Trek to Tungnath (13,106 feet), visiting the ancient temple and soaking in the serene atmosphere.", + "Day 3: Optional trek to Chandrashila Peak for panoramic views of the Himalayas, followed by return trek to Chopta.", + "Day 4: Return journey to your starting point, reflecting on the beauty and spirituality experienced.", + ], + attractions: [ + "The sacred Tungnath temple, the highest Shiva temple in the world.", + "Stunning views of the surrounding Himalayan peaks, including Chaukhamba and Trishul.", + "Beautiful meadows and forests, particularly vibrant during the spring season.", + "Rich biodiversity, with a chance to spot various bird species and flora.", + ], + culturalInsights: [ + "Explore the religious significance of the Tungnath temple and local rituals.", + "Learn about the folklore associated with Lord Shiva and the region's mythology.", + "Experience local cuisine and hospitality from the villagers along the route.", + ], + physicalChallenges: [ + "Moderate difficulty with steep sections, suitable for most fitness levels.", + "Changing weather conditions that can impact trekking experience.", + "Some rocky and uneven terrain requiring caution and steady footing.", + ], + recommendedGear: [ + "Comfortable trekking shoes with good grip and ankle support.", + "Warm clothing layers for high-altitude temperatures.", + "A daypack for carrying essentials, including water, snacks, and a first-aid kit.", + ], + bestTimeToVisit: + "The best time for the Chopta Tungnath Trek is between March to June and September to November, when the weather is pleasant and the trails are clear.", + image: + "https://trisoj.com/travel-guide/wp-content/uploads/2022/11/Chandrashila.png", + }, + { + title: "RUPIN PASS TREK", + difficultyLevel: "DIFFICULT", + altitude: 4650, + district: "UTTARKASHI", + address: "Rupin Pass, Uttarakhand, India", + coordinates: [31.1414, 78.5780], + introduction: + "Challenge yourself with the Rupin Pass trek, a breathtaking adventure that showcases the stunning beauty of the Himalayas. Known for its dramatic landscapes, this trek offers a unique opportunity to explore the diverse terrains and experience the rich culture of the region.", + overview: + "This trek takes you through picturesque landscapes, charming villages, and vibrant meadows, culminating at the Rupin Pass, which stands at an elevation of 4,650 meters. The journey is filled with mesmerizing views of snow-capped peaks, gushing waterfalls, and lush green valleys, making it a must-do for every adventure enthusiast.", + route: [ + "Day 1: Drive to Dhaula, the starting point, and acclimatize to the altitude while soaking in the natural beauty.", + "Day 2: Trek to Sewa, immersing in local culture and enjoying the warm hospitality of the villagers.", + "Day 3: Continue to Rupin Pass base camp, surrounded by breathtaking views of the surrounding peaks.", + "Day 4: Summit Rupin Pass and enjoy the panoramic views of the majestic Himalayas before descending.", + "Day 5: Return trek to Sewa, reflecting on your journey and the unforgettable memories created.", + ], + attractions: [ + "Stunning views from Rupin Pass, offering a vantage point of the snow-clad peaks.", + "Charming villages along the route, providing insight into local traditions and lifestyles.", + "Rich biodiversity and unique landscapes, including lush meadows, dense forests, and gushing streams.", + "Cultural insights from local communities, enhancing the overall trekking experience.", + ], + physicalChallenges: [ + "Moderate to challenging trek, requiring good physical fitness and acclimatization due to the high altitude.", + "Weather conditions can change rapidly, so preparedness for snow and rain is essential.", + ], + recommendedGear: [ + "High-quality trekking boots with good ankle support for rough terrain.", + "Warm clothing layers and waterproof gear to stay comfortable in varying weather conditions.", + "Essential trekking equipment, including trekking poles, a hydration system, and a first-aid kit.", + ], + culturalInsights: [ + "Experience the hospitality of the local villagers, who provide insights into their daily lives and customs.", + "Learn about the traditional practices and folklore of the region during your trek.", + ], + bestTimeToVisit: + "The best time for the Rupin Pass Trek is from May to October, when the weather is clear and the trails are accessible.", + image: + "https://trekthehimalayas.com/images/RupinPassTrek/GalleryDesktop/Winter/625ce941-4dcc-46d4-a5b7-015e4d037005_Rupin-Pass-6.webp", + }, + { + title: "CHOPTA TO TUNGNATH AND BACK", + difficultyLevel: "EASY", + altitude: 3680, + district: "CHAMOLI", + address: "Chopta, Chamoli, Uttarakhand, India", + coordinates: [30.3158, 79.0962], + introduction: + "Embark on a scenic trek from Chopta to Tungnath, a journey filled with natural beauty and spiritual significance. This trek not only offers stunning vistas but also allows you to connect with the sacred heritage of the region.", + overview: + "This trek offers a perfect blend of adventure and tranquility, showcasing the stunning landscapes of the region. As you ascend towards Tungnath, you’ll encounter lush green meadows, dense forests, and picturesque views of the surrounding Himalayan peaks, making it a rejuvenating experience.", + route: [ + "Day 1: Drive to Chopta (2,680 meters), your base camp, where you can relax and acclimatize to the altitude.", + "Day 2: Trek to Tungnath (3,680 meters), visiting the ancient Tungnath Temple, one of the highest Shiva temples in the world.", + "Day 3: Return trek to Chopta, with reflections on your experience and the serene beauty of the landscape.", + ], + attractions: [ + "Tungnath Temple, a significant pilgrimage site with deep spiritual resonance.", + "Mesmerizing views of the surrounding peaks, including Chaukamba and Neelkanth.", + "Lush green meadows and forests, providing a serene atmosphere for nature lovers.", + "Serenity and tranquility of the Himalayan landscape, perfect for meditation and relaxation.", + ], + culturalInsights: [ + "Learn about the local legends and traditions associated with the Tungnath Temple and its significance in Hindu mythology.", + "Interact with local villagers and experience their hospitality and unique way of life.", + ], + physicalChallenges: [ + "Moderate trek, suitable for beginners with a reasonable level of fitness; however, be prepared for steep sections.", + "Variable weather conditions, especially in early spring and late autumn, may require warm clothing and rain gear.", + ], + recommendedGear: [ + "Comfortable trekking shoes with good grip and support for the ascent.", + "Layered clothing to accommodate changes in temperature throughout the day.", + "Essential items like a daypack, water bottle, and a basic first-aid kit.", + ], + bestTimeToVisit: + "The best time for the Chopta to Tungnath trek is from April to June and September to November, when the weather is pleasant and the trails are clear.", + image: "https://trekiq.in/uploads/2021/04/Chandrashila-in-winters.jpg", + }, + { + title: "PANWALI KANTHA TREK", + difficultyLevel: "MODERATE", + altitude: 3075, + district: "TEHRI GARHWAL", + address: "Panwali Kantha, Tehri Garhwal, Uttarakhand, India", + coordinates: [30.7110, 78.6460], + introduction: + "The Panwali Kantha Trek is a serene journey that offers a perfect blend of lush greenery, stunning views, and rich cultural heritage. Nestled in the Garhwal Himalayas, this trek is ideal for beginners and nature lovers looking to escape into the wilderness. The path winds through quaint villages, dense forests, and breathtaking meadows, providing an immersive experience in the heart of Uttarakhand's natural beauty.", + overview: + "Covering approximately 36 kilometers, the Panwali Kantha Trek leads you to an altitude of 10,700 feet. The trek begins at the charming village of Kandikhal and ascends through thick oak forests and lush meadows. As you reach the summit, you are greeted with panoramic views of the Himalayan peaks and the enchanting landscapes of the region. The trek is dotted with local flora and fauna, making it a perfect spot for wildlife enthusiasts and photographers alike.", + route: [ + "Day 1: Drive to Kandikhal, the starting point, and acclimatize to the beautiful surroundings.", + "Day 2: Trek to Panwali Kantha (10,700 feet) through picturesque meadows and enjoy stunning views along the way.", + "Day 3: Explore the area, interact with local communities, and take in the serene beauty of the Himalayas before returning to Kandikhal.", + ], + attractions: [ + "Breathtaking views of the surrounding mountains and valleys, perfect for photography enthusiasts.", + "Rich biodiversity, including various species of flora and fauna unique to the region.", + "Cultural experiences with local villagers, offering insights into traditional Garhwali lifestyles.", + ], + culturalInsights: [ + "Engage with local families and learn about their daily lives, customs, and traditional practices.", + "Explore local temples and understand their significance in the cultural landscape of Uttarakhand.", + ], + physicalChallenges: [ + "Gentle ascents with some steep sections, making it suitable for beginner trekkers with moderate fitness levels.", + "Potentially unpredictable weather, especially in higher altitudes, necessitating preparedness.", + ], + recommendedGear: [ + "Comfortable trekking shoes, suitable for varied terrain and long walks.", + "Lightweight and breathable clothing for warm days, along with a warm jacket for cooler evenings.", + "A reliable backpack to carry essentials, along with a water bottle for hydration.", + ], + bestTimeToVisit: + "The best time to visit Panwali Kantha is from April to June and September to November, ensuring pleasant weather for trekking.", + image: + "https://uttarakhandtriptrek.com/wp-content/uploads/2019/03/Panwali-Kantha-Trek-Image.jpg", + }, + { + title: "DRONAGIRI TREK", + difficultyLevel: "MODERATE", + altitude: 6070, + district: "CHAMOLI", + address: "Dronagiri Peak, Chamoli, Uttarakhand, India", + coordinates: [30.3334, 80.1312], - introduction: - "The Dronagiri Trek takes you on an extraordinary journey to one of the lesser-known peaks of the Himalayas. It is renowned for its stunning landscapes and rich mythology associated with the Dronagiri mountain, believed to be where Hanuman fetched the Sanjeevani herb. This trek offers breathtaking views of the surrounding mountains and a unique adventure for trekkers.", - overview: - "Spanning around 45 kilometers, the Dronagiri Trek reaches an altitude of 19,918 feet. The journey begins at the village of Kanchoti and leads trekkers through lush forests, rocky terrains, and picturesque meadows. The trek is challenging yet rewarding, offering stunning vistas of snow-clad peaks and valleys as you approach the summit. This trek is perfect for experienced trekkers looking for an adventure in the heart of the Himalayas.", - route: [ - "Day 1: Drive to Kanchoti, the base camp, and acclimatize to the stunning views.", - "Day 2: Trek to Dronagiri Base Camp (16,500 feet) through lush forests and rocky terrains.", - "Day 3: Summit Dronagiri Peak (19,918 feet) and return to Base Camp.", - "Day 4: Descend back to Kanchoti, reflecting on the incredible journey.", - ], - attractions: [ - "Panoramic views of Nanda Devi, Kamet, and other prominent peaks of the Himalayas.", - "Rich flora and fauna, with unique species found in high-altitude regions.", - "Mythological significance of Dronagiri, making it a culturally enriching experience.", - ], - culturalInsights: [ - "Learn about the legends associated with Dronagiri and its significance in Hindu mythology.", - "Experience the local culture and traditions of the villages along the trek.", - ], - physicalChallenges: [ - "Steep ascents and rocky terrains require good stamina and physical fitness.", - "Altitude sickness may be a concern due to high elevations, necessitating acclimatization.", - ], - recommendedGear: [ - "High-quality trekking boots for challenging terrains and a good grip.", - "Layered clothing suitable for varying temperatures, along with a warm sleeping bag.", - "A sturdy backpack for carrying essentials, including hydration packs.", - ], - bestTimeToVisit: - "The ideal time for the Dronagiri Trek is from May to June and September to October, offering stable weather conditions.", - image: - "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTiWcyBC6dgDZKjp_xyCXjJSEEWd_XdnTrsAQ&s", - }, + introduction: + "The Dronagiri Trek takes you on an extraordinary journey to one of the lesser-known peaks of the Himalayas. It is renowned for its stunning landscapes and rich mythology associated with the Dronagiri mountain, believed to be where Hanuman fetched the Sanjeevani herb. This trek offers breathtaking views of the surrounding mountains and a unique adventure for trekkers.", + overview: + "Spanning around 45 kilometers, the Dronagiri Trek reaches an altitude of 19,918 feet. The journey begins at the village of Kanchoti and leads trekkers through lush forests, rocky terrains, and picturesque meadows. The trek is challenging yet rewarding, offering stunning vistas of snow-clad peaks and valleys as you approach the summit. This trek is perfect for experienced trekkers looking for an adventure in the heart of the Himalayas.", + route: [ + "Day 1: Drive to Kanchoti, the base camp, and acclimatize to the stunning views.", + "Day 2: Trek to Dronagiri Base Camp (16,500 feet) through lush forests and rocky terrains.", + "Day 3: Summit Dronagiri Peak (19,918 feet) and return to Base Camp.", + "Day 4: Descend back to Kanchoti, reflecting on the incredible journey.", + ], + attractions: [ + "Panoramic views of Nanda Devi, Kamet, and other prominent peaks of the Himalayas.", + "Rich flora and fauna, with unique species found in high-altitude regions.", + "Mythological significance of Dronagiri, making it a culturally enriching experience.", + ], + culturalInsights: [ + "Learn about the legends associated with Dronagiri and its significance in Hindu mythology.", + "Experience the local culture and traditions of the villages along the trek.", + ], + physicalChallenges: [ + "Steep ascents and rocky terrains require good stamina and physical fitness.", + "Altitude sickness may be a concern due to high elevations, necessitating acclimatization.", + ], + recommendedGear: [ + "High-quality trekking boots for challenging terrains and a good grip.", + "Layered clothing suitable for varying temperatures, along with a warm sleeping bag.", + "A sturdy backpack for carrying essentials, including hydration packs.", + ], + bestTimeToVisit: + "The ideal time for the Dronagiri Trek is from May to June and September to October, offering stable weather conditions.", + image: + "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTiWcyBC6dgDZKjp_xyCXjJSEEWd_XdnTrsAQ&s", + }, { - title: "CHANDRASHILA TREK", - difficultyLevel: "MODERATE", - altitude: 4000, - district: "RUDRAPRAYAG", - address: "Chandrashila Peak, Rudraprayag, Uttarakhand, India", - coordinates: [30.3238, 79.0745], - introduction: - "The Chandrashila Trek is a popular trek in the Garhwal region, offering trekkers the chance to reach the summit of Chandrashila, a peak revered in Hindu mythology. This trek is renowned for its breathtaking views of the Himalayas and provides a unique opportunity to witness the majestic beauty of the region, including the stunning sunrise from the summit.", - overview: - "Covering approximately 22 kilometers, the Chandrashila Trek takes trekkers to an altitude of 13,070 feet. The trek begins at Chopta, a small village known as the 'Mini Switzerland of India.' Trekkers will journey through lush meadows, dense forests, and rocky paths leading to the summit. The journey is rich in scenic beauty, offering stunning views of peaks like Nanda Devi, Trishul, and Chaukhamba from the top of Chandrashila.", - route: [ - "Day 1: Drive to Chopta and acclimatize while enjoying the surrounding beauty.", - "Day 2: Trek to Chandrashila (13,070 feet), experiencing stunning landscapes along the way.", - "Day 3: Enjoy the sunrise from the summit, capturing unforgettable memories.", - "Day 4: Descend back to Chopta, reflecting on the mesmerizing journey.", - ], - attractions: [ - "Breathtaking views of the Himalayan peaks, including Nanda Devi and Trishul.", - "Diverse flora and fauna, making it a treat for nature enthusiasts.", - "Cultural experiences at local villages along the trek.", - ], - culturalInsights: [ - "Learn about the legends associated with Chandrashila and its significance in Hindu culture.", - "Experience the warmth of local hospitality from villagers during the trek.", - ], - physicalChallenges: [ - "Moderate difficulty with some steep sections, making it suitable for moderately fit trekkers.", - "Weather conditions can change rapidly, so preparedness is key.", - ], - recommendedGear: [ - "Good-quality trekking boots for comfort and grip on rocky terrains.", - "Layered clothing suitable for fluctuating temperatures during the trek.", - "A sturdy backpack for carrying essentials, including snacks and hydration.", - ], - bestTimeToVisit: - "The best time for the Chandrashila Trek is from March to May and September to November, ensuring pleasant weather for trekking.", - image: - "https://media1.thrillophilia.com/filestore/vnxo50hgkek8ya56awjw92ok50rm_1513415035_Deoriatal-Chandrashila-Peak-trek-At-the-summit-Indiahikes.jpg", - }, + title: "CHANDRASHILA TREK", + difficultyLevel: "MODERATE", + altitude: 4000, + district: "RUDRAPRAYAG", + address: "Chandrashila Peak, Rudraprayag, Uttarakhand, India", + coordinates: [30.3238, 79.0745], + introduction: + "The Chandrashila Trek is a popular trek in the Garhwal region, offering trekkers the chance to reach the summit of Chandrashila, a peak revered in Hindu mythology. This trek is renowned for its breathtaking views of the Himalayas and provides a unique opportunity to witness the majestic beauty of the region, including the stunning sunrise from the summit.", + overview: + "Covering approximately 22 kilometers, the Chandrashila Trek takes trekkers to an altitude of 13,070 feet. The trek begins at Chopta, a small village known as the 'Mini Switzerland of India.' Trekkers will journey through lush meadows, dense forests, and rocky paths leading to the summit. The journey is rich in scenic beauty, offering stunning views of peaks like Nanda Devi, Trishul, and Chaukhamba from the top of Chandrashila.", + route: [ + "Day 1: Drive to Chopta and acclimatize while enjoying the surrounding beauty.", + "Day 2: Trek to Chandrashila (13,070 feet), experiencing stunning landscapes along the way.", + "Day 3: Enjoy the sunrise from the summit, capturing unforgettable memories.", + "Day 4: Descend back to Chopta, reflecting on the mesmerizing journey.", + ], + attractions: [ + "Breathtaking views of the Himalayan peaks, including Nanda Devi and Trishul.", + "Diverse flora and fauna, making it a treat for nature enthusiasts.", + "Cultural experiences at local villages along the trek.", + ], + culturalInsights: [ + "Learn about the legends associated with Chandrashila and its significance in Hindu culture.", + "Experience the warmth of local hospitality from villagers during the trek.", + ], + physicalChallenges: [ + "Moderate difficulty with some steep sections, making it suitable for moderately fit trekkers.", + "Weather conditions can change rapidly, so preparedness is key.", + ], + recommendedGear: [ + "Good-quality trekking boots for comfort and grip on rocky terrains.", + "Layered clothing suitable for fluctuating temperatures during the trek.", + "A sturdy backpack for carrying essentials, including snacks and hydration.", + ], + bestTimeToVisit: + "The best time for the Chandrashila Trek is from March to May and September to November, ensuring pleasant weather for trekking.", + image: + "https://media1.thrillophilia.com/filestore/vnxo50hgkek8ya56awjw92ok50rm_1513415035_Deoriatal-Chandrashila-Peak-trek-At-the-summit-Indiahikes.jpg", + }, - { - title: "NAG TIBBA TREK", - difficultyLevel: "EASY", - altitude: 3022, - district: "TEHRI GARHWAL", - address: "Nag Tibba, Tehri Garhwal, Uttarakhand, India", - coordinates: [30.4225, 78.4534], - introduction: - "The Nag Tibba Trek is an easy yet rewarding trek that takes you through lush green forests, quaint villages, and offers mesmerizing views of the Himalayas. Known as the 'Serpent's Peak,' this trek is perfect for beginners and families looking to explore the beauty of the Garhwal region in Uttarakhand.", - overview: - "Spanning approximately 20 kilometers, the Nag Tibba Trek reaches an altitude of 9,914 feet. The trek begins from the village of Pantwari and winds through picturesque landscapes, including dense oak and deodar forests. As you ascend, you'll be rewarded with breathtaking views of the surrounding mountains, including the majestic views of the Gangotri and Yamunotri ranges. The summit offers a serene atmosphere, perfect for camping and relaxation.", - route: [ - "Day 1: Drive to Pantwari and begin the trek towards Nag Tibba Base Camp.", - "Day 2: Summit Nag Tibba (9,914 feet) and enjoy the panoramic views.", - "Day 3: Descend back to Pantwari, reflecting on the beautiful journey.", - ], - attractions: [ - "Stunning views of the surrounding peaks and valleys, ideal for photography.", - "Rich biodiversity, with various flora and fauna found along the trail.", - "Cultural experiences in local villages, showcasing Garhwali traditions.", - ], - culturalInsights: [ - "Learn about the local folklore associated with Nag Tibba and its cultural significance.", - "Interact with local communities and experience their warm hospitality.", - ], - physicalChallenges: [ - "Easy trek, suitable for beginners and families with children.", - "Short steep sections may present minor challenges, but overall accessible.", - ], - recommendedGear: [ - "Comfortable trekking shoes for easy navigation and grip.", - "Light clothing suitable for warm weather, along with a warm layer for evenings.", - "A lightweight backpack for carrying essentials and snacks.", - ], - bestTimeToVisit: - "The best time for the Nag Tibba Trek is from March to June and September to November, ensuring pleasant weather.", - image: - "https://www.bikatadventures.com/images/BlogspotContents/BlogspotImageUrl3825.JPG", - }, + { + title: "NAG TIBBA TREK", + difficultyLevel: "EASY", + altitude: 3022, + district: "TEHRI GARHWAL", + address: "Nag Tibba, Tehri Garhwal, Uttarakhand, India", + coordinates: [30.4225, 78.4534], + introduction: + "The Nag Tibba Trek is an easy yet rewarding trek that takes you through lush green forests, quaint villages, and offers mesmerizing views of the Himalayas. Known as the 'Serpent's Peak,' this trek is perfect for beginners and families looking to explore the beauty of the Garhwal region in Uttarakhand.", + overview: + "Spanning approximately 20 kilometers, the Nag Tibba Trek reaches an altitude of 9,914 feet. The trek begins from the village of Pantwari and winds through picturesque landscapes, including dense oak and deodar forests. As you ascend, you'll be rewarded with breathtaking views of the surrounding mountains, including the majestic views of the Gangotri and Yamunotri ranges. The summit offers a serene atmosphere, perfect for camping and relaxation.", + route: [ + "Day 1: Drive to Pantwari and begin the trek towards Nag Tibba Base Camp.", + "Day 2: Summit Nag Tibba (9,914 feet) and enjoy the panoramic views.", + "Day 3: Descend back to Pantwari, reflecting on the beautiful journey.", + ], + attractions: [ + "Stunning views of the surrounding peaks and valleys, ideal for photography.", + "Rich biodiversity, with various flora and fauna found along the trail.", + "Cultural experiences in local villages, showcasing Garhwali traditions.", + ], + culturalInsights: [ + "Learn about the local folklore associated with Nag Tibba and its cultural significance.", + "Interact with local communities and experience their warm hospitality.", + ], + physicalChallenges: [ + "Easy trek, suitable for beginners and families with children.", + "Short steep sections may present minor challenges, but overall accessible.", + ], + recommendedGear: [ + "Comfortable trekking shoes for easy navigation and grip.", + "Light clothing suitable for warm weather, along with a warm layer for evenings.", + "A lightweight backpack for carrying essentials and snacks.", + ], + bestTimeToVisit: + "The best time for the Nag Tibba Trek is from March to June and September to November, ensuring pleasant weather.", + image: + "https://www.bikatadventures.com/images/BlogspotContents/BlogspotImageUrl3825.JPG", + }, - { - title: "KALINDI KHAL TREK", - difficultyLevel: "DIFFICULT", - altitude: 5950, - district: "CHAMOLI", - address: "Kalindi Khal, Chamoli, Uttarakhand, India", - coordinates: [30.3750, 78.7040], - introduction: - "The Kalindi Khal Trek is a thrilling adventure that connects the valleys of Bhagirathi and Alaknanda, offering breathtaking views of the Himalayan peaks. Known for its challenging terrains and high-altitude landscapes, this trek is suitable for experienced trekkers seeking a unique experience in the pristine wilderness of Uttarakhand.", - overview: - "Spanning approximately 80 kilometers, the Kalindi Khal Trek ascends to an altitude of 19,591 feet. The trek starts from Gangotri and takes trekkers through stunning glaciers, meadows, and rocky terrains. The highlight of this trek is the Kalindi Khal Pass, offering spectacular views of the surrounding peaks. The journey provides a perfect blend of adventure, beauty, and solitude, making it an unforgettable experience.", - route: [ - "Day 1: Drive to Gangotri and acclimatize while enjoying the views of the region.", - "Day 2: Trek to Bhoj Kharak, setting up camp amidst stunning landscapes.", - "Day 3: Continue to Kalindi Base Camp, preparing for the summit attempt.", - "Day 4: Summit Kalindi Khal and descend to the next campsite, soaking in the views.", - "Day 5: Trek back to Gangotri, reflecting on the incredible journey.", - ], - attractions: [ - "Stunning views of Bhagirathi peaks and other Himalayan ranges.", - "Challenging terrains that provide a sense of adventure and accomplishment.", - "Rich biodiversity and unique landscapes, perfect for nature lovers.", - ], - culturalInsights: [ - "Learn about the cultural significance of the region and its local traditions.", - "Experience the spiritual essence of the Himalayas while visiting sacred sites.", - ], - physicalChallenges: [ - "Difficult trek requiring good fitness and prior trekking experience.", - "High altitude can lead to altitude sickness, necessitating acclimatization.", - ], - recommendedGear: [ - "High-quality trekking boots for tough terrains and comfort.", - "Warm clothing suitable for extremely cold temperatures at higher altitudes.", - "A durable backpack for carrying essentials, including climbing gear.", - ], - bestTimeToVisit: - "The best time for the Kalindi Khal Trek is from late June to early September, ensuring better weather conditions.", - image: - "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRdKV_lPz1AKPYoEfTG8c4Jy91NNzir4P2S_g&s", - }, + { + title: "KALINDI KHAL TREK", + difficultyLevel: "DIFFICULT", + altitude: 5950, + district: "CHAMOLI", + address: "Kalindi Khal, Chamoli, Uttarakhand, India", + coordinates: [30.3750, 78.7040], + introduction: + "The Kalindi Khal Trek is a thrilling adventure that connects the valleys of Bhagirathi and Alaknanda, offering breathtaking views of the Himalayan peaks. Known for its challenging terrains and high-altitude landscapes, this trek is suitable for experienced trekkers seeking a unique experience in the pristine wilderness of Uttarakhand.", + overview: + "Spanning approximately 80 kilometers, the Kalindi Khal Trek ascends to an altitude of 19,591 feet. The trek starts from Gangotri and takes trekkers through stunning glaciers, meadows, and rocky terrains. The highlight of this trek is the Kalindi Khal Pass, offering spectacular views of the surrounding peaks. The journey provides a perfect blend of adventure, beauty, and solitude, making it an unforgettable experience.", + route: [ + "Day 1: Drive to Gangotri and acclimatize while enjoying the views of the region.", + "Day 2: Trek to Bhoj Kharak, setting up camp amidst stunning landscapes.", + "Day 3: Continue to Kalindi Base Camp, preparing for the summit attempt.", + "Day 4: Summit Kalindi Khal and descend to the next campsite, soaking in the views.", + "Day 5: Trek back to Gangotri, reflecting on the incredible journey.", + ], + attractions: [ + "Stunning views of Bhagirathi peaks and other Himalayan ranges.", + "Challenging terrains that provide a sense of adventure and accomplishment.", + "Rich biodiversity and unique landscapes, perfect for nature lovers.", + ], + culturalInsights: [ + "Learn about the cultural significance of the region and its local traditions.", + "Experience the spiritual essence of the Himalayas while visiting sacred sites.", + ], + physicalChallenges: [ + "Difficult trek requiring good fitness and prior trekking experience.", + "High altitude can lead to altitude sickness, necessitating acclimatization.", + ], + recommendedGear: [ + "High-quality trekking boots for tough terrains and comfort.", + "Warm clothing suitable for extremely cold temperatures at higher altitudes.", + "A durable backpack for carrying essentials, including climbing gear.", + ], + bestTimeToVisit: + "The best time for the Kalindi Khal Trek is from late June to early September, ensuring better weather conditions.", + image: + "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRdKV_lPz1AKPYoEfTG8c4Jy91NNzir4P2S_g&s", + }, ]; diff --git a/src/app/trekking/page.module.css b/src/app/trekking/page.module.css index 27a3391..7dad553 100644 --- a/src/app/trekking/page.module.css +++ b/src/app/trekking/page.module.css @@ -1,17 +1,17 @@ -.page-header{ +.page-header { margin-top: 10px; /*width: 99%;*/ width: 100%; } -.hero-section{ +.hero-section { display: flex; flex-direction: row; align-items: center; justify-content: space-evenly; } -.text-container{ +.text-container { text-align: center; } @@ -30,15 +30,13 @@ letter-spacing: 2px; } -.img-container > img{ +.img-container > img { filter: drop-shadow(0 0 0.60rem #A0A5AC); } - - -.card-container{ +.card-container { width: 95%; display: flex; flex-direction: column; @@ -47,23 +45,6 @@ } - - - - - - - - - - - - - - - - - .search-section { width: 100%; display: flex; @@ -99,7 +80,6 @@ } - .item > select { border: none; letter-spacing: 1px; @@ -112,64 +92,26 @@ } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* Mobile */ @media (max-width: 700px) { - .hero-section{ + .hero-section { flex-direction: column-reverse; gap: 20px; } - .page-header{ + + .page-header { /*margin-top: 30px;*/ height: 100vh; } - .img-container > img{ + + .img-container > img { width: 200px; height: 217px; filter: drop-shadow(0 0 0.80rem #A0A5AC); } + .search-section { margin: 5rem 0 0 0; } @@ -186,7 +128,7 @@ letter-spacing: 1px; } - .card-container{ + .card-container { width: 100%; } } @@ -194,11 +136,12 @@ /* Tablet and Smaller Desktop */ @media (min-width: 701px) and (max-width: 1120px) { - .page-header{ + .page-header { margin-top: 40px; width: 99%; } - .img-container > img{ + + .img-container > img { width: 250px; height: 271px; } diff --git a/src/app/trekking/page.tsx b/src/app/trekking/page.tsx index f9e6920..16f1e8c 100644 --- a/src/app/trekking/page.tsx +++ b/src/app/trekking/page.tsx @@ -3,8 +3,8 @@ import styles from "./page.module.css"; import Image from "next/image"; import TrekCard from "@/components/ui/TrekCard"; import TrekkingHeroImage from "/public/heroImage.png"; -import { trekDetails } from './location-detail'; -import { useState } from "react"; +import {trekDetails} from './location-detail'; +import {useState} from "react"; export default function Trekking() { const [difficultyLevel, setDifficultyLevel] = useState(""); @@ -19,12 +19,12 @@ export default function Trekking() { }; // Extract unique districts from trekDetails - + const filterTreks = trekDetails.filter(trek => { const matchesDifficulty = difficultyLevel === "" || trek.difficultyLevel.toLowerCase() === difficultyLevel.toLowerCase(); const matchesDistrict = district === "" || trek.district.toLowerCase() === district.toLowerCase(); - + let matchesAltitude = true; // Default to true (not filtering) if (altitude) { // Define altitude ranges for filtering @@ -49,17 +49,18 @@ export default function Trekking() {

EXPLORE HIDDEN PLACES IN UTTARAKHAND

- TREKKING + TREKKING
-
-
-
-
-
); }; diff --git a/src/components/Screen.tsx b/src/components/Screen.tsx deleted file mode 100644 index e192a0d..0000000 --- a/src/components/Screen.tsx +++ /dev/null @@ -1,29 +0,0 @@ -// "use client"; -// -// import { useState, useEffect } from 'react'; -// -// const ScreenWidth: React.FC = () => { -// const [screenWidth, setScreenWidth] = useState(0); -// -// useEffect(() => { -// // Function to update the screen width -// const updateWidth = () => setScreenWidth(window.innerWidth); -// -// // Set the initial width -// updateWidth(); -// -// // Add event listener to track window resize -// window.addEventListener('resize', updateWidth); -// -// // Cleanup event listener on component unmount -// return () => window.removeEventListener('resize', updateWidth); -// }, []); -// -// return ( -//
-//

Screen Width: {screenWidth}px

-//
-// ); -// }; -// -// export default ScreenWidth; diff --git a/src/components/about/About.css b/src/components/about/About.css index be53eb8..9089ade 100644 --- a/src/components/about/About.css +++ b/src/components/about/About.css @@ -42,7 +42,7 @@ .section-content { flex: 1; - font-size:x-large; + font-size: x-large; margin: 10px; padding: 10px; } @@ -53,10 +53,11 @@ border-radius: 12px; object-fit: cover; } -.section-content p{ + +.section-content p { color: #11181f; font-size: large; - line-height:30px; + line-height: 30px; margin-top: 20px; } diff --git a/src/components/about/About.tsx b/src/components/about/About.tsx index f8a8f0b..4eb547e 100644 --- a/src/components/about/About.tsx +++ b/src/components/about/About.tsx @@ -2,108 +2,108 @@ import React from "react"; import "./About.css"; const AboutUs: React.FC = () => { - return ( -
- {/* Hero Section */} -
-
-

Welcome to the Uttarakhand Culture Preservation Project

-

- Explore and preserve the cultural richness of Uttarakhand with us. - We provide a digital platform to share the traditions, history, and - natural beauty of the region, making it accessible for everyone. -

-
-
+ return ( +
+ {/* Hero Section */} +
+
+

Welcome to the Uttarakhand Culture Preservation Project

+

+ Explore and preserve the cultural richness of Uttarakhand with us. + We provide a digital platform to share the traditions, history, and + natural beauty of the region, making it accessible for everyone. +

+
+
- {/* Problem Section */} -
- Cultural heritage issue -
-

The Problem

-

- Uttarakhand{"'"}s cultural heritage is at risk of being forgotten - as younger generations move away from their roots. If not preserved, - these traditions might disappear, leaving future generations without - a connection to their past. -

-
-
+ {/* Problem Section */} +
+ Cultural heritage issue +
+

The Problem

+

+ Uttarakhand{"'"}s cultural heritage is at risk of being forgotten + as younger generations move away from their roots. If not preserved, + these traditions might disappear, leaving future generations without + a connection to their past. +

+
+
- {/* Solution Section */} -
-
-

Our Solution

-

- We digitize Uttarakhand’s cultural knowledge to ensure it’s - preserved and passed down. By leveraging technology, we make it easy - for the younger generation to access, learn, and engage with their - rich heritage. -

-
- Digital platform -
+ {/* Solution Section */} +
+
+

Our Solution

+

+ We digitize Uttarakhand’s cultural knowledge to ensure it’s + preserved and passed down. By leveraging technology, we make it easy + for the younger generation to access, learn, and engage with their + rich heritage. +

+
+ Digital platform +
- {/* Discover Section */} -
-

Discover Uttarakhand’s Cultural Wealth

-
    -
  • - Language: Kumaoni, Garhwali, Jaunsari -
  • -
  • - Cultural Stories: Historical kings, famous - personalities -
  • -
  • - History: Uttarakhand’s past, movements, and leaders -
  • -
  • - Spiritual Heritage: Temples, deities, architectural - wonders -
  • -
  • - Cuisine: Authentic recipes and traditional methods -
  • -
  • - Festivals & Events: Upcoming cultural festivals and - fairs -
  • -
  • - Art & Craft: Traditional art, handicrafts, and - artisans -
  • -
  • - Music & Dance: Regional music, instruments, and - dances -
  • -
  • - Nature: Flora, fauna, rivers, mountains -
  • -
-
+ {/* Discover Section */} +
+

Discover Uttarakhand’s Cultural Wealth

+
    +
  • + Language: Kumaoni, Garhwali, Jaunsari +
  • +
  • + Cultural Stories: Historical kings, famous + personalities +
  • +
  • + History: Uttarakhand’s past, movements, and leaders +
  • +
  • + Spiritual Heritage: Temples, deities, architectural + wonders +
  • +
  • + Cuisine: Authentic recipes and traditional methods +
  • +
  • + Festivals & Events: Upcoming cultural festivals and + fairs +
  • +
  • + Art & Craft: Traditional art, handicrafts, and + artisans +
  • +
  • + Music & Dance: Regional music, instruments, and + dances +
  • +
  • + Nature: Flora, fauna, rivers, mountains +
  • +
+
- {/* User-Suggested Features Section */} -
-
-

Your Voice Matters

-

- Have a suggestion for our platform? Send us an email or submit a - feature idea, and we’ll consider incorporating it to enhance our - platform. -

+ {/* User-Suggested Features Section */} +
+
+

Your Voice Matters

+

+ Have a suggestion for our platform? Send us an email or submit a + feature idea, and we’ll consider incorporating it to enhance our + platform. +

+
+
-
-
- ); + ); }; export default AboutUs; diff --git a/src/components/ui/Card.module.css b/src/components/ui/Card.module.css index e0e19de..b958fe7 100644 --- a/src/components/ui/Card.module.css +++ b/src/components/ui/Card.module.css @@ -1,4 +1,4 @@ -.card{ +.card { display: flex; flex-direction: row; justify-content: space-between; @@ -9,15 +9,16 @@ margin-top: 4rem; } -.title{ +.title { /*font-size: 2em;*/ } -.subTitle{ +.subTitle { margin-top: 0.5rem; letter-spacing: 1px; } -.description{ + +.description { margin-top: 1rem; font-size: 13px; color: var(--black); @@ -32,24 +33,27 @@ } -.link-container{ +.link-container { display: flex; flex-direction: row; margin-top: 1.5rem; } -.link-container > div{ +.link-container > div { border-top: 1px solid #E1E4E8; padding: 3px 10px 1px 10px; } -.link-container1{ + +.link-container1 { border-right: 1px solid #E1E4E8; } -.link-container2{ + +.link-container2 { } -.link-container > div > a{ + +.link-container > div > a { text-align: center; color: var(--grey); font-size: 12px; @@ -80,21 +84,21 @@ transform: scale(1, 1); } -.link-container > div:hover > a{ +.link-container > div:hover > a { color: var(--black); filter: drop-shadow(0 0 0.90rem #A0A5AC); } - -.image-container{ +.image-container { margin-left: 2rem; width: 100%; display: flex; flex-direction: row; justify-content: flex-end; } -.image-container > img{ + +.image-container > img { width: auto; max-width: 250px; @@ -105,33 +109,33 @@ } - /* Mobile */ @media (max-width: 700px) { - .card{ + .card { width: 96%; padding-top: 3rem; margin-top: 3rem; } - .subTitle{ + .subTitle { font-weight: 300; } - .title{ + .title { font-size: 20px; } - .image-container{ + .image-container { display: none; } - .image-container > img{ + + .image-container > img { width: 100px; height: 100%; } - .link-container > div > a{ + .link-container > div > a { font-size: 10px; } } \ No newline at end of file diff --git a/src/components/ui/Card.tsx b/src/components/ui/Card.tsx index 7c4025a..28650a2 100644 --- a/src/components/ui/Card.tsx +++ b/src/components/ui/Card.tsx @@ -13,19 +13,20 @@ type CardProps = { } export default function Card(props: CardProps) { - return( + return (
-
+

{props.title}

{props.subTitle}

{props.description}

-
READ MORE
-
VIEW LOCATION
+
READ MORE
+
VIEW LOCATION
-
- {""} +
+ {""}
); diff --git a/src/components/ui/DropDownMenu.module.css b/src/components/ui/DropDownMenu.module.css index 2ffa093..9c9a383 100644 --- a/src/components/ui/DropDownMenu.module.css +++ b/src/components/ui/DropDownMenu.module.css @@ -1,4 +1,4 @@ -.dropdown-menu-container{ +.dropdown-menu-container { display: none; } @@ -8,10 +8,7 @@ } - - - -.search-section{ +.search-section { width: 100%; display: flex; justify-content: center; @@ -20,7 +17,7 @@ } -.search-container{ +.search-container { width: 500px; height: 40px; min-width: 300px; @@ -33,18 +30,18 @@ border: 1px solid #E1E4E8; } -.item{ +.item { display: flex; flex-direction: row; align-items: center; } -.item > p{ +.item > p { color: var(--black); } -.card-container{ +.card-container { width: 100%; display: flex; flex-direction: column; diff --git a/src/components/ui/DropDownMenu.tsx b/src/components/ui/DropDownMenu.tsx index 959a33d..af977e4 100644 --- a/src/components/ui/DropDownMenu.tsx +++ b/src/components/ui/DropDownMenu.tsx @@ -1,11 +1,11 @@ import styles from "./DropDownMenu.module.css"; type DropDownMenuProps = { - title : string, + title: string, } export default function DropDownMenu(props: DropDownMenuProps) { - return( + return ( <>
diff --git a/src/components/ui/FestivalCard.module.css b/src/components/ui/FestivalCard.module.css index 5ab0bc7..6357c49 100644 --- a/src/components/ui/FestivalCard.module.css +++ b/src/components/ui/FestivalCard.module.css @@ -8,7 +8,7 @@ margin-top: 3rem; } -.festival-card > div{ +.festival-card > div { display: flex; flex-direction: row; justify-content: space-between; @@ -17,7 +17,7 @@ padding-top: 3rem; } -.fair-card > div{ +.fair-card > div { display: flex; flex-direction: row; justify-content: space-between; @@ -26,15 +26,16 @@ padding-top: 3rem; } -.title{ +.title { /*font-size: 2em;*/ } -.subTitle{ +.subTitle { margin-top: 0.5rem; letter-spacing: 1px; } -.description{ + +.description { margin-top: 1rem; font-size: 13px; color: var(--black); @@ -49,24 +50,27 @@ } -.link-container{ +.link-container { display: flex; flex-direction: row; margin-top: 1.5rem; } -.link-container > div{ +.link-container > div { border-top: 1px solid #E1E4E8; padding: 3px 10px 1px 10px; } -.link-container1{ + +.link-container1 { /*border-right: 1px solid #E1E4E8;*/ } -.link-container2{ + +.link-container2 { border-left: 1px solid #E1E4E8; } -.link-container > div > a{ + +.link-container > div > a { text-align: center; color: var(--grey); font-size: 12px; @@ -97,21 +101,21 @@ transform: scale(1, 1); } -.link-container > div:hover > a{ +.link-container > div:hover > a { color: var(--black); filter: drop-shadow(0 0 0.90rem #A0A5AC); } - -.image-container{ +.image-container { margin-left: 2rem; width: 100%; display: flex; flex-direction: row; justify-content: flex-end; } -.image-container > img{ + +.image-container > img { width: auto; max-width: 250px; @@ -120,7 +124,6 @@ } - /* Mobile */ @media (max-width: 700px) { @@ -129,8 +132,7 @@ /* padding-top: 3rem;*/ /* margin-top: 3rem;*/ /*}*/ - - .festival-card { + .festival-card { border-top: 1px solid var(--line-grey); margin-top: 8rem; } @@ -141,40 +143,39 @@ } - .festival-card > div{ + .festival-card > div { flex-direction: column-reverse !important; justify-content: space-between; } - .fair-card > div{ + .fair-card > div { flex-direction: column-reverse !important; justify-content: space-between; } - - - .subTitle{ + .subTitle { font-weight: 300; } - .title{ + .title { font-size: 20px; } - .image-container{ + .image-container { margin-left: 0; width: 100%; margin-bottom: 1rem; } - .image-container > img{ + + .image-container > img { width: auto; max-width: 250px; height: auto; border-radius: 5px; } - .image-container > img{ + .image-container > img { /*width: 100px;*/ /*height: 100%;*/ @@ -183,7 +184,7 @@ height: auto; } - .link-container > div > a{ + .link-container > div > a { font-size: 10px; } } \ No newline at end of file diff --git a/src/components/ui/FestivalCard.tsx b/src/components/ui/FestivalCard.tsx index 772b846..b825f37 100644 --- a/src/components/ui/FestivalCard.tsx +++ b/src/components/ui/FestivalCard.tsx @@ -2,7 +2,6 @@ import styles from "./FestivalCard.module.css" import Link from "next/link"; import Image from "next/image"; import GheeSankranti from "/public/Ghee_Sankranti.jpeg" -import Bagwal from "/public/bagwal.jpg" import Nanda_Sunanda from "/public/Nanda-Sunanda.webp" export default function FestivalCard() { @@ -49,7 +48,14 @@ export default function FestivalCard() {

8 SEPTEMBER - 19 SEPTEMBER · NAINITAL

- The Nanda Devi Mahotsav is a grand celebration dedicated to Goddess Nanda Devi, the revered deity of the Kumaon region. This vibrant festival, which takes place annually in Nainital, is deeply ingrained in the cultural fabric of Uttarakhand. It is believed to have started centuries ago to honor Nanda Devi, who is considered the protector of the region. The festival is marked by colorful processions, traditional dance performances, and rituals that attract devotees and tourists alike. The highlight of the event is the ‘Nanda Jaat Yatra,’ where a grand procession of devotees carries a palanquin of the goddess through the scenic landscapes of Uttarakhand, symbolizing her journey to her maternal home.

+ The Nanda Devi Mahotsav is a grand celebration dedicated to Goddess Nanda Devi, the revered + deity of the Kumaon region. This vibrant festival, which takes place annually in Nainital, + is deeply ingrained in the cultural fabric of Uttarakhand. It is believed to have started + centuries ago to honor Nanda Devi, who is considered the protector of the region. The + festival is marked by colorful processions, traditional dance performances, and rituals that + attract devotees and tourists alike. The highlight of the event is the ‘Nanda Jaat Yatra,’ + where a grand procession of devotees carries a palanquin of the goddess through the scenic + landscapes of Uttarakhand, symbolizing her journey to her maternal home.

READ MORE
diff --git a/src/components/ui/Footer.module.css b/src/components/ui/Footer.module.css index fa95a07..a49aec9 100644 --- a/src/components/ui/Footer.module.css +++ b/src/components/ui/Footer.module.css @@ -1,4 +1,4 @@ -.footer-container{ +.footer-container { margin-top: 15rem; margin-bottom: 1rem; padding-top: 2rem; @@ -27,9 +27,7 @@ /*}*/ - - -.newsletter-container{ +.newsletter-container { max-width: 1200px; /* 980 at 1280px*/ width: 100%; @@ -57,13 +55,15 @@ font-size: 28px; margin-bottom: 1rem; } + .newsletter-right-container > .newsletter-email-container > form { display: flex; flex-direction: row; gap: 1rem; margin-bottom: 1rem; } -.newsletter-right-container > .newsletter-email-container > form > input{ + +.newsletter-right-container > .newsletter-email-container > form > input { width: 100%; max-width: 250px; height: 3rem; @@ -75,7 +75,7 @@ outline: none; } -.newsletter-right-container > .newsletter-email-container > form > p{ +.newsletter-right-container > .newsletter-email-container > form > p { color: white; height: 3rem; font-size: 1rem; @@ -84,24 +84,24 @@ border-radius: 5px; background-color: var(--black); - box-shadow: 0 .7065919983928324px .7065919983928324px -.625px #00000026,0 1.8065619053231785px 1.8065619053231785px -1.25px #00000025,0 3.6217592146567767px 3.6217592146567767px -1.875px #00000023,0 6.8655999097303715px 6.8655999097303715px -2.5px #00000020,0 13.646761411524492px 13.646761411524492px -3.125px #0000001b,0 30px 30px -3.75px #0000000d; + box-shadow: 0 .7065919983928324px .7065919983928324px -.625px #00000026, 0 1.8065619053231785px 1.8065619053231785px -1.25px #00000025, 0 3.6217592146567767px 3.6217592146567767px -1.875px #00000023, 0 6.8655999097303715px 6.8655999097303715px -2.5px #00000020, 0 13.646761411524492px 13.646761411524492px -3.125px #0000001b, 0 30px 30px -3.75px #0000000d; } -.newsletter-right-container > .newsletter-email-container > form > p:hover{ + +.newsletter-right-container > .newsletter-email-container > form > p:hover { background-color: var(--slate-black); cursor: pointer; } - - -.footer{ +.footer { display: flex; flex-direction: row; justify-content: space-between; max-width: 1200px; width: 100%; } -.footer-right-container{ + +.footer-right-container { display: flex; flex-direction: row; justify-content: space-between; @@ -111,7 +111,8 @@ padding: 0 4rem 0 4rem; } -.footer-right-link-container{ + +.footer-right-link-container { display: flex; flex-direction: column; justify-content: space-between; @@ -119,7 +120,7 @@ text-align: left; } -.footer-left-container{ +.footer-left-container { text-align: left; max-width: 600px; width: 100%; @@ -130,6 +131,7 @@ color: var(--black); letter-spacing: 2px; } + .footer-right-link-container > p { color: var(--black); font-weight: 600; @@ -164,34 +166,36 @@ .footer-right-link-container > a:hover::after { transform: scale(1, 1); } + .footer-right-link-container > a:hover { - color: var(--black); - filter: drop-shadow(0 0 0.90rem #A0A5AC); - } + color: var(--black); + filter: drop-shadow(0 0 0.90rem #A0A5AC); +} -.copyright-container{ +.copyright-container { border-top: 1px solid var(--line-grey); margin-top: 5rem; max-width: 1200px; width: 100%; } -.copyright-container > p{ +.copyright-container > p { margin: 2rem 0 1rem 0; color: var(--black); } @media (max-width: 1000px) { - .newsletter-container{ + .newsletter-container { padding: 4rem 2rem 4rem 2rem; gap: 5px; } - .newsletter-right-container > .newsletter-email-container > form > p{ + .newsletter-right-container > .newsletter-email-container > form > p { padding: 10px 15px 10px 15px; } + .newsletter-right-container > .newsletter-email-container > form { gap: 0.5rem; } @@ -199,7 +203,7 @@ @media (max-width: 699px) { - .newsletter-container{ + .newsletter-container { padding: 4rem 1rem 4rem 1rem; flex-direction: column; gap: 3rem; @@ -207,10 +211,11 @@ align-items: flex-start; } - .newsletter-right-container > .newsletter-email-container > form > input{ + .newsletter-right-container > .newsletter-email-container > form > input { padding: 10px 15px 10px 15px; } - .footer-right-container{ + + .footer-right-container { max-width: 500px; width: 100%; padding: 0 0.5rem 0 2rem; @@ -223,32 +228,24 @@ } @media (max-width: 499px) { - .footer{ + .footer { flex-direction: column; gap: 2rem; } - .footer-left-container > h2{ + + .footer-left-container > h2 { text-align: center; } - .footer-right-container{ + .footer-right-container { padding: 0 2rem 0 2rem; } } - - - - - - - - - /* */ -.notify-early-container{ +.notify-early-container { } @@ -258,7 +255,7 @@ } -#notify-early-image{ +#notify-early-image { width: 100%; height: auto; } \ No newline at end of file diff --git a/src/components/ui/Footer.tsx b/src/components/ui/Footer.tsx index 58ade76..5471c2e 100644 --- a/src/components/ui/Footer.tsx +++ b/src/components/ui/Footer.tsx @@ -14,7 +14,8 @@ export default function Footer() {
- +

Subscribe

@@ -31,13 +32,14 @@ export default function Footer() {
-
+

Socials

- LinkedIn + LinkedIn Github Contact us
-
+

Contribution

Issues About us diff --git a/src/components/ui/InfoItem.module.css b/src/components/ui/InfoItem.module.css index 3a10ff9..cc9ec0e 100644 --- a/src/components/ui/InfoItem.module.css +++ b/src/components/ui/InfoItem.module.css @@ -1,4 +1,4 @@ -.language-importance-item{ +.language-importance-item { /*width: 48%;*/ flex: 1 1 calc(50% - 1rem); margin-bottom: 1rem; diff --git a/src/components/ui/InfoItem.tsx b/src/components/ui/InfoItem.tsx index 5f0f7d7..bcb72fe 100644 --- a/src/components/ui/InfoItem.tsx +++ b/src/components/ui/InfoItem.tsx @@ -1,4 +1,3 @@ -import Link from "next/link"; import styles from "./InfoItem.module.css"; type CardProps = { diff --git a/src/components/ui/MapModal.module.css b/src/components/ui/MapModal.module.css index 722b1dc..e374754 100644 --- a/src/components/ui/MapModal.module.css +++ b/src/components/ui/MapModal.module.css @@ -1,72 +1,72 @@ .modalOverlay { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: rgba(0, 0, 0, 0.5); - display: flex; - justify-content: center; - align-items: center; - z-index: 50; /* Lower than navbar */ + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + justify-content: center; + align-items: center; + z-index: 50; /* Lower than navbar */ } - + .modalContent { - display: flex; - width: 80%; - max-width: 900px; - background-color: white; - border-radius: 8px; - overflow: hidden; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); - transform: translateY(calc(var(--navbar-height, 50px) + 10px)); /* Adjust height as necessary */ + display: flex; + width: 80%; + max-width: 900px; + background-color: white; + border-radius: 8px; + overflow: hidden; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); + transform: translateY(calc(var(--navbar-height, 50px) + 10px)); /* Adjust height as necessary */ } - - .leftColumn { + +.leftColumn { width: 90%; position: relative; display: flex; flex-direction: column; justify-content: center; - } - - .mapContainer { +} + +.mapContainer { width: 100%; height: 100%; /* Ensures the map fills the entire left column */ min-height: 400px; /* A minimum height to prevent collapsing */ position: relative; - } - - .rightColumn { +} + +.rightColumn { width: fit-content; padding: 16px; display: flex; flex-direction: column; justify-content: space-between; - } - - - .subTitle{ +} + + +.subTitle { width: fit-content; - } - - .imageSection { +} + +.imageSection { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; width: fit-content; - } - - .imageSection img { +} + +.imageSection img { width: 250px; height: auto; border-radius: 4px; object-fit: cover; - } - - .closeButton { +} + +.closeButton { margin-top: 16px; padding: 8px 16px; background-color: #333; @@ -75,19 +75,20 @@ border-radius: 4px; cursor: pointer; background-color: #333; - } - .closeButton:hover{ +} + +.closeButton:hover { background-color: black; - } - - .mapLinks { +} + +.mapLinks { margin-top: 10px; gap: 2px; display: flex; justify-content: space-between; - } - - .mapLinks a { +} + +.mapLinks a { white-space: nowrap; color: white; background-color: #333; @@ -97,54 +98,56 @@ text-align: center; border-radius: 4px; font-weight: 500; - } - - .mapLinks a:hover { +} + +.mapLinks a:hover { background-color: black; - } - .mapLinks .icon { +} + +.mapLinks .icon { position: relative; display: inline-flex; margin-right: 2px; top: 2px; - } - @media (max-width: 768px) { +} + +@media (max-width: 768px) { .modalContent { - flex-direction: column; /* Stack columns vertically */ - width: 80%; /* Full width on mobile */ - max-height: 80%; /* Prevent the modal from exceeding the viewport */ - overflow-y: auto; /* Enable vertical scrolling */ - + flex-direction: column; /* Stack columns vertically */ + width: 80%; /* Full width on mobile */ + max-height: 80%; /* Prevent the modal from exceeding the viewport */ + overflow-y: auto; /* Enable vertical scrolling */ + } - + .leftColumn, .rightColumn { - width: 100%; /* Full width for both columns */ - padding: 12px; /* Adjust padding for mobile */ + width: 100%; /* Full width for both columns */ + padding: 12px; /* Adjust padding for mobile */ } - + .mapContainer { - min-height: 200px; /* Reduce minimum height for mobile */ - flex-grow: 1; /* Allow the map container to grow and take available space */ + min-height: 200px; /* Reduce minimum height for mobile */ + flex-grow: 1; /* Allow the map container to grow and take available space */ } - + .imageSection img { - width: 100%; /* Full width for images on mobile */ - height: auto; /* Maintain aspect ratio */ + width: 100%; /* Full width for images on mobile */ + height: auto; /* Maintain aspect ratio */ } - + .closeButton { - margin-top: 12px; /* Adjust margin for mobile */ - width: 100%; /* Full width for button */ + margin-top: 12px; /* Adjust margin for mobile */ + width: 100%; /* Full width for button */ } - + .mapLinks { - flex-direction: column; /* Stack links vertically */ - gap: 8px; /* Add spacing between links */ + flex-direction: column; /* Stack links vertically */ + gap: 8px; /* Add spacing between links */ } - + .mapLinks a { - width: 100%; /* Full width for each link */ - text-align: center; /* Center text for links */ + width: 100%; /* Full width for each link */ + text-align: center; /* Center text for links */ } - } \ No newline at end of file +} \ No newline at end of file diff --git a/src/components/ui/MapModal.tsx b/src/components/ui/MapModal.tsx index 0956c15..11881ae 100644 --- a/src/components/ui/MapModal.tsx +++ b/src/components/ui/MapModal.tsx @@ -1,108 +1,145 @@ // components/MapModal.tsx -import React, { useRef, useEffect } from 'react'; +import React, {useEffect, useRef} from 'react'; import mapboxgl from 'mapbox-gl'; import styles from './MapModal.module.css'; import 'mapbox-gl/dist/mapbox-gl.css'; +// Define the TrekDetails type with image as an array of strings +import {TrekDetails} from '../ui/TrekCard'; // Ensure Mapbox token is defined if (!process.env.NEXT_PUBLIC_MAPBOX_TOKEN) { - throw new Error("Mapbox access token is not defined. Please set NEXT_PUBLIC_MAPBOX_TOKEN in your environment variables."); + throw new Error("Mapbox access token is not defined. Please set NEXT_PUBLIC_MAPBOX_TOKEN in your environment variables."); } mapboxgl.accessToken = process.env.NEXT_PUBLIC_MAPBOX_TOKEN; -// Define the TrekDetails type with image as an array of strings -import { TrekDetails } from '../ui/TrekCard'; - // Define the props interface, including `info` as a prop of type TrekDetails interface MapModalProps { - isOpen: boolean; - onClose: () => void; - center?: number[]; - zoom?: number; - markerLocation?: number[]; - info: TrekDetails; - subTitle : string; + isOpen: boolean; + onClose: () => void; + center?: number[]; + zoom?: number; + markerLocation?: number[]; + info: TrekDetails; + subTitle: string; } const MapModal: React.FC = ({ - isOpen, - onClose, - center = [78.9629, 20.5937], - zoom = 5, - markerLocation = [78.9629, 20.5937], - info, - subTitle -}) => { - const mapContainerRef = useRef(null); - const mapRef = useRef(null); + isOpen, + onClose, + center = [78.9629, 20.5937], + zoom = 5, + markerLocation = [78.9629, 20.5937], + info, + subTitle + }) => { + const mapContainerRef = useRef(null); + const mapRef = useRef(null); - useEffect(() => { - if (isOpen && mapContainerRef.current) { - mapRef.current = new mapboxgl.Map({ - container: mapContainerRef.current, - style: 'mapbox://styles/mapbox/streets-v11', - center: [center[1], center[0]], - zoom: zoom, - }); + useEffect(() => { + if (isOpen && mapContainerRef.current) { + mapRef.current = new mapboxgl.Map({ + container: mapContainerRef.current, + style: 'mapbox://styles/mapbox/streets-v11', + center: [center[1], center[0]], + zoom: zoom, + }); - // Add the marker to the specified location - new mapboxgl.Marker() - .setLngLat([markerLocation[1], markerLocation[0]]) - .addTo(mapRef.current); + // Add the marker to the specified location + new mapboxgl.Marker() + .setLngLat([markerLocation[1], markerLocation[0]]) + .addTo(mapRef.current); - return () => mapRef.current?.remove(); - } - }, [isOpen, center, zoom, markerLocation]); + return () => mapRef.current?.remove(); + } + }, [isOpen, center, zoom, markerLocation]); - if (!isOpen) return null; + if (!isOpen) return null; - // URLs for Google Maps and Apple Maps - const googleMapsUrl = `https://www.google.com/maps?q=${center[0]},${center[1]}`; - const appleMapsUrl = `https://maps.apple.com/?ll=${center[0]},${center[1]}`; + // URLs for Google Maps and Apple Maps + const googleMapsUrl = `https://www.google.com/maps?q=${center[0]},${center[1]}`; + const appleMapsUrl = `https://maps.apple.com/?ll=${center[0]},${center[1]}`; - return ( -
-
e.stopPropagation()}> -
-
-
- - ); + ); }; export default MapModal; diff --git a/src/components/ui/Proverbs.module.css b/src/components/ui/Proverbs.module.css index 00625b3..fddb56a 100644 --- a/src/components/ui/Proverbs.module.css +++ b/src/components/ui/Proverbs.module.css @@ -3,14 +3,14 @@ width: 100%; } -.sectionCardTitle{ +.sectionCardTitle { display: flex; flex-direction: column; align-items: center; justify-content: center; } -.sectionCardTitleLine{ +.sectionCardTitleLine { position: absolute; border-top: 1px solid var(--line-grey); width: 95%; @@ -47,12 +47,14 @@ font-weight: 500; text-align: center; } -.englishTextContainer> p { + +.englishTextContainer > p { color: var(--black); font-size: 18px; font-weight: 500; text-align: center; } + .meaningTextContainer > p { color: var(--slate-black); font-size: 16px; @@ -61,11 +63,10 @@ } - /* Mobile */ @media (max-width: 700px) { - .sectionCardContainer { + .sectionCardContainer { margin-top: 5rem; } diff --git a/src/components/ui/Proverbs.tsx b/src/components/ui/Proverbs.tsx index 8cb9c85..8a43a47 100644 --- a/src/components/ui/Proverbs.tsx +++ b/src/components/ui/Proverbs.tsx @@ -3,13 +3,13 @@ import Style from "./Proverbs.module.css"; import {getRandomProverb} from "@/utils/proverbs"; type ProverbProps = { - hindi:String, + hindi: String, english: string, meaning?: String } -const Proverbs = ()=> { - const Proverb = getRandomProverb(); +const Proverbs = () => { + const Proverb = getRandomProverb(); return ( <>
@@ -30,12 +30,11 @@ const Proverbs = ()=> {

{Proverb.english}

- { Proverb.meaning? -
-

{Proverb.meaning}

-
- :" " } - + {Proverb.meaning ? +
+

{Proverb.meaning}

+
+ : " "}
diff --git a/src/components/ui/SectionCard.tsx b/src/components/ui/SectionCard.tsx index 52dee4f..761b496 100644 --- a/src/components/ui/SectionCard.tsx +++ b/src/components/ui/SectionCard.tsx @@ -1,9 +1,7 @@ import React from 'react'; import styles from "@/components/ui/sectionCard.module.css"; import Link from "next/link"; -import Image from "next/image"; -import {StaticImageData} from 'next/image'; -import GheeSankranti from "/public/Ghee_Sankranti.jpeg" +import Image, {StaticImageData} from "next/image"; type SectionCardProps = { cardTitle: string @@ -16,7 +14,7 @@ type SectionCardProps = { } -const SectionCard = ( props : SectionCardProps) => { +const SectionCard = (props: SectionCardProps) => { return (
@@ -33,7 +31,8 @@ const SectionCard = ( props : SectionCardProps) => {

{props.description}

-
READ MORE
+
READ MORE
{props.location && (
div{ +.link-container > div { border-top: 1px solid #E1E4E8; padding: 3px 10px 1px 10px; } -.link-container2{ + +.link-container2 { border-left: 1px solid #E1E4E8; } -.link-container > div > a{ + +.link-container > div > a { text-align: center; color: var(--grey); font-size: 12px; @@ -103,7 +110,7 @@ transform: scale(1, 1); } -.link-container > div:hover > a{ +.link-container > div:hover > a { color: var(--black); filter: drop-shadow(0 0 0.90rem #A0A5AC); } @@ -147,17 +154,18 @@ } -.image-container{ +.image-container { margin-top: 0%; margin-bottom: auto; - margin-left: auto; + margin-left: auto; margin-right: 0%; width: fit-content; flex: 1; flex-direction: row; justify-content: flex-end; } -.image-container > img{ + +.image-container > img { width: auto; max-width: 250px; @@ -168,33 +176,33 @@ } - /* Mobile */ @media (max-width: 700px) { - .card{ + .card { width: 96%; padding-top: 3rem; margin-top: 3rem; } - .subTitle{ + .subTitle { font-weight: 300; } - .title{ + .title { font-size: 20px; } - .image-container{ + .image-container { display: none; } - .image-container > img{ + + .image-container > img { width: 100px; height: 100%; } - .link-container > div > a{ + .link-container > div > a { font-size: 10px; } } diff --git a/src/components/ui/TrekCard.tsx b/src/components/ui/TrekCard.tsx index 254d145..8a46097 100644 --- a/src/components/ui/TrekCard.tsx +++ b/src/components/ui/TrekCard.tsx @@ -1,137 +1,143 @@ "use client"; // Marking this as a client component -import React, { useState } from "react"; // Import useState for managing state - +import React, {useState} from "react"; // Import useState for managing state import styles from "./TrekCard.module.css"; import MapModal from '../../components/ui/MapModal'; + export type TrekDetails = { - title: string; - introduction: string; - address : string; - coordinates : number[]; - overview: string; - route: string[]; - attractions: string[]; - culturalInsights: string[]; - physicalChallenges: string[]; - recommendedGear: string[]; - bestTimeToVisit: string; - image: string; // Change this to an array of strings + title: string; + introduction: string; + address: string; + coordinates: number[]; + overview: string; + route: string[]; + attractions: string[]; + culturalInsights: string[]; + physicalChallenges: string[]; + recommendedGear: string[]; + bestTimeToVisit: string; + image: string; // Change this to an array of strings }; type CardProps = { - title: string; - subTitle: string; - trekDetails: TrekDetails; - readMoreLink?: string; + title: string; + subTitle: string; + trekDetails: TrekDetails; + readMoreLink?: string; }; export default function TrekCard(props: CardProps) { - const { title, subTitle, trekDetails, readMoreLink } = props; // Destructure props - const [isExpanded, setIsExpanded] = useState(false); // State to track the expanded content - const [isMapOpen, setIsMapOpen] = useState(false); - - const handleOpenMap = () => setIsMapOpen(true); - const handleCloseMap = () => setIsMapOpen(false); - - - return ( -
-
-

{title}

-

{subTitle}

-
-

{trekDetails.introduction}

- - - - {/* Conditional rendering of the extra content */} - {isExpanded && ( -
-

◆ Overview

-

{trekDetails.overview}

-

◆ Route

-

-

    - {trekDetails.route.map((item, index) => ( -
  • {item}
  • - ))} -
-

- -

◆ Nearby Attractions

-

-

    - {trekDetails.attractions.map((item, index) => ( -
  • - {item} -
  • - ))} -
-

-

◆ Physical Challenges

-

-

    - {trekDetails.physicalChallenges.map((item, index) => ( -
  • - {item} -
  • - ))} -
-

-

◆ Recommended Gear

-

-

    - {trekDetails.recommendedGear.map((item, index) => ( -
  • - {item} -
  • - ))} -
-

-

◆ Cultural Insights

-

-

    - {trekDetails.culturalInsights.map((item, index) => ( -
  • - {item} -
  • - ))} -
-

-

◆ Best Time To Visit

-

{trekDetails.bestTimeToVisit}

- -
- )} -
- -
- {/* Conditionally hide the 'READ MORE' link when expanded */} - {!isExpanded && ( -
- + const {title, subTitle, trekDetails, readMoreLink} = props; // Destructure props + const [isExpanded, setIsExpanded] = useState(false); // State to track the expanded content + const [isMapOpen, setIsMapOpen] = useState(false); + + const handleOpenMap = () => setIsMapOpen(true); + const handleCloseMap = () => setIsMapOpen(false); + + + return ( +
+
+

{title}

+

{subTitle}

+
+

{trekDetails.introduction}

+ + + {/* Conditional rendering of the extra content */} + {isExpanded && ( +
+

◆ Overview

+

{trekDetails.overview}

+

◆ Route

+

+

    + {trekDetails.route.map((item, index) => ( +
  • {item}
  • + ))} +
+

+ +

◆ Nearby Attractions

+

+

    + {trekDetails.attractions.map((item, index) => ( +
  • + {item} +
  • + ))} +
+

+

◆ Physical Challenges

+

+

    + {trekDetails.physicalChallenges.map((item, index) => ( +
  • + {item} +
  • + ))} +
+

+

◆ Recommended Gear

+

+

    + {trekDetails.recommendedGear.map((item, index) => ( +
  • + {item} +
  • + ))} +
+

+

◆ Cultural Insights

+

+

    + {trekDetails.culturalInsights.map((item, index) => ( +
  • + {item} +
  • + ))} +
+

+

◆ Best Time To Visit

+

{trekDetails.bestTimeToVisit}

+ +
+ )} +
+ +
+ {/* Conditionally hide the 'READ MORE' link when expanded */} + {!isExpanded && ( +
+ +
+ )} + {isExpanded && ( +
+ +
+ )} +
+ +
+
- )} - {isExpanded && ( -
- + +
+ {title}
- )} -
- -
-
-
-
- {title} -
+ - - -
- ); +
+ ); } diff --git a/src/components/ui/navbar.module.css b/src/components/ui/navbar.module.css index c03fe57..0e9ac2f 100644 --- a/src/components/ui/navbar.module.css +++ b/src/components/ui/navbar.module.css @@ -1,89 +1,93 @@ .navbar-container { - width: 100%; - backdrop-filter: blur(10px); - z-index: 100; - position: fixed; - display: flex; - justify-content: center; + width: 100%; + backdrop-filter: blur(10px); + z-index: 100; + position: fixed; + display: flex; + justify-content: center; } + .avatar-container { - display: flex; - align-items: center; + display: flex; + align-items: center; } .avatar { - width: 40px; - height: 40px; - border-radius: 50%; - object-fit: cover; + width: 40px; + height: 40px; + border-radius: 50%; + object-fit: cover; } + .navbar { - width: 95%; - height: 4rem; - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - padding: 22px 0 20px 0; - border-bottom: 1px solid #e1e4e8; + width: 95%; + height: 4rem; + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + padding: 22px 0 20px 0; + border-bottom: 1px solid #e1e4e8; } + .fade-navbar-effect { - width: 100%; - height: 4rem; - margin-top: 3rem; + width: 100%; + height: 4rem; + margin-top: 3rem; - z-index: 1; - position: fixed; - /*background-image: linear-gradient(294deg, rgb(59, 61, 65) 0%, rgba(255, 0, 0, 0.8) 108.834%);*/ - -webkit-mask-image: linear-gradient( - to bottom, - rgba(0, 0, 0, 1) 0%, - rgba(0, 0, 0, 0.2) 100%, - rgba(0, 0, 0, 0) 100% - ); - mask-image: linear-gradient( - to bottom, - rgba(0, 0, 0, 1) 0%, - rgba(0, 0, 0, 0.2) 90%, - rgba(0, 0, 0, 0) 100% - ); - backdrop-filter: blur(10px); + z-index: 1; + position: fixed; + /*background-image: linear-gradient(294deg, rgb(59, 61, 65) 0%, rgba(255, 0, 0, 0.8) 108.834%);*/ + -webkit-mask-image: linear-gradient( + to bottom, + rgba(0, 0, 0, 1) 0%, + rgba(0, 0, 0, 0.2) 100%, + rgba(0, 0, 0, 0) 100% + ); + mask-image: linear-gradient( + to bottom, + rgba(0, 0, 0, 1) 0%, + rgba(0, 0, 0, 0.2) 90%, + rgba(0, 0, 0, 0) 100% + ); + backdrop-filter: blur(10px); } + .empty-navbar { - margin-top: 2rem; - height: 4rem; - width: 95%; + margin-top: 2rem; + height: 4rem; + width: 95%; } .title { - font-size: 14px; - color: var(--green); - letter-spacing: 0.03em; - font-weight: 700; - filter: drop-shadow(0 0 0.8rem #a0a5ac); - text-transform: uppercase; - margin: 0; + font-size: 14px; + color: var(--green); + letter-spacing: 0.03em; + font-weight: 700; + filter: drop-shadow(0 0 0.8rem #a0a5ac); + text-transform: uppercase; + margin: 0; } .heading { - text-decoration: none; + text-decoration: none; } .link { - font-size: 14px; - color: var(--soil); - letter-spacing: -0.01em; - font-weight: 650; - filter: drop-shadow(0 0 0.8rem #a0a5ac); - text-transform: uppercase; - text-decoration: none; + font-size: 14px; + color: var(--soil); + letter-spacing: -0.01em; + font-weight: 650; + filter: drop-shadow(0 0 0.8rem #a0a5ac); + text-transform: uppercase; + text-decoration: none; } /* Hover Effects */ .title:hover, .link:hover { - cursor: pointer; - color: rgb(0, 0, 0); + cursor: pointer; + color: rgb(0, 0, 0); } /* Mobile */ @@ -92,7 +96,7 @@ /* Tablet and Smaller Desktop */ @media (min-width: 701px) and (max-width: 1120px) { - .navbar { - width: 93%; - } + .navbar { + width: 93%; + } } diff --git a/src/components/ui/sectionCard.module.css b/src/components/ui/sectionCard.module.css index a0f2a80..743f21b 100644 --- a/src/components/ui/sectionCard.module.css +++ b/src/components/ui/sectionCard.module.css @@ -2,7 +2,7 @@ margin-top: 5rem; } -.sectionCardTitle{ +.sectionCardTitle { display: flex; flex-direction: column; @@ -10,7 +10,7 @@ justify-content: center; } -.sectionCardTitleLine{ +.sectionCardTitleLine { position: absolute; border-top: 1px solid var(--line-grey); @@ -28,8 +28,6 @@ } - - .sectionCardContainer > .sectionCard { display: flex; flex-direction: row; @@ -40,16 +38,17 @@ } -.title{ +.title { /*font-size: 2em;*/ } -.subTitle{ +.subTitle { margin-top: 0.5rem; letter-spacing: 1px; } -.description{ + +.description { margin-top: 1rem; font-size: 13px; color: var(--black); @@ -66,23 +65,26 @@ } -.linkContainer{ +.linkContainer { display: flex; flex-direction: row; margin-top: 1.5rem; } -.linkContainer > div{ +.linkContainer > div { border-top: 1px solid #E1E4E8; padding: 3px 10px 1px 10px; } -.linkContainer1{ + +.linkContainer1 { } -.linkContainer2{ + +.linkContainer2 { border-left: 1px solid #E1E4E8; } -.linkContainer > div > a{ + +.linkContainer > div > a { text-align: center; color: var(--grey); font-size: 12px; @@ -113,21 +115,21 @@ transform: scale(1, 1); } -.linkContainer > div:hover > a{ +.linkContainer > div:hover > a { color: var(--black); filter: drop-shadow(0 0 0.90rem #A0A5AC); } - -.imageContainer{ +.imageContainer { margin-left: 2rem; width: 100%; display: flex; flex-direction: row; justify-content: flex-end; } -.imageContainer > img{ + +.imageContainer > img { width: auto; max-width: 250px; @@ -136,7 +138,6 @@ } - /* Mobile */ @media (max-width: 700px) { @@ -145,8 +146,7 @@ /* padding-top: 3rem;*/ /* margin-top: 3rem;*/ /*}*/ - - .sectionCardContainer { + .sectionCardContainer { margin-top: 8rem; } @@ -156,27 +156,28 @@ justify-content: space-between; } - .subTitle{ + .subTitle { font-weight: 300; } - .title{ + .title { font-size: 20px; } - .imageContainer{ + .imageContainer { margin-left: 0; width: 100%; margin-bottom: 1rem; } - .imageContainer > img{ + + .imageContainer > img { width: auto; max-width: 250px; height: auto; border-radius: 5px; } - .imageContainer > img{ + .imageContainer > img { /*width: 100px;*/ /*height: 100%;*/ @@ -185,7 +186,7 @@ height: auto; } - .linkContainer > div > a{ + .linkContainer > div > a { font-size: 10px; } } \ No newline at end of file diff --git a/src/lib/drizzle.ts b/src/lib/drizzle.ts index 28b50f6..4c96241 100644 --- a/src/lib/drizzle.ts +++ b/src/lib/drizzle.ts @@ -1,6 +1,6 @@ -import { drizzle } from 'drizzle-orm/neon-http'; +import {drizzle} from 'drizzle-orm/neon-http'; import * as schema from '@/lib/schema'; -import { neon } from '@neondatabase/serverless'; +import {neon} from '@neondatabase/serverless'; // Load the connection string from environment variables const connectionString = process.env.DATABASE_URL; @@ -13,4 +13,4 @@ if (!connectionString) { const pool = neon(connectionString); // Export the configured database instance -export const db = drizzle(pool, { schema }); +export const db = drizzle(pool, {schema}); diff --git a/src/lib/mailer.ts b/src/lib/mailer.ts index aa1af9f..31c6b00 100644 --- a/src/lib/mailer.ts +++ b/src/lib/mailer.ts @@ -1,12 +1,13 @@ import nodemailer from 'nodemailer'; + const mailer = nodemailer.createTransport({ - host: process.env.MAIL_SERVER_HOST as string, - port: 465, - secure: true, // Use `true` for port 465, `false` for all other ports - auth: { - user: process.env.MAIL_SERVER_USER, - pass: process.env.MAIL_SERVER_PASS, - } + host: process.env.MAIL_SERVER_HOST as string, + port: 465, + secure: true, // Use `true` for port 465, `false` for all other ports + auth: { + user: process.env.MAIL_SERVER_USER, + pass: process.env.MAIL_SERVER_PASS, + } }); export default mailer; \ No newline at end of file diff --git a/src/lib/schema.ts b/src/lib/schema.ts index 40d9225..0341517 100644 --- a/src/lib/schema.ts +++ b/src/lib/schema.ts @@ -1,82 +1,75 @@ -import { - boolean, - timestamp, - pgTable, - text, - primaryKey, - integer, -} from "drizzle-orm/pg-core" -import type { AdapterAccountType } from "next-auth/adapters" +import {boolean, integer, pgTable, primaryKey, text, timestamp,} from "drizzle-orm/pg-core" +import type {AdapterAccountType} from "next-auth/adapters" export const users = pgTable("user", { - id: text("id") - .primaryKey() - .$defaultFn(() => crypto.randomUUID()), - name: text("name"), - email: text("email").unique(), - username: text("username").unique(), - password: text("password"), - alerts: boolean("alerts"), - emailVerified: timestamp("emailVerified", { mode: "date" }), - image: text("image"), + id: text("id") + .primaryKey() + .$defaultFn(() => crypto.randomUUID()), + name: text("name"), + email: text("email").unique(), + username: text("username").unique(), + password: text("password"), + alerts: boolean("alerts"), + emailVerified: timestamp("emailVerified", {mode: "date"}), + image: text("image"), }) export const accounts = pgTable( - "account", - { - userId: text("userId") - .notNull() - .references(() => users.id, { onDelete: "cascade" }), - type: text("type").$type().notNull(), - provider: text("provider").notNull(), - providerAccountId: text("providerAccountId").notNull(), - refresh_token: text("refresh_token"), - access_token: text("access_token"), - expires_at: integer("expires_at"), - token_type: text("token_type"), - scope: text("scope"), - id_token: text("id_token"), - session_state: text("session_state"), - }, - (account) => ({ - compoundKey: primaryKey({ - columns: [account.provider, account.providerAccountId], - }), - }) + "account", + { + userId: text("userId") + .notNull() + .references(() => users.id, {onDelete: "cascade"}), + type: text("type").$type().notNull(), + provider: text("provider").notNull(), + providerAccountId: text("providerAccountId").notNull(), + refresh_token: text("refresh_token"), + access_token: text("access_token"), + expires_at: integer("expires_at"), + token_type: text("token_type"), + scope: text("scope"), + id_token: text("id_token"), + session_state: text("session_state"), + }, + (account) => ({ + compoundKey: primaryKey({ + columns: [account.provider, account.providerAccountId], + }), + }) ) export const sessions = pgTable("session", { - sessionToken: text("sessionToken").primaryKey(), - userId: text("userId") - .notNull() - .references(() => users.id, { onDelete: "cascade" }), - expires: timestamp("expires", { mode: "date" }).notNull(), + sessionToken: text("sessionToken").primaryKey(), + userId: text("userId") + .notNull() + .references(() => users.id, {onDelete: "cascade"}), + expires: timestamp("expires", {mode: "date"}).notNull(), }) export const verificationTokens = pgTable( - "verificationToken", - { - identifier: text("identifier").notNull(), - token: text("token").notNull(), - expires: timestamp("expires", { mode: "date" }).notNull(), - }, - (verificationToken) => ({ - compositePk: primaryKey({ - columns: [verificationToken.identifier, verificationToken.token], - }), - }) + "verificationToken", + { + identifier: text("identifier").notNull(), + token: text("token").notNull(), + expires: timestamp("expires", {mode: "date"}).notNull(), + }, + (verificationToken) => ({ + compositePk: primaryKey({ + columns: [verificationToken.identifier, verificationToken.token], + }), + }) ) export const otps = pgTable("otp", { - userId: text("userId") - .notNull() - .references(() => users.id, { onDelete: "cascade" }), - otp: text("otp").notNull(), - createdAt: timestamp("createdAt", { mode: "date" }).notNull(), - expiresAt: timestamp("expiresAt", { mode: "date" }).notNull(), - isUsed: boolean("isUsed").notNull().default(false), + userId: text("userId") + .notNull() + .references(() => users.id, {onDelete: "cascade"}), + otp: text("otp").notNull(), + createdAt: timestamp("createdAt", {mode: "date"}).notNull(), + expiresAt: timestamp("expiresAt", {mode: "date"}).notNull(), + isUsed: boolean("isUsed").notNull().default(false), }, (otp) => ({ - primaryKey: primaryKey({ columns: [otp.userId, otp.createdAt] }), + primaryKey: primaryKey({columns: [otp.userId, otp.createdAt]}), })); \ No newline at end of file diff --git a/src/lib/zod.ts b/src/lib/zod.ts index ba8fc62..f268022 100644 --- a/src/lib/zod.ts +++ b/src/lib/zod.ts @@ -1,39 +1,39 @@ -import { object, string, z } from "zod"; +import {z} from "zod"; const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/; export const loginSchema = z.object({ - loginIdentifier: z.string().min(1, "Email or Username is required"), - password: z - .string() - .min(8, "Password must be at least 8 characters long") - .regex( - passwordRegex, - "Password must be include at least one uppercase letter, one lowercase letter, one number, and one special character." - ), + loginIdentifier: z.string().min(1, "Email or Username is required"), + password: z + .string() + .min(8, "Password must be at least 8 characters long") + .regex( + passwordRegex, + "Password must be include at least one uppercase letter, one lowercase letter, one number, and one special character." + ), }); export const signupSchema = z - .object({ - username: z.string().min(1, "Username is required"), - name: z.string().min(1, "Name is required"), - email: z.string().email("Invalid email format"), - password: z - .string() - .min(8, "Password must be at least 8 characters long") - .regex( - passwordRegex, - "Password must be include at least one uppercase letter, one lowercase letter, one number, and one special character." - ), - confirmPassword: z.string().min(8, "Confirm Password is required"), - alerts: z.boolean().default(true), - }) - .superRefine(({ password, confirmPassword }, ctx) => { - if (confirmPassword !== password) { - ctx.addIssue({ - code: "custom", - message: "The passwords did not match", - path: ["confirmPassword"], - }); - } - }); \ No newline at end of file + .object({ + username: z.string().min(1, "Username is required"), + name: z.string().min(1, "Name is required"), + email: z.string().email("Invalid email format"), + password: z + .string() + .min(8, "Password must be at least 8 characters long") + .regex( + passwordRegex, + "Password must be include at least one uppercase letter, one lowercase letter, one number, and one special character." + ), + confirmPassword: z.string().min(8, "Confirm Password is required"), + alerts: z.boolean().default(true), + }) + .superRefine(({password, confirmPassword}, ctx) => { + if (confirmPassword !== password) { + ctx.addIssue({ + code: "custom", + message: "The passwords did not match", + path: ["confirmPassword"], + }); + } + }); \ No newline at end of file diff --git a/src/middleware.ts b/src/middleware.ts index eb29563..7cd1105 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -1,57 +1,51 @@ import NextAuth from "next-auth"; import authConfig from "./auth.config"; -import { - DEFAULT_LOGIN_REDIRECT, - apiAuthPrefix, - authRoutes, - publicRoutes, -} from "@/routes"; -import { NextResponse } from "next/server"; +import {apiAuthPrefix, authRoutes, DEFAULT_LOGIN_REDIRECT, publicRoutes,} from "@/routes"; +import {NextResponse} from "next/server"; -const { auth } = NextAuth(authConfig); +const {auth} = NextAuth(authConfig); export default auth((req) => { - const { nextUrl } = req; - const isLoggedIn = !!req.auth; + const {nextUrl} = req; + const isLoggedIn = !!req.auth; - const isApiAuthRoute = nextUrl.pathname.startsWith(apiAuthPrefix); - const isPublicRoute = publicRoutes.includes(nextUrl.pathname); - const isAuthRoute = authRoutes.includes(nextUrl.pathname); - const headers = new Headers(req.headers); - headers.set("x-current-path", req.nextUrl.pathname); + const isApiAuthRoute = nextUrl.pathname.startsWith(apiAuthPrefix); + const isPublicRoute = publicRoutes.includes(nextUrl.pathname); + const isAuthRoute = authRoutes.includes(nextUrl.pathname); + const headers = new Headers(req.headers); + headers.set("x-current-path", req.nextUrl.pathname); - - if (isApiAuthRoute) { - return; - } - - if (isAuthRoute) { - if (isLoggedIn) { - const callbackUrl = nextUrl.searchParams.get("CallbackUrl") || DEFAULT_LOGIN_REDIRECT; - return Response.redirect(new URL(callbackUrl, nextUrl)); + if (isApiAuthRoute) { + return; } - return NextResponse.next({ headers }); - } - if (!isLoggedIn && !isPublicRoute) { - let callbackUrl = nextUrl.pathname; - if (nextUrl.search) { - callbackUrl += nextUrl.search; + if (isAuthRoute) { + if (isLoggedIn) { + const callbackUrl = nextUrl.searchParams.get("CallbackUrl") || DEFAULT_LOGIN_REDIRECT; + return Response.redirect(new URL(callbackUrl, nextUrl)); + } + return NextResponse.next({headers}); } - const encodedCallbackUrl = encodeURIComponent(callbackUrl); + if (!isLoggedIn && !isPublicRoute) { + let callbackUrl = nextUrl.pathname; + if (nextUrl.search) { + callbackUrl += nextUrl.search; + } + const encodedCallbackUrl = encodeURIComponent(callbackUrl); - return Response.redirect( - new URL(`/auth?callbackUrl=${encodedCallbackUrl}`, nextUrl) - ); - } - return NextResponse.next({ headers }); + return Response.redirect( + new URL(`/auth?callbackUrl=${encodedCallbackUrl}`, nextUrl) + ); + } + + return NextResponse.next({headers}); }); // Optionally, don't invoke Middleware on some paths export const config = { - matcher: ["/((?!.+\\.[\\w]+$|_next).*)", "/(api|trpc)(.*)"], + matcher: ["/((?!.+\\.[\\w]+$|_next).*)", "/(api|trpc)(.*)"], }; \ No newline at end of file diff --git a/src/utils/festivals.ts b/src/utils/festivals.ts index 12e1c00..f4f3858 100644 --- a/src/utils/festivals.ts +++ b/src/utils/festivals.ts @@ -10,13 +10,13 @@ export interface Festival { // Define a constant 'festivals', which is an array of objects, each object conforming // to the 'Festival' interface. This array contains details about several Uttarakhand festivals. export const festivals: Festival[] = [ - { name: "Harela", date: "16-07" }, - { name: "Phool Dei", date: "14-03" }, - { name: "Nanda Devi Raj Jat", date: "05-09" }, - { name: "Bikhauti", date: "14-04" }, - { name: "Kauthig", date: "22-02" }, - { name: "Ghee Sankranti", date: "17-02" }, - { name: "Egaas Bhagwal", date: "12-03" } + {name: "Harela", date: "16-07"}, + {name: "Phool Dei", date: "14-03"}, + {name: "Nanda Devi Raj Jat", date: "05-09"}, + {name: "Bikhauti", date: "14-04"}, + {name: "Kauthig", date: "22-02"}, + {name: "Ghee Sankranti", date: "17-02"}, + {name: "Egaas Bhagwal", date: "12-03"} ]; // Define a function 'getUpcomingFestival' which returns the festival happening today or the next upcoming festival, diff --git a/src/utils/proverbs.ts b/src/utils/proverbs.ts index a8b5f2a..6c756d7 100644 --- a/src/utils/proverbs.ts +++ b/src/utils/proverbs.ts @@ -1,5 +1,5 @@ export interface Proverb { - hindi:String, + hindi: String, english: string, meaning?: String } @@ -8,7 +8,7 @@ export const proverbs: Proverb[] = [ { hindi: "पहाड़ का पानी, पहाड़ की जवानी, पहाड़ के काम नहीं आती", english: "The water and the youth of the mountains are never useful to the mountains", - meaning:"Water flows down in the valley and the youth go out to cities to earn, are not useful to the mountains" + meaning: "Water flows down in the valley and the youth go out to cities to earn, are not useful to the mountains" }, { hindi: "अति रुख्यार रूख हूं छुटुछ अति तैरक गाड़ हूं बगछ",