diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..7087371 --- /dev/null +++ b/.env.development @@ -0,0 +1,35 @@ +# Development Environment Variables +# This file contains configuration for local development + +# Deployment +NODE_ENV=development +NEXT_PUBLIC_APP_ENV=development + +# API Configuration +NEXT_PUBLIC_API_URL=https://api.jeepedia.in/api +NEXT_PUBLIC_CDN_URL=https://res.cloudinary.com +NEXT_PUBLIC_ASSETS_URL=https://assets.jeepedia.in + +# Website Configuration +NEXT_PUBLIC_SITE_URL=http://localhost:3000 +NEXT_PUBLIC_DEV_TUNNEL_URL=https://7rfkcr7r-3000.inc1.devtunnels.ms +NEXT_PUBLIC_CONTACT_EMAIL=jeepedia.in@gmail.com + +# Social Media +NEXT_PUBLIC_DISCORD_URL=https://discord.gg/Z8s9JECw4C +NEXT_PUBLIC_INSTAGRAM_URL=https://www.instagram.com/jeepedia.in +NEXT_PUBLIC_GITHUB_URL=https://github.com/J2J-App + +# Analytics (disabled in development) +NEXT_PUBLIC_UMAMI_WEBSITE_ID=dev-test-id +NEXT_PUBLIC_UMAMI_SCRIPT_URL=https://cloud.umami.is/script.js +NEXT_PUBLIC_GOOGLE_ADSENSE_ID=ca-pub-6258466000437582 + +# Feature Flags +NEXT_PUBLIC_ENABLE_ANALYTICS=false +NEXT_PUBLIC_ENABLE_CONSOLE_LOGS=true +NEXT_PUBLIC_MAINTENANCE_MODE=false + +# Performance +NEXT_PUBLIC_API_TIMEOUT=15000 +NEXT_PUBLIC_MAX_RETRIES=3 diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..08952b9 --- /dev/null +++ b/.env.example @@ -0,0 +1,61 @@ +# Environment Variables Template +# Copy this file to .env.local and fill in your actual values +# See README.md for detailed instructions + +# =================== +# DEPLOYMENT CONFIGURATION +# =================== +NODE_ENV=development +NEXT_PUBLIC_APP_ENV=development + +# =================== +# API CONFIGURATION +# =================== +# Main API endpoint +NEXT_PUBLIC_API_URL=https://api.jeepedia.in/api + +# CDN and Asset URLs +NEXT_PUBLIC_CDN_URL=https://res.cloudinary.com +NEXT_PUBLIC_ASSETS_URL=https://assets.jeepedia.in + +# =================== +# WEBSITE CONFIGURATION +# =================== +# Main website URL (used for sitemap, metadata, etc.) +NEXT_PUBLIC_SITE_URL=https://www.jeepedia.in + +# Development tunnel URL (for local development with external access) +NEXT_PUBLIC_DEV_TUNNEL_URL=https://7rfkcr7r-3000.inc1.devtunnels.ms + +# Contact email +NEXT_PUBLIC_CONTACT_EMAIL=jeepedia.in@gmail.com + +# =================== +# SOCIAL MEDIA LINKS +# =================== +NEXT_PUBLIC_DISCORD_URL=https://discord.gg/Z8s9JECw4C +NEXT_PUBLIC_INSTAGRAM_URL=https://www.instagram.com/jeepedia.in +NEXT_PUBLIC_GITHUB_URL=https://github.com/J2J-App + +# =================== +# ANALYTICS & TRACKING +# =================== +# Umami Analytics +NEXT_PUBLIC_UMAMI_WEBSITE_ID=your-umami-website-id +NEXT_PUBLIC_UMAMI_SCRIPT_URL=https://cloud.umami.is/script.js + +# Google Analytics / AdSense +NEXT_PUBLIC_GOOGLE_ADSENSE_ID=ca-pub-6258466000437582 + +# =================== +# FEATURE FLAGS +# =================== +NEXT_PUBLIC_ENABLE_ANALYTICS=true +NEXT_PUBLIC_ENABLE_CONSOLE_LOGS=false +NEXT_PUBLIC_MAINTENANCE_MODE=false + +# =================== +# RATE LIMITING & PERFORMANCE +# =================== +NEXT_PUBLIC_API_TIMEOUT=10000 +NEXT_PUBLIC_MAX_RETRIES=3 diff --git a/.gitignore b/.gitignore index 5ef6a52..fc7dba6 100644 --- a/.gitignore +++ b/.gitignore @@ -30,8 +30,12 @@ yarn-debug.log* yarn-error.log* .pnpm-debug.log* -# env files (can opt-in for committing if needed) -.env* +# env files - allow template and development files, ignore sensitive local files +.env*.local +.env.staging +.env.production +!.env.example +!.env.development # vercel .vercel diff --git a/src/app/compare/page.tsx b/src/app/compare/page.tsx index 7515db0..4c17be8 100644 --- a/src/app/compare/page.tsx +++ b/src/app/compare/page.tsx @@ -5,720 +5,750 @@ import SelectMenu from "@/components/select-menus/select-menu.tsx"; import Combobox from "@/components/combobox/combobox"; import Button from "@/components/buttons/button.tsx"; import Loader from "@/components/loader/loader.tsx"; -import API_URL from "@/config"; +import { API_URL } from "@/config"; -type DataType = any +type DataType = any; export default function Page() { - const [data01, setData01] = useState(null); - const [data02, setData02] = useState(null); - const [year, setYear] = useState("2024"); - const [firstBranch, setFirstBranch] = useState(null); - const [firstUni, setFirstUni] = useState(null); - const [secondBranch, setSecondBranch] = useState(null); - const [secondUni, setSecondUni] = useState(null); - const [errors, setErrors] = useState([]); - const [isLoading, setIsLoading] = useState(false); - const [results, setResults] = useState(null); - - const collegeMap: { [key: string]: string } = { - "nit-jalandhar": "NIT Jalandhar", - "nit-allahabad": "MNNIT Allahabad", - "nit-calicut": "NIT Calicut", - "nit-delhi": "NIT Delhi", - "nit-durgapur": "NIT Durgapur", - "nit-goa": "NIT Goa", - "nit-hamirpur": "NIT Hamirpur", - "nit-surathkal": "NIT Surathkal", - "nit-meghalaya": "NIT Meghalaya", - "nit-patna": "NIT Patna", - "nit-puducherry": "NIT Puducherry", - "nit-raipur": "NIT Raipur", - "nit-sikkim": "NIT Sikkim", - "nit-arunachal-pradesh": "NIT Arunachal Pradesh", - "nit-jamshedpur": "NIT Jamshedpur", - "nit-kurukshetra": "NIT Kurukshetra", - "nit-mizoram": "NIT Mizoram", - "nit-silchar": "NIT Silchar", - "nit-srinagar": "NIT Srinagar", - "nit-trichy": "NIT Trichy", - "nit-uttarakhand": "NIT Uttarakhand", - "nit-warangal": "NIT Warangal", - "nit-surat": "SVNIT Surat", - "nit-nagpur": "VNIT Nagpur", - "iit-bombay": "IIT Bombay", - "iit-mandi": "IIT Mandi", - "iit-delhi": "IIT Delhi", - "iit-indore": "IIT Indore", - "iit-kharagpur": "IIT Kharagpur", - "iit-hyderabad": "IIT Hyderabad", - "iit-jodhpur": "IIT Jodhpur", - "iit-kanpur": "IIT Kanpur", - "iit-gandhinagar": "IIT Gandhinagar", - "iit-patna": "IIT Patna", - "iit-roorkee": "IIT Roorkee", - "iit-ism-dhanbad": "IIT (ISM) Dhanbad", - "iit-ropar": "IIT Ropar", - "iit-guwahati": "IIT Guwahati", - "iit-bhilai": "IIT Bhilai", - "iit-goa": "IIT Goa", - "iit-palakkad": "IIT Palakkad", - "iit-tirupati": "IIT Tirupati", - "iit-jammu": "IIT Jammu", - "iit-dharwad": "IIT Dharwad", - "iiit-guwahati": "IIIT Guwahati", - "iiitm-gwalior": "IIITM Gwalior", - "iiit-kota": "IIIT Kota", - "iiit-surat": "IIIT Surat", - "iiit-sonepat": "IIIT Sonepat", - "iiit-una": "IIIT Una", - "iiit-sri-city": "IIIT Sri City", - "iiit-allahabad": "IIIT Allahabad", - "iiitdm-kancheepuram": "IIITDM Kancheepuram", - "iiitdm-jabalpur": "IIITDM Jabalpur", - "iiit-manipur": "IIIT Manipur", - "iiit-trichy": "IIIT Trichy", - "iiit-dharwad": "IIIT Dharwad", - "iiitdm-kurnool": "IIITDM Kurnool", - "iiit-ranchi": "IIIT Ranchi", - "iiit-nagpur": "IIIT Nagpur", - "iiit-pune": "IIIT Pune", - "iiit-kalyani": "IIIT Kalyani", - "bit-mesra": "BIT Mesra", - "bit-patna": "BIT Patna", - "pec-chandigarh": "PEC Chandigarh", - "iiest-shibpur": "IIEST Shibpur", - "tssot-silchar": "TSSOT Silchar", - "soe-tezpur": "SoE Tezpur University", - "dtu-delhi": "DTU Delhi", - "nsut-delhi-west-campus": "NSUT Delhi (West Campus)", - "nsut-delhi-east-campus": "NSUT Delhi (East Campus)", - "nsut-delhi": "NSUT Delhi", - "igdtuw-delhi": "IGDTUW Delhi", - "iiit-delhi": "IIIT Delhi" - }; - - let option01 = data01?.data[year]?.map((branch: string) => ({ - value: branch, - label: branch, - })) ?? [] - - let option02 = data02?.data[year]?.map((branch: string) => ({ - value: branch, - label: branch, - })) ?? [] + const [data01, setData01] = useState(null); + const [data02, setData02] = useState(null); + const [year, setYear] = useState("2024"); + const [firstBranch, setFirstBranch] = useState(null); + const [firstUni, setFirstUni] = useState(null); + const [secondBranch, setSecondBranch] = useState(null); + const [secondUni, setSecondUni] = useState(null); + const [errors, setErrors] = useState([]); + const [isLoading, setIsLoading] = useState(false); + const [results, setResults] = useState(null); + + const collegeMap: { [key: string]: string } = { + "nit-jalandhar": "NIT Jalandhar", + "nit-allahabad": "MNNIT Allahabad", + "nit-calicut": "NIT Calicut", + "nit-delhi": "NIT Delhi", + "nit-durgapur": "NIT Durgapur", + "nit-goa": "NIT Goa", + "nit-hamirpur": "NIT Hamirpur", + "nit-surathkal": "NIT Surathkal", + "nit-meghalaya": "NIT Meghalaya", + "nit-patna": "NIT Patna", + "nit-puducherry": "NIT Puducherry", + "nit-raipur": "NIT Raipur", + "nit-sikkim": "NIT Sikkim", + "nit-arunachal-pradesh": "NIT Arunachal Pradesh", + "nit-jamshedpur": "NIT Jamshedpur", + "nit-kurukshetra": "NIT Kurukshetra", + "nit-mizoram": "NIT Mizoram", + "nit-silchar": "NIT Silchar", + "nit-srinagar": "NIT Srinagar", + "nit-trichy": "NIT Trichy", + "nit-uttarakhand": "NIT Uttarakhand", + "nit-warangal": "NIT Warangal", + "nit-surat": "SVNIT Surat", + "nit-nagpur": "VNIT Nagpur", + "iit-bombay": "IIT Bombay", + "iit-mandi": "IIT Mandi", + "iit-delhi": "IIT Delhi", + "iit-indore": "IIT Indore", + "iit-kharagpur": "IIT Kharagpur", + "iit-hyderabad": "IIT Hyderabad", + "iit-jodhpur": "IIT Jodhpur", + "iit-kanpur": "IIT Kanpur", + "iit-gandhinagar": "IIT Gandhinagar", + "iit-patna": "IIT Patna", + "iit-roorkee": "IIT Roorkee", + "iit-ism-dhanbad": "IIT (ISM) Dhanbad", + "iit-ropar": "IIT Ropar", + "iit-guwahati": "IIT Guwahati", + "iit-bhilai": "IIT Bhilai", + "iit-goa": "IIT Goa", + "iit-palakkad": "IIT Palakkad", + "iit-tirupati": "IIT Tirupati", + "iit-jammu": "IIT Jammu", + "iit-dharwad": "IIT Dharwad", + "iiit-guwahati": "IIIT Guwahati", + "iiitm-gwalior": "IIITM Gwalior", + "iiit-kota": "IIIT Kota", + "iiit-surat": "IIIT Surat", + "iiit-sonepat": "IIIT Sonepat", + "iiit-una": "IIIT Una", + "iiit-sri-city": "IIIT Sri City", + "iiit-allahabad": "IIIT Allahabad", + "iiitdm-kancheepuram": "IIITDM Kancheepuram", + "iiitdm-jabalpur": "IIITDM Jabalpur", + "iiit-manipur": "IIIT Manipur", + "iiit-trichy": "IIIT Trichy", + "iiit-dharwad": "IIIT Dharwad", + "iiitdm-kurnool": "IIITDM Kurnool", + "iiit-ranchi": "IIIT Ranchi", + "iiit-nagpur": "IIIT Nagpur", + "iiit-pune": "IIIT Pune", + "iiit-kalyani": "IIIT Kalyani", + "bit-mesra": "BIT Mesra", + "bit-patna": "BIT Patna", + "pec-chandigarh": "PEC Chandigarh", + "iiest-shibpur": "IIEST Shibpur", + "tssot-silchar": "TSSOT Silchar", + "soe-tezpur": "SoE Tezpur University", + "dtu-delhi": "DTU Delhi", + "nsut-delhi-west-campus": "NSUT Delhi (West Campus)", + "nsut-delhi-east-campus": "NSUT Delhi (East Campus)", + "nsut-delhi": "NSUT Delhi", + "igdtuw-delhi": "IGDTUW Delhi", + "iiit-delhi": "IIIT Delhi", + }; + + let option01 = + data01?.data[year]?.map((branch: string) => ({ + value: branch, + label: branch, + })) ?? []; + + let option02 = + data02?.data[year]?.map((branch: string) => ({ + value: branch, + label: branch, + })) ?? []; + + if (option01.length === 0) { + option01 = [ + { + value: `No Placement for this year`, + label: `No Placement for this year`, + }, + ]; + } + + if (option02.length === 0) { + option02 = [ + { + value: `No Placement for this year`, + label: `No Placement for this year`, + }, + ]; + } + + useEffect(() => { + if (!firstUni) return; + + const fetchData01 = async () => { + try { + const response = await fetch(`${API_URL}/v2/about/placement-branches`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ college: firstUni }), + }); + + if (!response.ok) { + throw new Error("Network response was not ok"); + } - if (option01.length === 0) { - option01 = [ {value : `No Placement for this year` , label : `No Placement for this year`} ] - } + const result: DataType = await response.json(); + setData01(result); + } catch (error) { + console.error("Error fetching data01:", error); + } + }; - if (option02.length === 0) { - option02 = [ {value : `No Placement for this year` , label : `No Placement for this year`} ] - } + fetchData01(); + }, [firstUni]); + + useEffect(() => { + const fetchBranchData = async ( + college: string, + setter: (data: DataType) => void + ) => { + try { + const response = await fetch(`${API_URL}/v2/about/placement-branches`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ college }), + }); + if (!response.ok) throw new Error("Network error"); + const result: DataType = await response.json(); + setter(result); + } catch (error) { + console.error(`Error fetching data for ${college}:`, error); + } + }; + if (firstUni) fetchBranchData(firstUni, setData01); + if (secondUni) fetchBranchData(secondUni, setData02); + }, [firstUni, secondUni]); - useEffect(() => { - if (!firstUni) return; - - const fetchData01 = async () => { - try { - const response = await fetch( - `${API_URL}/v2/about/placement-branches`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ college: firstUni }), - } - ); - - if (!response.ok) { - throw new Error("Network response was not ok"); - } - - const result: DataType = await response.json(); - setData01(result); - } catch (error) { - console.error("Error fetching data01:", error); - } - }; - - fetchData01(); - }, [firstUni]); - - useEffect(() => { - const fetchBranchData = async (college: string, setter: (data: DataType) => void) => { - try { - const response = await fetch( - `${API_URL}/v2/about/placement-branches`, - { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ college }), - } - ); - if (!response.ok) throw new Error("Network error"); - const result: DataType = await response.json(); - setter(result); - } catch (error) { - console.error(`Error fetching data for ${college}:`, error); - } - }; - - if (firstUni) fetchBranchData(firstUni, setData01); - if (secondUni) fetchBranchData(secondUni, setData02); - }, [firstUni, secondUni]); - - - function DataCard({ data }: { data: any }) { - // console.log(data); - return ( -
+
+

{data.name}

•{" "} +

+ {data.branch} +

+
+
+
+
+
+

Registered

+

+ {data.data.registered ? data.data.registered : "NA"} +

+
+
+

Placed

+

+ {data.data.placed ? data.data.placed : "NA"} +

+
+
+
+

-

-

{data.name}

•{" "} -

- {data.branch} -

-
-
-
-
-
-

Registered

-

- {data.data.registered ? data.data.registered : "NA"} -

-
-
-

Placed

-

- {data.data.placed ? data.data.placed : "NA"} -

-
-
-
-

- {data.data.percent_placed - ? `${data.data.percent_placed.toString().slice(0, 4)}%` - : "NA"} -

-
-
-
-
-

Average

-

- {data.data.avg ? `₹${data.data.avg} LPA` : "NA"} -

-
-
-

Median

-

- {data.data.medium ? `₹${data.data.medium} LPA` : "NA"} -

-
-
-
+ > + {data.data.percent_placed + ? `${data.data.percent_placed.toString().slice(0, 4)}%` + : "NA"} +

- ); - } +
+
+
+

Average

+

+ {data.data.avg ? `₹${data.data.avg} LPA` : "NA"} +

+
+
+

Median

+

+ {data.data.medium ? `₹${data.data.medium} LPA` : "NA"} +

+
+
+
+
+ ); + } - function handleYearChange(e: string) { - setYear(e); - } + function handleYearChange(e: string) { + setYear(e); + } - async function handleClick() { - // Clear previous errors and results - setErrors([]); - setResults(null); + async function handleClick() { + // Clear previous errors and results + setErrors([]); + setResults(null); - // Validate inputs - if (!firstUni || !firstBranch || !secondUni || !secondBranch) { - setErrors(["Please select all options"]); - return; + // Validate inputs + if (!firstUni || !firstBranch || !secondUni || !secondBranch) { + setErrors(["Please select all options"]); + return; + } + + setIsLoading(true); + + try { + // First college/branch fetch + let response1, data1; + try { + response1 = await fetch(`${API_URL}/v2/placement/getPlacement`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + year: Number(year), + branch: firstBranch, + college: firstUni, + }), + }); + + if (!response1.ok) { + throw new Error( + `Failed to fetch data for ${firstUni}: ${response1.status} ${response1.statusText}` + ); } - setIsLoading(true); - - try { - // First college/branch fetch - let response1, data1; - try { - response1 = await fetch( - `${API_URL}/v2/placement/getPlacement`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - year: Number(year), - branch: firstBranch, - college: firstUni, - }), - } - ); - - if (!response1.ok) { - throw new Error( - `Failed to fetch data for ${firstUni}: ${response1.status} ${response1.statusText}` - ); - } - - data1 = await response1.json(); - if (!data1.data) { - throw new Error(`No data available for ${firstUni} - ${firstBranch}`); - } - } catch (error: any) { - throw new Error(`Error fetching data for ${firstUni}: ${error.message}`); - } - - // Second college/branch fetch - let response2, data2; - try { - response2 = await fetch( - `${API_URL}/v2/placement/getPlacement`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - year: Number(year), - branch: secondBranch, - college: secondUni, - }), - } - ); - - if (!response2.ok) { - throw new Error( - `Failed to fetch data for ${secondUni}: ${response2.status} ${response2.statusText}` - ); - } - - data2 = await response2.json(); - if (!data2.data) { - throw new Error( - `No data available for ${secondUni} - ${secondBranch}` - ); - } - } catch (error: any) { - throw new Error( - `Error fetching data for ${secondUni}: ${error.message}` - ); - } - - // Construct result object - const data = { - first: { - name: collegeMap[firstUni] || firstUni, - branch: firstBranch, - data: data1.data, - }, - second: { - name: collegeMap[secondUni] || secondUni, - branch: secondBranch, - data: data2.data, - }, - }; - - setResults(data); - } catch (error: any) { - setErrors([error.message || "An unexpected error occurred"]); - console.error("Compare error:", error); - } finally { - setIsLoading(false); + data1 = await response1.json(); + if (!data1.data) { + throw new Error(`No data available for ${firstUni} - ${firstBranch}`); + } + } catch (error: any) { + throw new Error( + `Error fetching data for ${firstUni}: ${error.message}` + ); + } + + // Second college/branch fetch + let response2, data2; + try { + response2 = await fetch(`${API_URL}/v2/placement/getPlacement`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + year: Number(year), + branch: secondBranch, + college: secondUni, + }), + }); + + if (!response2.ok) { + throw new Error( + `Failed to fetch data for ${secondUni}: ${response2.status} ${response2.statusText}` + ); } - } - function compareAgainClick() { - setFirstBranch(null); - setFirstUni(null); - setSecondBranch(null); - setSecondUni(null); - setIsLoading(false); - setResults(null); - setYear("2024"); + data2 = await response2.json(); + if (!data2.data) { + throw new Error( + `No data available for ${secondUni} - ${secondBranch}` + ); + } + } catch (error: any) { + throw new Error( + `Error fetching data for ${secondUni}: ${error.message}` + ); + } + + // Construct result object + const data = { + first: { + name: collegeMap[firstUni] || firstUni, + branch: firstBranch, + data: data1.data, + }, + second: { + name: collegeMap[secondUni] || secondUni, + branch: secondBranch, + data: data2.data, + }, + }; + + setResults(data); + } catch (error: any) { + setErrors([error.message || "An unexpected error occurred"]); + console.error("Compare error:", error); + } finally { + setIsLoading(false); } - - return ( -
+
+

Compare

+

-
+
+
+

+ Compare branches and colleges based on your preferences. This tool + will help you make an informed decision about your future. +

+
+ {!isLoading && !results && ( +
+ +
+
+

-

Compare

-

- Compare -

+ className={styles.head} + > + Left +

+ setFirstUni(Array.isArray(v) ? v[0] : v)} + /> + {firstUni && ( + setFirstBranch(v)} + /> + )}
-
+

-

- Compare branches and colleges based on your preferences. This tool will - help you make an informed decision about your future. -

+ className={styles.head} + > + Right +

+ setSecondUni(Array.isArray(v) ? v[0] : v)} + /> + {secondUni && ( + setSecondBranch(v)} + /> + )}
- {!isLoading && !results && ( -
- -
-
-

- Left -

- setFirstUni(Array.isArray(v) ? v[0] : v)} - /> - {firstUni && ( - setFirstBranch(v)} - /> - )} -
-
-

- Right -

- setSecondUni(Array.isArray(v) ? v[0] : v)} - /> - {secondUni && ( - setSecondBranch(v)} - /> - )} -
-
-
-
-
- )} - {isLoading && ( -
- -
- )} - {!isLoading && results && ( - <> -
-
-
- -
-
- -
-
-
-
-
- - )} +
+
+
- ); + )} + {isLoading && ( +
+ +
+ )} + {!isLoading && results && ( + <> +
+
+
+ +
+
+ +
+
+
+
+
+ + )} + + ); } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 9b40881..56c4d2e 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -7,8 +7,12 @@ import { Analytics } from "@vercel/analytics/react" import { SpeedInsights } from "@vercel/speed-insights/next" import Footer from "@/components/footer/footer.tsx"; import FooterWrapper from "@/components/footer/footer-wrapper.tsx"; + +import { SITE_URL, CONTACT_EMAIL, DEV_TUNNEL_URL, ANALYTICS, FEATURES } from "@/config"; + import ScrollButton from "@/components/scroll-btn/scroll-button"; + const roboto = Roboto({ subsets: ["latin"], weight: ["100","200","300","400","500","600","700","800","900"], @@ -31,14 +35,14 @@ export const metadata: Metadata = { openGraph: { title: 'The no-bullshit tool for JEE counselling', description: 'JEE Pedia is your ultimate guide to cracking Counselling – get real cutoffs, accurate placement data and branch comparisons all in one place.', - url: 'https://jeepedia.in', + url: SITE_URL, siteName: 'JEEPedia', images: [ { - url: 'https://7rfkcr7r-3000.inc1.devtunnels.ms/og-image.png', + url: `${DEV_TUNNEL_URL || SITE_URL}/og-image.png`, width: 1200, height: 630, - alt: 'Social image alt text', + alt: 'JEEPedia - JEE College Predictor and Counselling Guide', }, ], locale: 'en_US', @@ -46,8 +50,8 @@ export const metadata: Metadata = { }, twitter: { card: 'summary_large_image', - title: 'Your Twitter Title', - description: 'Your Twitter Description', + title: 'JEEPedia - JEE College Predictor', + description: 'The no-bullshit tool for JEE counselling - get real cutoffs, accurate placement data and branch comparisons', images: ['/og-image.png'], }, keywords: [ @@ -69,10 +73,21 @@ export default function RootLayout({ return ( - - + {FEATURES.enableAnalytics && ANALYTICS.umamiWebsiteId && ( +