├── .eslintrc.json ├── .github ├── ISSUE_TEMPLATE │ ├── bug.yml │ ├── documentation.yml │ └── feature.yml └── workflows │ └── greetings.yaml ├── .gitignore ├── .prettierrc ├── CODE_OF_CONDUCT ├── Contributing.md ├── LICENSE ├── README.md ├── app ├── about │ └── page.tsx ├── blog-details │ └── page.tsx ├── blog-sidebar │ └── page.tsx ├── blog │ ├── ChargingStationDayDataset.js │ ├── EVLocations.js │ └── page.tsx ├── contact │ └── page.tsx ├── error │ └── page.tsx ├── layout.tsx ├── page.tsx ├── providers.tsx ├── signin │ └── page.tsx └── signup │ └── page.tsx ├── components ├── About │ ├── AboutSectionOne.tsx │ └── AboutSectionTwo.tsx ├── Blog │ ├── RelatedPost.tsx │ ├── SharePost.tsx │ ├── SingleBlog.tsx │ ├── TagButton.tsx │ ├── blogData.tsx │ └── index.tsx ├── Brands │ ├── brandsData.tsx │ └── index.tsx ├── Common │ ├── Breadcrumb.tsx │ ├── ScrollUp.tsx │ └── SectionTitle.tsx ├── Contact │ ├── NewsLatterBox.tsx │ └── index.tsx ├── Features │ ├── SingleFeature.tsx │ ├── featuresData.tsx │ └── index.tsx ├── Footer │ ├── index.tsx │ └── styles.css ├── Header │ ├── ChargingStationDayDataset.js │ ├── EVLocations.js │ ├── ThemeToggler.tsx │ ├── index.tsx │ └── menuData.tsx ├── Hero │ ├── ChargingStationDayDataset.js │ ├── EVLocations.js │ └── index.tsx ├── Pricing │ ├── OfferList.tsx │ ├── PricingBox.tsx │ └── index.tsx ├── ScrollToTop │ └── index.tsx ├── Testimonials │ ├── SingleTestimonial.tsx │ └── index.tsx └── Video │ └── index.tsx ├── firebaseConfig.js ├── global.d.ts ├── jsconfig.json ├── next-env.d.ts ├── next.config.js ├── package-lock.json ├── package.json ├── pnpm-lock.yaml ├── postcss.config.js ├── public ├── favicon.ico └── images │ ├── 404.svg │ ├── about │ ├── about-image-2-dark.svg │ ├── about-image-2.svg │ ├── about-image-dark.svg │ └── about-image.svg │ ├── blog │ ├── author-01.png │ ├── author-02.png │ ├── author-03.png │ ├── blog-01.jpg │ ├── blog-02.jpg │ ├── blog-03.jpg │ ├── blog-details-01.jpg │ ├── blog-details-02.jpg │ ├── post-01.jpg │ ├── post-02.jpg │ └── post-03.jpg │ ├── brands │ ├── ayroui-light.svg │ ├── ayroui.svg │ ├── ecommerce-html.svg │ ├── graygrids.svg │ ├── lineicons-light.svg │ ├── lineicons.svg │ ├── plainadmin-light.svg │ ├── plainadmin.svg │ ├── tailadmin.svg │ ├── tailgrids-light.svg │ ├── tailgrids.svg │ ├── uideck-light.svg │ └── uideck.svg │ ├── favicon.png │ ├── hero │ ├── shape-01.svg │ └── shape-02.svg │ ├── logo │ ├── logo1.png │ └── logo2.jpg │ ├── testimonials │ ├── auth-01.png │ ├── auth-02.png │ ├── auth-03.png │ ├── author-01.png │ ├── author-02.png │ └── author-03.png │ └── video │ ├── shape.svg │ └── video.jpg ├── styles └── index.css ├── tailwind.config.js ├── trained.h5 ├── tsconfig.json └── types ├── blog.ts ├── brand.ts ├── feature.ts ├── menu.ts └── testimonial.ts /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug.yml: -------------------------------------------------------------------------------- 1 | name: "🐞 Bug Report" 2 | description: "Create a report to help us improve" 3 | title: "BUG:" 4 | labels: ["Bug"] 5 | body: 6 | - type: checkboxes 7 | attributes: 8 | label: "Is there an existing issue for this?" 9 | description: "Please search to see if an issue already exists for the bug you encountered." 10 | options: 11 | - label: "I have searched the existing issues" 12 | required: true 13 | - type: textarea 14 | attributes: 15 | label: "What happened?" 16 | description: "A concise description of what you're experiencing." 17 | validations: 18 | required: true 19 | - type: checkboxes 20 | attributes: 21 | label: "Record" 22 | options: 23 | - label: "I agree to follow this project's Code of Conduct" 24 | required: true 25 | - label: "I'm a GSSOC'24 contributor" 26 | - label: "I want to work on this issue" -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/documentation.yml: -------------------------------------------------------------------------------- 1 | name: "📑 Documentation Update" 2 | description: "Improve Documentation" 3 | title: "DOC:" 4 | labels: [DOC, Needs Triage] 5 | body: 6 | - type: textarea 7 | attributes: 8 | label: "What's wrong with the existing documentation" 9 | description: "Which things do we need to add or delete" 10 | validations: 11 | required: true 12 | - type: textarea 13 | attributes: 14 | label: "Add ScreenShots" 15 | description: "Add sufficient SS to explain your issue." 16 | validations: 17 | required: false 18 | 19 | - type: checkboxes 20 | attributes: 21 | label: "Record" 22 | options: 23 | - label: "I agree to follow this project's Code of Conduct" 24 | required: true 25 | - label: "I'm a GSSOC'24 contributor" 26 | - label: "I want to work on this issue" -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature.yml: -------------------------------------------------------------------------------- 1 | name: "✨ Feature Request" 2 | description: "Suggest an idea for this project " 3 | title: "Feat:" 4 | labels: [Feat, Needs Triage] 5 | body: 6 | - type: textarea 7 | attributes: 8 | label: "Describe the feature" 9 | description: 10 | validations: 11 | required: true 12 | - type: textarea 13 | attributes: 14 | label: "Add ScreenShots" 15 | description: "Add sufficient SS to explain your issue." 16 | validations: 17 | required: true 18 | - type: checkboxes 19 | attributes: 20 | label: "Record" 21 | options: 22 | - label: "I agree to follow this project's Code of Conduct" 23 | required: true 24 | - label: "I'm a GSSOC'24 contributor" 25 | - label: "I want to work on this issue" -------------------------------------------------------------------------------- /.github/workflows/greetings.yaml: -------------------------------------------------------------------------------- 1 | name: Greetings 2 | 3 | on: [pull_request_target, issues] 4 | 5 | jobs: 6 | greeting: 7 | runs-on: ubuntu-latest 8 | permissions: 9 | issues: write 10 | pull-requests: write 11 | steps: 12 | - uses: actions/first-interaction@v1 13 | with: 14 | repo-token: ${{ secrets.GITHUB_TOKEN }} 15 | issue-message: "Hi there! Thanks for opening this issue. We appreciate your contribution to this open-source project. We aim to respond or assign your issue as soon as possible." 16 | pr-message: "Welcome to Our repository.🎊 Thank you so much for taking the time to point this out." 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .vscode 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | .pnpm-debug.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["prettier-plugin-tailwindcss"] 3 | } 4 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT: -------------------------------------------------------------------------------- 1 | # Smart-grid - GSSoC Contributors Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | - Demonstrating empathy and kindness toward other people 21 | - Being respectful of differing opinions, viewpoints, and experiences 22 | - Giving and gracefully accepting constructive feedback 23 | - Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | - Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | - The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | - Trolling, insulting or derogatory comments, and personal or political attacks 33 | - Public or private harassment 34 | - Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | - Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | [Mayank Sharma]https://www.linkedin.com/in/mayanksharma2808/ 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. -------------------------------------------------------------------------------- /Contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing to Smart-grid 2 | 3 | Welcome to **Smart-grid!** We are glad that you are interested in contributing. 4 | 5 | ## How to Contribute 6 | 7 | We welcome contributions from everyone. Here are some ways you can contribute: 8 | 9 | 1. **Reporting Bugs**: If you encounter a bug, please open an issue and provide as much detail as possible, including steps to reproduce the bug. 10 | 11 | 2. **Requesting Features**: If you have a feature request, feel free to open an issue to discuss it. We appreciate detailed descriptions of the requested feature and its use case. 12 | 13 | 3. **Fixing Issues**: Raise an issue if you find any issue. 14 | 15 | 4. **Improving Documentation**: Documentation is crucial. If you find any errors or areas that need improvement in our documentation, feel free to submit a pull request with your changes. 16 | 17 | 5. **Adding Features**: If you want to add a new feature, please open an issue first to discuss it. Once approved, you can work on it and submit a pull request. 18 | 19 | ## Getting Started 20 | 21 | To start contributing, follow these steps: 22 | 23 | 1. Fork the repository to your GitHub account using the **Fork** button. 24 | 25 | 2. Clone your forked repository to your local machine: 26 | ``` 27 | git clone 28 | ``` 29 | 30 | 3. Create a new branch for your changes: 31 | ``` 32 | git checkout -b feature/your-feature 33 | ``` 34 | 35 | 4. To run the project make sure to download all the packages using npm: 36 | ``` 37 | npm install 38 | ``` 39 | 40 | 5. Make your changes and commit them with descriptive commit messages: 41 | ``` 42 | git add . 43 | git commit -m "Add your commit message" 44 | ``` 45 | 46 | 6. Push your changes to your forked repository: 47 | ``` 48 | git push origin 49 | ``` 50 | 51 | 7. Finally, open a pull request on the original repository. 52 | 53 | 54 | ## Code Style 55 | 56 | Please follow the existing code style and conventions used in the project. If you are unsure about anything, feel free to ask. 57 | 58 | ## Code Review 59 | 60 | All submissions require review. GitHub pull requests are used for this purpose. 61 | 62 | 63 | Thank you for your interest in contributing to **Smart-grid!** 64 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Next.js Templates 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EVNotify 2 | 3 | ![image](public/images/logo/logo2.jpg) 4 | 5 | 6 | EVNotify is a revolutionary application designed to streamline communication between powerhouses and electric vehicle (EV) charging stations. By harnessing decentralized networks, EVNotify provides users with real-time updates on charging station status, maintenance schedules, and nearby optimal charging options. Our mission is to simplify EV charging for a greener future. 7 | 8 | ## Visit our [Website](https://smart-ethindia.vercel.app/blog) 9 | 10 | ![image](https://github.com/dhanyashreem2400/Smart-grid/assets/97956917/68ccf581-b048-4600-8bc0-b5d340279a18) 11 | 12 | 13 | ## Features 14 | 15 | ### Integrated Map 16 | - Displays nearby charging stations with red, yellow, and green markers indicating high, medium, and low traffic respectively. 17 | 18 | ![image](https://github.com/dhanyashreem2400/Smart-grid/assets/97956917/8ac68d24-e626-4dbb-928d-6fe8c981f133) 19 | 20 | 21 | ### Nearest Station 22 | - Guides users to the nearest charging station with high power availability and less traffic. 23 | 24 | ![image](https://github.com/dhanyashreem2400/Smart-grid/assets/97956917/5637d37a-cd3b-4211-9828-511af49308f7) 25 | 26 | 27 | ### Station Updates 28 | - Utilizes push protocol to keep users informed about closed EV stations, maintenance schedules, and updates on high-traffic charging stations. 29 | - Employs the power of Long-Short Term Memory models (LLMs) and machine learning models to predict the load of charging stations. 30 | 31 | ![image](https://github.com/dhanyashreem2400/Smart-grid/assets/97956917/dcec5333-9c02-47d3-acee-b7ea7c8d71aa) 32 | 33 | 34 | ### Real-time Data Storage 35 | - Utilizes [InterPlanetary File System (IPFS)](https://ipfs.tech/) to store real-time data of EVs at power stations. 36 | 37 | ## Getting Started 38 | 39 | To get started with EVNotify, follow these steps: 40 | 41 | 1. Click on the website [EVNotify](https://smart-ethindia.vercel.app/) 42 | 43 | ![image](https://github.com/dhanyashreem2400/Smart-grid/assets/97956917/87d1db48-c247-4624-9f02-6c5be11fbc3d) 44 | 45 | 2. Connect your wallet using [Metamask](https://metamask.io/), follow the on-screen instructions to connect your MetaMask wallet to EVNotify. 46 | 47 | ![image](https://github.com/dhanyashreem2400/Smart-grid/assets/97956917/4a8963d8-50c0-4327-8660-c0d9d6c737e0) 48 | 49 | 3. Sign up for an account or log in if you already have one. 50 | 4. Enable location services to access nearby charging stations. 51 | 5. Explore the integrated map to find charging stations near you. 52 | 6. Receive real-time updates on station status, maintenance schedules, and optimal charging options. 53 | 54 | ## Install Locally on your system 55 | 56 | To run EVNotify locally on your system, follow these steps: 57 | 58 | 1. Clone the repository: 59 | 60 | ```bash 61 | git clone https://github.com/SmartGrid-ETHIndia/Smart-grid 62 | 63 | 2. Install Dependencies: 64 | Use npm (Node Package Manager) to install the project dependencies. In your project directory, run: 65 | 66 | ```bash 67 | npm install 68 | 69 | 3. Environment Configuration: 70 | If your project uses environment variables, make sure to set them up. Typically, you would create a .env file in your project directory and define your environment variables there. 71 | 72 | 4. Start the Application: 73 | Once the dependencies are installed, you can start your Next.js application. If your package.json file has a start script defined, you can simply run: 74 | 75 | ```bash 76 | npm run dev 77 | 78 | 5. Access the Application: 79 | Once the development server is running, open your web browser and navigate to `http://localhost:3000` to view your Next.js application. 80 | 81 | ## License 82 | 83 | [MIT License](LICENSE) 84 | 85 | ## Feedback 86 | 87 | We are constantly working to improve EVNotify and contributions are highly appriciated. 88 | 89 | Let's drive towards a sustainable future together! 90 | 91 | 🔋⚡️🌱 #EVNotify #GreenTech #ElectricVehicles 92 | 93 | -------------------------------------------------------------------------------- /app/about/page.tsx: -------------------------------------------------------------------------------- 1 | import AboutSectionOne from "@/components/About/AboutSectionOne"; 2 | import AboutSectionTwo from "@/components/About/AboutSectionTwo"; 3 | import Breadcrumb from "@/components/Common/Breadcrumb"; 4 | 5 | import { Metadata } from "next"; 6 | 7 | export const metadata: Metadata = { 8 | title: "About Page | Free Next.js Template for Startup and SaaS", 9 | description: "This is About Page for Startup Nextjs Template", 10 | // other metadata 11 | }; 12 | 13 | const AboutPage = () => { 14 | return ( 15 | <> 16 | 20 | 21 | 22 | 23 | ); 24 | }; 25 | 26 | export default AboutPage; 27 | -------------------------------------------------------------------------------- /app/blog/page.tsx: -------------------------------------------------------------------------------- 1 | 2 | "use client" 3 | import React, { useEffect, useRef, useState } from 'react'; 4 | import { Loader } from '@googlemaps/js-api-loader'; 5 | import chargingData from './ChargingStationDayDataset'; 6 | import data from './EVLocations.js'; 7 | import { db } from "./../../firebaseConfig"; 8 | import { getDocs, collection } from 'firebase/firestore'; 9 | 10 | const MapComponent = () => { 11 | const googlemap = useRef(null); 12 | const [addresses, setAddresses] = useState(data); 13 | const EVStationData = chargingData; 14 | const [userLocation, setUserLocation] = useState({ lat: 28.6107, lng: 77.219666 }); // Default location 15 | 16 | const fetchUserLocation = () => { 17 | if (navigator.geolocation) { 18 | navigator.geolocation.getCurrentPosition(position => { 19 | setUserLocation({ 20 | lat: position.coords.latitude, 21 | lng: position.coords.longitude 22 | }); 23 | }, () => { 24 | console.log("Error in getting your location"); 25 | }); 26 | } else { 27 | console.log("Geolocation is not supported by this browser."); 28 | } 29 | }; 30 | 31 | const calculateDistance = (lat1, lon1, lat2, lon2) => { 32 | const R = 6371; // Radius of the Earth in km 33 | const dLat = (lat2 - lat1) * (Math.PI / 180); 34 | const dLon = (lon2 - lon1) * (Math.PI / 180); 35 | const a = 36 | Math.sin(dLat / 2) * Math.sin(dLat / 2) + 37 | Math.cos(lat1 * (Math.PI / 180)) * Math.cos(lat2 * (Math.PI / 180)) * 38 | Math.sin(dLon / 2) * Math.sin(dLon / 2); 39 | const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); 40 | return R * c; 41 | }; 42 | 43 | const searchNearbyStations = (radius) => { 44 | return addresses.filter(address => { 45 | const distance = calculateDistance(userLocation.lat, userLocation.lng, address.latitude, address.longitude); 46 | return distance <= radius; 47 | }); 48 | }; 49 | 50 | let nearbyAddresses = searchNearbyStations(5); 51 | 52 | const searchNearbyStationsWithIncreasedRadius = (radius, maxRadius) => { 53 | if (radius > maxRadius) { 54 | return null; // Stop searching if reached the maximum radius 55 | } 56 | 57 | const nearbyStations = searchNearbyStations(radius); 58 | if (nearbyStations.length === 0) { 59 | // If no stations found in the current radius, try with increased radius 60 | return searchNearbyStationsWithIncreasedRadius(radius * 2, maxRadius); 61 | } else { 62 | return nearbyStations; 63 | } 64 | }; 65 | 66 | // Use the recursive function to search for stations with increasing radii 67 | nearbyAddresses = searchNearbyStationsWithIncreasedRadius(10, 3000); 68 | 69 | const calculateBestStation = () => { 70 | const loadValues = { LOW: 1, MEDIUM: 2, HIGH: 3 }; 71 | const loadTotals = {}; 72 | const loadCounts = {}; 73 | 74 | EVStationData.forEach(record => { 75 | if (nearbyAddresses.some(addr => addr.name === record.station_id)) { 76 | const loadValue = loadValues[record.status.toUpperCase()] || 0; 77 | loadTotals[record.station_id] = (loadTotals[record.station_id] || 0) + loadValue; 78 | loadCounts[record.station_id] = (loadCounts[record.station_id] || 0) + 1; 79 | } 80 | }); 81 | 82 | let minAvgLoad = Infinity; 83 | let bestStation = null; 84 | 85 | Object.keys(loadTotals).forEach(station => { 86 | const avgLoad = loadTotals[station] / loadCounts[station]; 87 | if (avgLoad < minAvgLoad) { 88 | minAvgLoad = avgLoad; 89 | bestStation = nearbyAddresses.find(addr => addr.name === station); 90 | } 91 | }); 92 | 93 | return bestStation; 94 | }; 95 | 96 | const highestCapacityAddress = calculateBestStation(); 97 | 98 | const fetchEVStations = async () => { 99 | const querySnapshot = await getDocs(collection(db, "EVStations")); 100 | const stations = []; 101 | querySnapshot.forEach((doc) => { 102 | stations.push(doc.data()); 103 | }); 104 | setAddresses(stations); 105 | }; 106 | 107 | useEffect(() => { 108 | fetchUserLocation(); 109 | }, []); 110 | 111 | useEffect(() => { 112 | const openGoogleMaps = (event) => { 113 | const lat = event.target.getAttribute('data-lat'); 114 | const lng = event.target.getAttribute('data-lng'); 115 | const url = `https://www.google.com/maps/search/?api=1&query=${lat},${lng}`; 116 | window.open(url, '_blank'); 117 | }; 118 | 119 | window.openGoogleMaps = openGoogleMaps; 120 | 121 | const loader = new Loader({ 122 | apiKey: "AIzaSyBvdxOyyKyljBkWE2M4Y8WUTlVBkBvHwQw", 123 | version: "weekly", 124 | }); 125 | 126 | loader.load().then(() => { 127 | const map = new window.google.maps.Map(googlemap.current, { 128 | center: userLocation, 129 | zoom: 13.3, 130 | mapTypeControl: false 131 | }); 132 | 133 | const greenIcon = { url: 'http://maps.google.com/mapfiles/ms/icons/green-dot.png' }; 134 | const yellowIcon = { url: 'http://maps.google.com/mapfiles/ms/icons/yellow-dot.png' }; 135 | const redIcon = { url: 'http://maps.google.com/mapfiles/ms/icons/red-dot.png' }; 136 | const blueIcon = { url: 'http://maps.google.com/mapfiles/ms/icons/blue-dot.png' }; // Blue icon for user location 137 | 138 | new window.google.maps.Marker({ 139 | position: { lat: userLocation.lat, lng: userLocation.lng }, 140 | map: map, 141 | title: "Your Location", 142 | icon: blueIcon, 143 | }); 144 | 145 | const infoWindow = new window.google.maps.InfoWindow(); 146 | 147 | addresses.forEach(address => { 148 | const isNearby = nearbyAddresses.includes(address); 149 | const isHighestCapacity = address === highestCapacityAddress; 150 | const marker = new window.google.maps.Marker({ 151 | position: { lat: address.latitude, lng: address.longitude }, 152 | map: map, 153 | title: address.name, 154 | icon: isNearby ? (isHighestCapacity ? greenIcon : yellowIcon) : redIcon, 155 | }); 156 | 157 | marker.addListener("click", () => { 158 | const distance = calculateDistance(userLocation.lat, userLocation.lng, address.latitude, address.longitude).toFixed(2); 159 | const contentString = ` 160 |
161 |

Distance: ${distance} km

162 | 163 |
164 | `; 165 | infoWindow.setContent(contentString); 166 | infoWindow.open(map, marker); 167 | }); 168 | }); 169 | }); 170 | }, [addresses, userLocation, nearbyAddresses, highestCapacityAddress]); 171 | 172 | return
; 173 | }; 174 | 175 | export default MapComponent; 176 | -------------------------------------------------------------------------------- /app/contact/page.tsx: -------------------------------------------------------------------------------- 1 | import Breadcrumb from "@/components/Common/Breadcrumb"; 2 | import Contact from "@/components/Contact"; 3 | 4 | import { Metadata } from "next"; 5 | 6 | export const metadata: Metadata = { 7 | title: "Contact Page | Free Next.js Template for Startup and SaaS", 8 | description: "This is Contact Page for Startup Nextjs Template", 9 | // other metadata 10 | }; 11 | 12 | const ContactPage = () => { 13 | return ( 14 | <> 15 | 19 | 20 | 21 | 22 | ); 23 | }; 24 | 25 | export default ContactPage; 26 | -------------------------------------------------------------------------------- /app/layout.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import Footer from "@/components/Footer"; 4 | import Header from "@/components/Header"; 5 | import ScrollToTop from "@/components/ScrollToTop"; 6 | import { Inter } from "next/font/google"; 7 | import "node_modules/react-modal-video/css/modal-video.css"; 8 | import "../styles/index.css"; 9 | 10 | const inter = Inter({ subsets: ["latin"] }); 11 | 12 | export default function RootLayout({ 13 | children, 14 | }: { 15 | children: React.ReactNode; 16 | }) { 17 | return ( 18 | 19 | {/* 20 | will contain the components returned by the nearest parent 21 | head.js. Find out more at https://beta.nextjs.org/docs/api-reference/file-conventions/head 22 | */} 23 | 24 | 25 | 26 | 27 |
28 | {children} 29 |