├── public ├── img │ ├── img6.jpg │ ├── img14.jpg │ └── img1 (2).jpg ├── images │ ├── gg.png │ ├── gg2.png │ ├── us3.png │ ├── img15.jpg │ └── picture1.jpg ├── Profile Template │ └── Profile Template.rar ├── css │ ├── Home.css │ ├── sign.css │ ├── login.css │ ├── profilr.css │ ├── pic (1).css │ └── style.css ├── assets │ └── vendor │ │ ├── bootstrap-icons │ │ └── fonts │ │ │ ├── bootstrap-icons.woff │ │ │ └── bootstrap-icons.woff2 │ │ ├── bootstrap │ │ └── css │ │ │ ├── bootstrap-reboot.min.css │ │ │ ├── bootstrap-reboot.rtl.min.css │ │ │ ├── bootstrap-reboot.rtl.css │ │ │ └── bootstrap-reboot.css │ │ └── swiper │ │ └── swiper-bundle.min.css ├── js │ ├── user_log_session.js │ ├── fogetPass.js │ ├── feedback.js │ ├── login.js │ ├── signup.js │ ├── main.js │ └── backend_map.js ├── style1.css ├── foget.html ├── login.html ├── sign.html ├── style.css ├── pic (1).html ├── profile.html └── index.html ├── Read me first.txt ├── backend ├── Ballerina.toml ├── target │ ├── build │ └── cache │ │ └── niranga_nayanajith │ │ └── backend │ │ └── 0.1.0 │ │ └── java17 │ │ └── niranga_nayanajith-backend-0.1.0.jar ├── Dependencies.toml └── main.bal ├── .github └── workflows │ ├── npm-publish-github-packages.yml │ └── datadog-synthetics.yml └── README.md /public/img/img6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nngeek195/Ballerina-ToWo-Tech/HEAD/public/img/img6.jpg -------------------------------------------------------------------------------- /public/images/gg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nngeek195/Ballerina-ToWo-Tech/HEAD/public/images/gg.png -------------------------------------------------------------------------------- /public/images/gg2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nngeek195/Ballerina-ToWo-Tech/HEAD/public/images/gg2.png -------------------------------------------------------------------------------- /public/images/us3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nngeek195/Ballerina-ToWo-Tech/HEAD/public/images/us3.png -------------------------------------------------------------------------------- /public/img/img14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nngeek195/Ballerina-ToWo-Tech/HEAD/public/img/img14.jpg -------------------------------------------------------------------------------- /public/images/img15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nngeek195/Ballerina-ToWo-Tech/HEAD/public/images/img15.jpg -------------------------------------------------------------------------------- /public/img/img1 (2).jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nngeek195/Ballerina-ToWo-Tech/HEAD/public/img/img1 (2).jpg -------------------------------------------------------------------------------- /public/images/picture1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nngeek195/Ballerina-ToWo-Tech/HEAD/public/images/picture1.jpg -------------------------------------------------------------------------------- /Read me first.txt: -------------------------------------------------------------------------------- 1 | if you are not running backend please use follow to log as a super admin 2 | 3 | 4 | user-name= admin 5 | password= admin -------------------------------------------------------------------------------- /public/Profile Template/Profile Template.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nngeek195/Ballerina-ToWo-Tech/HEAD/public/Profile Template/Profile Template.rar -------------------------------------------------------------------------------- /public/css/Home.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | margin-top: 45px; 3 | margin: 0; 4 | padding: 90px; 5 | width: 120%; 6 | background: #ff0000; 7 | 8 | } -------------------------------------------------------------------------------- /public/assets/vendor/bootstrap-icons/fonts/bootstrap-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nngeek195/Ballerina-ToWo-Tech/HEAD/public/assets/vendor/bootstrap-icons/fonts/bootstrap-icons.woff -------------------------------------------------------------------------------- /public/assets/vendor/bootstrap-icons/fonts/bootstrap-icons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nngeek195/Ballerina-ToWo-Tech/HEAD/public/assets/vendor/bootstrap-icons/fonts/bootstrap-icons.woff2 -------------------------------------------------------------------------------- /backend/Ballerina.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | org = "niranga_nayanajith" 3 | name = "backend" 4 | version = "0.1.0" 5 | distribution = "2201.10.0" 6 | 7 | [build-options] 8 | observabilityIncluded = true 9 | -------------------------------------------------------------------------------- /backend/target/build: -------------------------------------------------------------------------------- 1 | { 2 | "last_build_time": 1728983844833, 3 | "last_update_time": 1728918475936, 4 | "distribution_version": "2201.10.0", 5 | "last_modified_time": { 6 | "backend": 1728828749683 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /backend/target/cache/niranga_nayanajith/backend/0.1.0/java17/niranga_nayanajith-backend-0.1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nngeek195/Ballerina-ToWo-Tech/HEAD/backend/target/cache/niranga_nayanajith/backend/0.1.0/java17/niranga_nayanajith-backend-0.1.0.jar -------------------------------------------------------------------------------- /public/js/user_log_session.js: -------------------------------------------------------------------------------- 1 | 2 | window.addEventListener('load', () => { 3 | const loggedInUser = localStorage.getItem('loggedInUser'); // Get the logged-in user's username 4 | const loggedInEmail = localStorage.getItem('loggedInEmail'); 5 | if (loggedInUser) { 6 | // If the user is logged in, display their username 7 | document.getElementById('username').innerText = loggedInUser; // Replace username placeholder with actual username 8 | document.getElementById('email').innerText = loggedInEmail; // Replace email placeholder with actual email address 9 | } else { 10 | // If no user is logged in, redirect to the signup page 11 | window.location.href = 'sign.html'; // Redirect to registration page if user is not logged in 12 | } 13 | }); 14 | function logout(){ 15 | 16 | localStorage.removeItem('loggedInUser'); // Clear the logged-in user data 17 | window.location.href = 'index.html'; // Redirect to the login page 18 | }; 19 | 20 | -------------------------------------------------------------------------------- /.github/workflows/npm-publish-github-packages.yml: -------------------------------------------------------------------------------- 1 | # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created 2 | # For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages 3 | 4 | name: Node.js Package 5 | 6 | on: 7 | release: 8 | types: [created] 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v4 15 | - uses: actions/setup-node@v4 16 | with: 17 | node-version: 20 18 | - run: npm ci 19 | - run: npm test 20 | 21 | publish-gpr: 22 | needs: build 23 | runs-on: ubuntu-latest 24 | permissions: 25 | contents: read 26 | packages: write 27 | steps: 28 | - uses: actions/checkout@v4 29 | - uses: actions/setup-node@v4 30 | with: 31 | node-version: 20 32 | registry-url: https://npm.pkg.github.com/ 33 | - run: npm ci 34 | - run: npm publish 35 | env: 36 | NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}} 37 | -------------------------------------------------------------------------------- /public/style1.css: -------------------------------------------------------------------------------- 1 | 2 | @import url('https://fonts.googleapis.com/css2?family=Poppins&display=swap'); 3 | body,html{ 4 | height: 100%; 5 | margin: 0; 6 | font-family: 'poppins',sans-serif; 7 | } 8 | .background{ 9 | 10 | background-size: cover; 11 | background-position: center; 12 | height: 50%; 13 | display: flex; 14 | align-items: center; 15 | justify-content: center; 16 | } 17 | .booking-form{ 18 | background-color: rgba(255,255,255,0.7); 19 | padding: 20px; 20 | border-radius: 10px; 21 | max-width: 500px; 22 | width: 80%; 23 | margin: 0 auto; 24 | } 25 | .booking-form h2{ 26 | text-align: center; 27 | } 28 | .booking-form form{ 29 | display: flex; 30 | flex-direction: column; 31 | } 32 | .booking-form input{ 33 | padding: 8px; 34 | border: 1px solid #ccc; 35 | border-radius: 5px; 36 | } 37 | .booking-form button{ 38 | margin-top:10px; 39 | padding: 10px; 40 | background-color: #4CAF50; 41 | color: white; 42 | border: none; 43 | border-radius: 5px; 44 | cursor: pointer; 45 | } 46 | .booking-form button:hover{ 47 | background-color: #45a049; 48 | } -------------------------------------------------------------------------------- /public/js/fogetPass.js: -------------------------------------------------------------------------------- 1 | 2 | const apiUrl = 'http://localhost:9095/api'; 3 | 4 | // Handle foget password 5 | document.getElementById('foget').addEventListener('click', async (event) => { 6 | event.preventDefault(); // Prevent the form from submitting the traditional way 7 | 8 | const username = document.getElementById('username').value; 9 | const email = document.getElementById('email').value; 10 | 11 | // Display "Please wait" message while processing 12 | document.getElementById('msg_result').textContent = 'Your request is sending...'; 13 | 14 | try { 15 | // Make a POST request 16 | await axios.post(`${apiUrl}/foget`, { username,email }); 17 | 18 | // On success, display a welcome message and redirect to the login page 19 | document.getElementById('msg_result').textContent = 'Your request accepted!'; 20 | // Redirect to the login page after 3 seconds 21 | setTimeout(() => { 22 | document.getElementById('msg_result').textContent = 'Check your mail box'; 23 | }, 3000); 24 | 25 | } catch (error) { 26 | // Handle email sending failure or other errors 27 | document.getElementById('msg_result').textContent = `Check your username and Email`; 28 | } 29 | }); 30 | 31 | 32 | -------------------------------------------------------------------------------- /public/js/feedback.js: -------------------------------------------------------------------------------- 1 | 2 | const apiUrl = 'http://localhost:9094/api'; 3 | 4 | // Handle user feedback events 5 | document.getElementById('send_msg').addEventListener('click', async (event) => { 6 | event.preventDefault(); // Prevent the form from submitting the traditional way 7 | 8 | const username = localStorage.getItem('loggedInUser'); 9 | const msg = document.getElementById('msg').value; 10 | const email = localStorage.getItem('loggedInEmail'); 11 | 12 | // Display "Please wait" message while processing 13 | document.getElementById('msg_result').textContent = 'Your massage is sending...'; 14 | 15 | try { 16 | // Make a POST request 17 | await axios.post(`${apiUrl}/msg`, { username,email,msg }); 18 | 19 | // display a message 20 | document.getElementById('msg_result').textContent = 'Your massage sent successfully'; 21 | // Redirect to the login page after 3 seconds 22 | setTimeout(() => { 23 | document.getElementById('msg_result').textContent = 'Thank you'; 24 | }, 3000); 25 | 26 | } catch (error) { 27 | // Handle email sending failure 28 | document.getElementById('msg_result').textContent = `Fail to send, please try again`; 29 | } 30 | }); 31 | 32 | 33 | 34 | function cancel(){ 35 | window.location.href = "pic (1).html"; // Redirect to home page on cancel button click. 36 | } 37 | 38 | -------------------------------------------------------------------------------- /public/foget.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Login Page 7 | 8 | 10 | 11 | 12 | 13 |
14 |
15 |

Fogot Password

16 |
17 |
18 | 19 | 21 |
22 |
23 | 24 | 26 |
27 | 28 |
29 |
30 |

Signup

31 | 32 | 33 |
34 |
35 |
36 |
37 | 38 | 39 | -------------------------------------------------------------------------------- /public/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Login Page 7 | 8 | 10 | 11 | 12 | 13 |
14 |
15 |

Login

16 |
17 |
18 | 19 | 21 |
22 |
23 | 24 | 26 |
27 | 28 |

29 |

Foget Password

30 |
31 |

Signup

32 |
33 |
34 |
35 |
36 | 37 | 38 | -------------------------------------------------------------------------------- /.github/workflows/datadog-synthetics.yml: -------------------------------------------------------------------------------- 1 | # This workflow will trigger Datadog Synthetic tests within your Datadog organisation 2 | # For more information on running Synthetic tests within your GitHub workflows see: https://docs.datadoghq.com/synthetics/cicd_integrations/github_actions/ 3 | 4 | # This workflow uses actions that are not certified by GitHub. 5 | # They are provided by a third-party and are governed by 6 | # separate terms of service, privacy policy, and support 7 | # documentation. 8 | 9 | # To get started: 10 | 11 | # 1. Add your Datadog API (DD_API_KEY) and Application Key (DD_APP_KEY) as secrets to your GitHub repository. For more information, see: https://docs.datadoghq.com/account_management/api-app-keys/. 12 | # 2. Start using the action within your workflow 13 | 14 | name: Run Datadog Synthetic tests 15 | 16 | on: 17 | push: 18 | branches: [ "main" ] 19 | pull_request: 20 | branches: [ "main" ] 21 | 22 | jobs: 23 | build: 24 | runs-on: ubuntu-latest 25 | 26 | steps: 27 | - uses: actions/checkout@v2 28 | 29 | # Run Synthetic tests within your GitHub workflow. 30 | # For additional configuration options visit the action within the marketplace: https://github.com/marketplace/actions/datadog-synthetics-ci 31 | - name: Run Datadog Synthetic tests 32 | uses: DataDog/synthetics-ci-github-action@87b505388a22005bb8013481e3f73a367b9a53eb # v1.4.0 33 | with: 34 | api_key: ${{secrets.DD_API_KEY}} 35 | app_key: ${{secrets.DD_APP_KEY}} 36 | test_search_query: 'tag:e2e-tests' #Modify this tag to suit your tagging strategy 37 | 38 | 39 | -------------------------------------------------------------------------------- /public/js/login.js: -------------------------------------------------------------------------------- 1 | // Base URL of your backend API with the /api prefix 2 | const apiUrl = 'http://localhost:9090/api'; 3 | 4 | // Handle user login 5 | document.getElementById('log').addEventListener('click', async (event) => { 6 | event.preventDefault(); // Prevent the form from submitting the traditional way 7 | const superUser = "admin"; 8 | const superuserpassword = "admin"; 9 | const username = document.getElementById('username').value; 10 | const password = document.getElementById('password').value; 11 | 12 | if(username === superUser && password === superuserpassword){ 13 | localStorage.setItem('loggedInUser', username); 14 | window.location.href= 'pic (1).html'; 15 | }else{ 16 | 17 | try { 18 | const response = await axios.post(`${apiUrl}/login`, { 19 | username, 20 | password 21 | }); 22 | 23 | // If login is successful, store the username in localStorage and redirect to the next page 24 | localStorage.setItem('loggedInUser', username); // Save username in local storage to make user control 25 | document.getElementById('loginResult').textContent = 'Login successful!'; 26 | window.location.href = 'pic (1).html'; // Redirect to the function page 27 | } catch (error) { 28 | // Show error message if login fails 29 | document.getElementById('loginResult').textContent = `Login failed: Invalid username or password.`; 30 | }} 31 | }); 32 | 33 | //foget button redirection 34 | document.getElementById("foget").addEventListener("click", function(){ 35 | window.location.href = "foget.html"; //redirect to fogetpage 36 | }); 37 | 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Towo-Tech-Web-App 2 | 3 | This is a fully functional web application create with #ballerina backend 💃💃 , #mongodb data bases 🛢🛢 and some google api services 4 | 5 | ## How Set Up ballerina To Project 6 | 7 | - First clone the project 🔗 8 | - Install Ballerina to computure. 9 | - Create a ballerina work space as backend 10 | ```bash 11 | bal new backend 12 | 13 | - Then replace that created backend folder into clone folder 14 | 15 | ## How Set Up Data Base 16 | 17 | - Donwload mongodb local data base 📥 18 | Link - https://www.mongodb.com/try/download/community 19 | 20 | - Then create a connection as admin 21 | - In that connection create two databases as "city" & "shops" 22 | 23 | - In city database create a collection as "city" and import the json file which I have given in the souce folder (/json/city.city.json) 24 | - As same make collection in shops database as "shops" and import json file which I have given (/json/shops.shops.json) 25 | - note- in city json file contain real set of data but in shops json file is just a file create for demostration 26 | 27 | #### Now you can run the program 28 | ##### In here I used local database becouse it was easy for my developing porpose 29 | 30 | ## Special 💎💎 31 | 32 | - If you need to skip the loging/signup form without running backend please use follow as username and password then you will able to pass the step 33 | (this step I just use for code viewers to easy their work) 34 | - username 35 | ```bash 36 | admin 37 | - password 38 | ```bash 39 | admin 40 | 41 | 42 | ![WhatsApp Image 2024-10-17 at 10 26 24_96d05dea](https://github.com/user-attachments/assets/5c585ae2-2fa7-421f-aa5e-208765ccfcc0) 43 | 44 | 45 | -------------------------------------------------------------------------------- /public/sign.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SignUp Page 7 | 8 | 10 | 11 | 12 | 13 |
14 |
15 |

SignUp

16 |
17 |
18 | 19 | 21 |
22 |
23 | 24 | 25 |
26 |
27 | 28 | 30 |
31 | 32 |
33 |
34 |

Alredy have a account

35 | 36 |
37 |
38 |
39 |
40 | 41 | 42 | -------------------------------------------------------------------------------- /public/css/sign.css: -------------------------------------------------------------------------------- 1 | /* CSS: sign.css */ 2 | * { 3 | margin: 0; 4 | padding: 0; 5 | box-sizing: border-box; 6 | font-family: 'Arial', sans-serif; 7 | } 8 | 9 | body { 10 | display: flex; 11 | justify-content: center; 12 | align-items: center; 13 | height: 100vh; 14 | background-color: #f0f0f0; 15 | } 16 | 17 | .container { 18 | display: flex; 19 | justify-content: center; 20 | align-items: center; 21 | height: 100%; 22 | } 23 | 24 | .login-box { 25 | background-color: #fff; 26 | padding: 40px; 27 | border-radius: 10px; 28 | box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1); 29 | width: 350px; 30 | text-align: center; 31 | } 32 | 33 | h2 { 34 | margin-bottom: 20px; 35 | font-size: 24px; 36 | color: #333; 37 | } 38 | 39 | .input-group { 40 | margin-bottom: 20px; 41 | text-align: left; 42 | } 43 | 44 | .input-group label { 45 | display: block; 46 | margin-bottom: 8px; 47 | font-size: 14px; 48 | color: #333; 49 | } 50 | 51 | .input-group input { 52 | width: 100%; 53 | padding: 10px; 54 | border: 1px solid #ddd; 55 | border-radius: 5px; 56 | font-size: 16px; 57 | background-color: #f9f9f9; 58 | transition: border 0.3s; 59 | } 60 | 61 | .input-group input:focus { 62 | outline: none; 63 | border-color: #777; 64 | } 65 | 66 | button { 67 | width: 100%; 68 | padding: 12px; 69 | font-size: 16px; 70 | border: none; 71 | border-radius: 5px; 72 | cursor: pointer; 73 | transition: background-color 0.3s ease; 74 | color: white; 75 | background-color: red; 76 | } 77 | 78 | button:hover { 79 | background-color: #cc0000; 80 | } 81 | 82 | a { 83 | text-decoration: none; 84 | color: #ff0000; 85 | font-size: 14px; 86 | } 87 | 88 | a:hover { 89 | text-decoration: underline; 90 | } 91 | 92 | #signupResult { 93 | margin-top: 20px; 94 | color: rgb(253, 3, 3); 95 | } -------------------------------------------------------------------------------- /public/css/login.css: -------------------------------------------------------------------------------- 1 | /* CSS: login.css */ 2 | * { 3 | margin: 0; 4 | padding: 0; 5 | box-sizing: border-box; 6 | font-family: 'Arial', sans-serif; 7 | } 8 | 9 | body { 10 | display: flex; 11 | justify-content: center; 12 | align-items: center; 13 | height: 100vh; 14 | background-color: #f0f0f0; 15 | } 16 | 17 | .container { 18 | display: flex; 19 | justify-content: center; 20 | align-items: center; 21 | height: 100%; 22 | } 23 | 24 | .login-box { 25 | background-color: #fff; 26 | padding: 40px; 27 | border-radius: 10px; 28 | box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1); 29 | width: 350px; 30 | text-align: center; 31 | } 32 | 33 | h2 { 34 | margin-bottom: 20px; 35 | font-size: 24px; 36 | color: #333; 37 | } 38 | 39 | .input-group { 40 | margin-bottom: 20px; 41 | text-align: left; 42 | } 43 | 44 | .input-group label { 45 | display: block; 46 | margin-bottom: 8px; 47 | font-size: 14px; 48 | color: #333; 49 | } 50 | 51 | .input-group input { 52 | width: 100%; 53 | padding: 10px; 54 | border: 1px solid #ddd; 55 | border-radius: 5px; 56 | font-size: 16px; 57 | background-color: #f9f9f9; 58 | transition: border 0.3s; 59 | } 60 | 61 | .input-group input:focus { 62 | outline: none; 63 | border-color: #777; 64 | } 65 | 66 | button { 67 | width: 100%; 68 | padding: 12px; 69 | font-size: 16px; 70 | border: none; 71 | border-radius: 5px; 72 | cursor: pointer; 73 | transition: background-color 0.3s ease; 74 | color: white; 75 | } 76 | 77 | button#log { 78 | background-color: red; 79 | } 80 | 81 | button#log:hover { 82 | background-color: #cc0000; 83 | } 84 | 85 | button#foget { 86 | background-color: #ff3333; 87 | margin-top: 10px; 88 | } 89 | 90 | button#foget:hover { 91 | background-color: #b30000; 92 | } 93 | 94 | a { 95 | text-decoration: none; 96 | color: #ff0000; 97 | font-size: 14px; 98 | } 99 | 100 | a:hover { 101 | text-decoration: underline; 102 | } 103 | 104 | #loginResult { 105 | margin-top: 20px; 106 | color: red; 107 | } -------------------------------------------------------------------------------- /public/js/signup.js: -------------------------------------------------------------------------------- 1 | // Base URL of your backend API with the /api prefix 2 | const apiUrl = 'http://localhost:9090/api'; 3 | 4 | // Helper function to check if the password is strong 5 | function isStrongPassword(password) { 6 | const strongPasswordPattern = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/; 7 | return strongPasswordPattern.test(password); 8 | } 9 | 10 | // Helper function to check if the username contains a number 11 | function isValidUsername(username) { 12 | const usernamePattern = /[0-9]/; 13 | return usernamePattern.test(username); 14 | } 15 | 16 | document.getElementById('signupForm').addEventListener('submit', async (event) => { 17 | event.preventDefault(); 18 | 19 | const username = document.getElementById('username').value; 20 | const password = document.getElementById('password').value; 21 | const email = document.getElementById('email').value; 22 | 23 | // Clear any previous result messages 24 | document.getElementById('signupResult').textContent = ''; 25 | 26 | // Validate the username to contain at least one number 27 | if (!isValidUsername(username)) { 28 | document.getElementById('signupResult').textContent = 'Username must contain at least one number.'; 29 | return; 30 | } 31 | 32 | // Validate the password strength 33 | if (!isStrongPassword(password)) { 34 | document.getElementById('signupResult').textContent = 'Password must be at least 8 characters long and include an uppercase letter, a lowercase letter, a number, and a special character.'; 35 | return; 36 | } 37 | 38 | // Display "Please wait" message while processing 39 | document.getElementById('signupResult').textContent = 'Please wait while we confirm your details...'; 40 | 41 | try { 42 | // Make a POST request to the signup API 43 | await axios.post(`${apiUrl}/signup`, { username, password, email }); 44 | 45 | // On success, display a welcome message and redirect to the login page 46 | document.getElementById('signupResult').textContent = 'Signup successful! Welcome email sent. Redirecting to login...'; 47 | localStorage.setItem('loggedInEmail', email); // Save username in local storage 48 | // Redirect to the login page after 3 seconds 49 | setTimeout(() => { 50 | window.location.href = 'login.html'; 51 | }, 3000); 52 | 53 | } catch (error) { 54 | // Handle email sending failure or other issues 55 | document.getElementById('signupResult').textContent = `Signup failed: Email or username already exists.`; 56 | } 57 | }); 58 | -------------------------------------------------------------------------------- /public/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #f5f5f5; 3 | margin-top: 20px; 4 | } 5 | 6 | .ui-w-80 { 7 | width : 80px !important; 8 | height: auto; 9 | } 10 | 11 | .btn-default { 12 | border-color: rgba(24, 28, 33, 0.1); 13 | background : rgba(0, 0, 0, 0); 14 | color : #4E5155; 15 | } 16 | 17 | label.btn { 18 | margin-bottom: 0; 19 | } 20 | 21 | .btn-outline-primary { 22 | border-color: #26B4FF; 23 | background : transparent; 24 | color : #26B4FF; 25 | } 26 | 27 | .btn { 28 | cursor: pointer; 29 | } 30 | 31 | .text-light { 32 | color: #babbbc !important; 33 | } 34 | 35 | .btn-facebook { 36 | border-color: rgba(0, 0, 0, 0); 37 | background : #3B5998; 38 | color : #fff; 39 | } 40 | 41 | .btn-instagram { 42 | border-color: rgba(0, 0, 0, 0); 43 | background : #000; 44 | color : #fff; 45 | } 46 | 47 | .card { 48 | background-clip: padding-box; 49 | box-shadow : 0 1px 4px rgba(24, 28, 33, 0.012); 50 | } 51 | 52 | .row-bordered { 53 | overflow: hidden; 54 | } 55 | 56 | .account-settings-fileinput { 57 | position : absolute; 58 | visibility: hidden; 59 | width : 1px; 60 | height : 1px; 61 | opacity : 0; 62 | } 63 | 64 | .account-settings-links .list-group-item.active { 65 | font-weight: bold !important; 66 | } 67 | 68 | html:not(.dark-style) .account-settings-links .list-group-item.active { 69 | background: transparent !important; 70 | } 71 | 72 | .account-settings-multiselect~.select2-container { 73 | width: 100% !important; 74 | } 75 | 76 | .light-style .account-settings-links .list-group-item { 77 | padding : 0.85rem 1.5rem; 78 | border-color: rgba(24, 28, 33, 0.03) !important; 79 | } 80 | 81 | .light-style .account-settings-links .list-group-item.active { 82 | color: #4e5155 !important; 83 | } 84 | 85 | .material-style .account-settings-links .list-group-item { 86 | padding : 0.85rem 1.5rem; 87 | border-color: rgba(24, 28, 33, 0.03) !important; 88 | } 89 | 90 | .material-style .account-settings-links .list-group-item.active { 91 | color: #4e5155 !important; 92 | } 93 | 94 | .dark-style .account-settings-links .list-group-item { 95 | padding : 0.85rem 1.5rem; 96 | border-color: rgba(255, 255, 255, 0.03) !important; 97 | } 98 | 99 | .dark-style .account-settings-links .list-group-item.active { 100 | color: #fff !important; 101 | } 102 | 103 | .light-style .account-settings-links .list-group-item.active { 104 | color: #4E5155 !important; 105 | } 106 | 107 | .light-style .account-settings-links .list-group-item { 108 | padding : 0.85rem 1.5rem; 109 | border-color: rgba(24, 28, 33, 0.03) !important; 110 | } -------------------------------------------------------------------------------- /public/css/profilr.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #f5f5f5; 3 | margin-top: 20px; 4 | } 5 | 6 | .ui-w-80 { 7 | width : 80px !important; 8 | height: auto; 9 | } 10 | 11 | .btn-default { 12 | border-color: rgba(24, 28, 33, 0.1); 13 | background : rgba(0, 0, 0, 0); 14 | color : #4E5155; 15 | } 16 | 17 | label.btn { 18 | margin-bottom: 0; 19 | } 20 | 21 | .btn-outline-primary { 22 | border-color: #ff0000; 23 | background : transparent; 24 | color : #ff0000; 25 | } 26 | 27 | .btn { 28 | cursor: pointer; 29 | } 30 | 31 | .text-light { 32 | color: #babbbc !important; 33 | } 34 | 35 | .btn-facebook { 36 | border-color: rgba(0, 0, 0, 0); 37 | background : #ff0000; 38 | color : #fff; 39 | } 40 | 41 | .btn-instagram { 42 | border-color: rgba(0, 0, 0, 0); 43 | background : #000; 44 | color : #fff; 45 | } 46 | 47 | .card { 48 | background-clip: padding-box; 49 | box-shadow : 0 1px 4px rgba(24, 28, 33, 0.012); 50 | } 51 | 52 | .row-bordered { 53 | overflow: hidden; 54 | } 55 | 56 | .account-settings-fileinput { 57 | position : absolute; 58 | visibility: hidden; 59 | width : 1px; 60 | height : 1px; 61 | opacity : 0; 62 | } 63 | 64 | .account-settings-links .list-group-item.active { 65 | font-weight: bold !important; 66 | } 67 | 68 | html:not(.dark-style) .account-settings-links .list-group-item.active { 69 | background: transparent !important; 70 | } 71 | 72 | .account-settings-multiselect~.select2-container { 73 | width: 100% !important; 74 | } 75 | 76 | .light-style .account-settings-links .list-group-item { 77 | padding : 0.85rem 1.5rem; 78 | border-color: rgba(24, 28, 33, 0.03) !important; 79 | } 80 | 81 | .light-style .account-settings-links .list-group-item.active { 82 | color: #4e5155 !important; 83 | } 84 | 85 | .material-style .account-settings-links .list-group-item { 86 | padding : 0.85rem 1.5rem; 87 | border-color: rgba(24, 28, 33, 0.03) !important; 88 | } 89 | 90 | .material-style .account-settings-links .list-group-item.active { 91 | color: #4e5155 !important; 92 | } 93 | 94 | .dark-style .account-settings-links .list-group-item { 95 | padding : 0.85rem 1.5rem; 96 | border-color: rgba(255, 255, 255, 0.03) !important; 97 | } 98 | 99 | .dark-style .account-settings-links .list-group-item.active { 100 | color: #fff !important; 101 | } 102 | 103 | .light-style .account-settings-links .list-group-item.active { 104 | color: #4E5155 !important; 105 | } 106 | 107 | .light-style .account-settings-links .list-group-item { 108 | padding : 0.85rem 1.5rem; 109 | border-color: rgba(24, 28, 33, 0.03) !important; 110 | } -------------------------------------------------------------------------------- /public/js/main.js: -------------------------------------------------------------------------------- 1 | (function ($) { 2 | "use strict"; 3 | 4 | // loader 5 | var loader = function () { 6 | setTimeout(function () { 7 | if ($('#loader').length > 0) { 8 | $('#loader').removeClass('show'); 9 | } 10 | }, 1); 11 | }; 12 | loader(); 13 | 14 | // Back to top button 15 | $(window).scroll(function () { 16 | if ($(this).scrollTop() > 200) { 17 | $('.back-to-top').fadeIn('slow'); 18 | } else { 19 | $('.back-to-top').fadeOut('slow'); 20 | } 21 | }); 22 | $('.back-to-top').click(function () { 23 | $('html, body').animate({scrollTop: 0}, 1500, 'easeInOutExpo'); 24 | return false; 25 | }); 26 | 27 | 28 | // Sticky Navbar 29 | $(window).scroll(function () { 30 | if ($(this).scrollTop() > 90) { 31 | $('.nav-bar').addClass('nav-sticky'); 32 | $('.carousel, .page-header').css("margin-top", "73px"); 33 | } else { 34 | $('.nav-bar').removeClass('nav-sticky'); 35 | $('.carousel, .page-header').css("margin-top", "0"); 36 | } 37 | }); 38 | 39 | 40 | // Dropdown on mouse hover 41 | $(document).ready(function () { 42 | function toggleNavbarMethod() { 43 | if ($(window).width() > 992) { 44 | $('.navbar .dropdown').on('mouseover', function () { 45 | $('.dropdown-toggle', this).trigger('click'); 46 | }).on('mouseout', function () { 47 | $('.dropdown-toggle', this).trigger('click').blur(); 48 | }); 49 | } else { 50 | $('.navbar .dropdown').off('mouseover').off('mouseout'); 51 | } 52 | } 53 | toggleNavbarMethod(); 54 | $(window).resize(toggleNavbarMethod); 55 | }); 56 | 57 | 58 | // Main carousel 59 | $(".carousel .owl-carousel").owlCarousel({ 60 | autoplay: true, 61 | animateOut: 'fadeOut', 62 | animateIn: 'fadeIn', 63 | items: 1, 64 | smartSpeed: 300, 65 | dots: false, 66 | loop: true, 67 | nav : true, 68 | navText : [ 69 | '', 70 | '' 71 | ] 72 | }); 73 | 74 | 75 | // Facts counter 76 | $('[data-toggle="counter-up"]').counterUp({ 77 | delay: 10, 78 | time: 2000 79 | }); 80 | 81 | 82 | // Testimonials carousel 83 | $(".testimonials-carousel").owlCarousel({ 84 | center: true, 85 | autoplay: true, 86 | smartSpeed: 2000, 87 | dots: true, 88 | loop: true, 89 | responsive: { 90 | 0:{ 91 | items:1 92 | }, 93 | 576:{ 94 | items:1 95 | }, 96 | 768:{ 97 | items:2 98 | }, 99 | 992:{ 100 | items:3 101 | } 102 | } 103 | }); 104 | 105 | 106 | // Related post carousel 107 | $(".related-slider").owlCarousel({ 108 | autoplay: true, 109 | dots: false, 110 | loop: true, 111 | nav : true, 112 | navText : [ 113 | '', 114 | '' 115 | ], 116 | responsive: { 117 | 0:{ 118 | items:1 119 | }, 120 | 576:{ 121 | items:1 122 | }, 123 | 768:{ 124 | items:2 125 | } 126 | } 127 | }); 128 | 129 | })(jQuery); 130 | 131 | -------------------------------------------------------------------------------- /public/pic (1).html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Towo Tech 8 | 9 | 10 | 11 | 15 | 16 | 17 | 18 | 21 | 22 | 23 | 26 | 29 | 30 | 31 | 33 | 34 | 35 | 36 | 38 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 77 | 78 | 79 |
80 |
81 |
82 | 83 | 84 |
85 |
86 |
87 | user 90 |

91 |
92 |
93 | 94 |
95 |
96 | 97 | 102 | 107 | 108 | 109 |
110 | 111 |
112 | 113 |
114 | 115 | 116 | 117 |
118 |
119 | 120 |
121 | 130 | 135 |
136 | 137 | 138 |
139 |
140 |
141 | 142 |
143 |
144 | 145 |
146 |
147 | 148 |
149 |
150 |
151 |

Garage Requests

152 | 154 | 157 | 160 |
161 |

162 | 163 |
164 |
165 | 166 |
167 | 168 |
169 | 170 |
171 |
172 | 173 |
174 |
175 |
176 | 177 | 178 | 179 | 188 | 189 | 190 | -------------------------------------------------------------------------------- /backend/Dependencies.toml: -------------------------------------------------------------------------------- 1 | # AUTO-GENERATED FILE. DO NOT MODIFY. 2 | 3 | # This file is auto-generated by Ballerina for managing dependency versions. 4 | # It should not be modified by hand. 5 | 6 | [ballerina] 7 | dependencies-toml-version = "2" 8 | distribution-version = "2201.10.0" 9 | 10 | [[package]] 11 | org = "ballerina" 12 | name = "auth" 13 | version = "2.12.0" 14 | dependencies = [ 15 | {org = "ballerina", name = "crypto"}, 16 | {org = "ballerina", name = "jballerina.java"}, 17 | {org = "ballerina", name = "lang.array"}, 18 | {org = "ballerina", name = "lang.string"}, 19 | {org = "ballerina", name = "log"} 20 | ] 21 | 22 | [[package]] 23 | org = "ballerina" 24 | name = "cache" 25 | version = "3.8.0" 26 | dependencies = [ 27 | {org = "ballerina", name = "constraint"}, 28 | {org = "ballerina", name = "jballerina.java"}, 29 | {org = "ballerina", name = "task"}, 30 | {org = "ballerina", name = "time"} 31 | ] 32 | 33 | [[package]] 34 | org = "ballerina" 35 | name = "constraint" 36 | version = "1.5.0" 37 | dependencies = [ 38 | {org = "ballerina", name = "jballerina.java"} 39 | ] 40 | 41 | [[package]] 42 | org = "ballerina" 43 | name = "crypto" 44 | version = "2.7.2" 45 | dependencies = [ 46 | {org = "ballerina", name = "jballerina.java"}, 47 | {org = "ballerina", name = "time"} 48 | ] 49 | 50 | [[package]] 51 | org = "ballerina" 52 | name = "email" 53 | version = "2.10.0" 54 | dependencies = [ 55 | {org = "ballerina", name = "jballerina.java"}, 56 | {org = "ballerina", name = "log"}, 57 | {org = "ballerina", name = "mime"}, 58 | {org = "ballerina", name = "task"} 59 | ] 60 | modules = [ 61 | {org = "ballerina", packageName = "email", moduleName = "email"} 62 | ] 63 | 64 | [[package]] 65 | org = "ballerina" 66 | name = "file" 67 | version = "1.10.0" 68 | dependencies = [ 69 | {org = "ballerina", name = "io"}, 70 | {org = "ballerina", name = "jballerina.java"}, 71 | {org = "ballerina", name = "os"}, 72 | {org = "ballerina", name = "time"} 73 | ] 74 | 75 | [[package]] 76 | org = "ballerina" 77 | name = "http" 78 | version = "2.12.1" 79 | dependencies = [ 80 | {org = "ballerina", name = "auth"}, 81 | {org = "ballerina", name = "cache"}, 82 | {org = "ballerina", name = "constraint"}, 83 | {org = "ballerina", name = "crypto"}, 84 | {org = "ballerina", name = "file"}, 85 | {org = "ballerina", name = "io"}, 86 | {org = "ballerina", name = "jballerina.java"}, 87 | {org = "ballerina", name = "jwt"}, 88 | {org = "ballerina", name = "lang.array"}, 89 | {org = "ballerina", name = "lang.decimal"}, 90 | {org = "ballerina", name = "lang.int"}, 91 | {org = "ballerina", name = "lang.regexp"}, 92 | {org = "ballerina", name = "lang.runtime"}, 93 | {org = "ballerina", name = "lang.string"}, 94 | {org = "ballerina", name = "lang.value"}, 95 | {org = "ballerina", name = "log"}, 96 | {org = "ballerina", name = "mime"}, 97 | {org = "ballerina", name = "oauth2"}, 98 | {org = "ballerina", name = "observe"}, 99 | {org = "ballerina", name = "time"}, 100 | {org = "ballerina", name = "url"} 101 | ] 102 | modules = [ 103 | {org = "ballerina", packageName = "http", moduleName = "http"}, 104 | {org = "ballerina", packageName = "http", moduleName = "http.httpscerr"} 105 | ] 106 | 107 | [[package]] 108 | org = "ballerina" 109 | name = "io" 110 | version = "1.6.1" 111 | dependencies = [ 112 | {org = "ballerina", name = "jballerina.java"}, 113 | {org = "ballerina", name = "lang.value"} 114 | ] 115 | 116 | [[package]] 117 | org = "ballerina" 118 | name = "jballerina.java" 119 | version = "0.0.0" 120 | 121 | [[package]] 122 | org = "ballerina" 123 | name = "jwt" 124 | version = "2.13.0" 125 | dependencies = [ 126 | {org = "ballerina", name = "cache"}, 127 | {org = "ballerina", name = "crypto"}, 128 | {org = "ballerina", name = "io"}, 129 | {org = "ballerina", name = "jballerina.java"}, 130 | {org = "ballerina", name = "lang.int"}, 131 | {org = "ballerina", name = "lang.string"}, 132 | {org = "ballerina", name = "log"}, 133 | {org = "ballerina", name = "time"} 134 | ] 135 | 136 | [[package]] 137 | org = "ballerina" 138 | name = "lang.__internal" 139 | version = "0.0.0" 140 | dependencies = [ 141 | {org = "ballerina", name = "jballerina.java"}, 142 | {org = "ballerina", name = "lang.object"} 143 | ] 144 | 145 | [[package]] 146 | org = "ballerina" 147 | name = "lang.array" 148 | version = "0.0.0" 149 | dependencies = [ 150 | {org = "ballerina", name = "jballerina.java"}, 151 | {org = "ballerina", name = "lang.__internal"} 152 | ] 153 | 154 | [[package]] 155 | org = "ballerina" 156 | name = "lang.decimal" 157 | version = "0.0.0" 158 | dependencies = [ 159 | {org = "ballerina", name = "jballerina.java"} 160 | ] 161 | 162 | [[package]] 163 | org = "ballerina" 164 | name = "lang.int" 165 | version = "0.0.0" 166 | dependencies = [ 167 | {org = "ballerina", name = "jballerina.java"}, 168 | {org = "ballerina", name = "lang.__internal"}, 169 | {org = "ballerina", name = "lang.object"} 170 | ] 171 | 172 | [[package]] 173 | org = "ballerina" 174 | name = "lang.object" 175 | version = "0.0.0" 176 | 177 | [[package]] 178 | org = "ballerina" 179 | name = "lang.regexp" 180 | version = "0.0.0" 181 | dependencies = [ 182 | {org = "ballerina", name = "jballerina.java"} 183 | ] 184 | 185 | [[package]] 186 | org = "ballerina" 187 | name = "lang.runtime" 188 | version = "0.0.0" 189 | dependencies = [ 190 | {org = "ballerina", name = "jballerina.java"} 191 | ] 192 | 193 | [[package]] 194 | org = "ballerina" 195 | name = "lang.string" 196 | version = "0.0.0" 197 | dependencies = [ 198 | {org = "ballerina", name = "jballerina.java"}, 199 | {org = "ballerina", name = "lang.regexp"} 200 | ] 201 | 202 | [[package]] 203 | org = "ballerina" 204 | name = "lang.value" 205 | version = "0.0.0" 206 | dependencies = [ 207 | {org = "ballerina", name = "jballerina.java"} 208 | ] 209 | 210 | [[package]] 211 | org = "ballerina" 212 | name = "log" 213 | version = "2.10.0" 214 | dependencies = [ 215 | {org = "ballerina", name = "io"}, 216 | {org = "ballerina", name = "jballerina.java"}, 217 | {org = "ballerina", name = "lang.value"}, 218 | {org = "ballerina", name = "observe"} 219 | ] 220 | 221 | [[package]] 222 | org = "ballerina" 223 | name = "mime" 224 | version = "2.10.0" 225 | dependencies = [ 226 | {org = "ballerina", name = "io"}, 227 | {org = "ballerina", name = "jballerina.java"}, 228 | {org = "ballerina", name = "lang.int"}, 229 | {org = "ballerina", name = "log"} 230 | ] 231 | 232 | [[package]] 233 | org = "ballerina" 234 | name = "oauth2" 235 | version = "2.12.0" 236 | dependencies = [ 237 | {org = "ballerina", name = "cache"}, 238 | {org = "ballerina", name = "crypto"}, 239 | {org = "ballerina", name = "jballerina.java"}, 240 | {org = "ballerina", name = "log"}, 241 | {org = "ballerina", name = "time"}, 242 | {org = "ballerina", name = "url"} 243 | ] 244 | 245 | [[package]] 246 | org = "ballerina" 247 | name = "observe" 248 | version = "1.3.0" 249 | dependencies = [ 250 | {org = "ballerina", name = "jballerina.java"} 251 | ] 252 | 253 | [[package]] 254 | org = "ballerina" 255 | name = "os" 256 | version = "1.8.0" 257 | dependencies = [ 258 | {org = "ballerina", name = "io"}, 259 | {org = "ballerina", name = "jballerina.java"} 260 | ] 261 | 262 | [[package]] 263 | org = "ballerina" 264 | name = "task" 265 | version = "2.5.0" 266 | dependencies = [ 267 | {org = "ballerina", name = "jballerina.java"}, 268 | {org = "ballerina", name = "time"} 269 | ] 270 | 271 | [[package]] 272 | org = "ballerina" 273 | name = "time" 274 | version = "2.5.0" 275 | dependencies = [ 276 | {org = "ballerina", name = "jballerina.java"} 277 | ] 278 | 279 | [[package]] 280 | org = "ballerina" 281 | name = "url" 282 | version = "2.4.0" 283 | dependencies = [ 284 | {org = "ballerina", name = "jballerina.java"} 285 | ] 286 | 287 | [[package]] 288 | org = "ballerina" 289 | name = "uuid" 290 | version = "1.8.0" 291 | dependencies = [ 292 | {org = "ballerina", name = "crypto"}, 293 | {org = "ballerina", name = "jballerina.java"}, 294 | {org = "ballerina", name = "lang.int"}, 295 | {org = "ballerina", name = "time"} 296 | ] 297 | modules = [ 298 | {org = "ballerina", packageName = "uuid", moduleName = "uuid"} 299 | ] 300 | 301 | [[package]] 302 | org = "ballerinai" 303 | name = "observe" 304 | version = "0.0.0" 305 | dependencies = [ 306 | {org = "ballerina", name = "jballerina.java"}, 307 | {org = "ballerina", name = "observe"} 308 | ] 309 | modules = [ 310 | {org = "ballerinai", packageName = "observe", moduleName = "observe"} 311 | ] 312 | 313 | [[package]] 314 | org = "ballerinax" 315 | name = "mongodb" 316 | version = "5.0.0" 317 | dependencies = [ 318 | {org = "ballerina", name = "crypto"}, 319 | {org = "ballerina", name = "jballerina.java"}, 320 | {org = "ballerina", name = "log"} 321 | ] 322 | modules = [ 323 | {org = "ballerinax", packageName = "mongodb", moduleName = "mongodb"} 324 | ] 325 | 326 | [[package]] 327 | org = "niranga_nayanajith" 328 | name = "backend" 329 | version = "0.1.0" 330 | dependencies = [ 331 | {org = "ballerina", name = "email"}, 332 | {org = "ballerina", name = "http"}, 333 | {org = "ballerina", name = "uuid"}, 334 | {org = "ballerinai", name = "observe"}, 335 | {org = "ballerinax", name = "mongodb"} 336 | ] 337 | modules = [ 338 | {org = "niranga_nayanajith", packageName = "backend", moduleName = "backend"} 339 | ] 340 | 341 | -------------------------------------------------------------------------------- /public/profile.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Profile Template 9 | 10 | 13 | 15 | 17 | 18 | 19 | 20 | 23 | 24 | 25 | 28 | 31 | 32 | 33 | 35 | 36 | 37 | 38 | 40 | 41 | 42 | 43 | 44 | 45 | 68 | 69 |
70 |

71 | FeedBack 72 |

73 |
74 |
75 |
76 | 87 |
88 |
89 |
90 |
92 |
93 | 94 |
95 |
96 |
97 |
98 |
99 | 103 | 104 |
105 | 106 |
107 | 110 |
111 |
112 | 115 | 118 |
119 |
120 |   123 | 126 |
127 |
128 |
129 |
130 |
131 | 164 |
165 |
166 |
167 | 168 |
169 | 170 | 171 | 172 | 174 | 175 | 177 | 180 | 181 | 182 | -------------------------------------------------------------------------------- /public/assets/vendor/bootstrap/css/bootstrap-reboot.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v5.3.2 (https://getbootstrap.com/) 3 | * Copyright 2011-2023 The Bootstrap Authors 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | */:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-primary-text-emphasis:#052c65;--bs-secondary-text-emphasis:#2b2f32;--bs-success-text-emphasis:#0a3622;--bs-info-text-emphasis:#055160;--bs-warning-text-emphasis:#664d03;--bs-danger-text-emphasis:#58151c;--bs-light-text-emphasis:#495057;--bs-dark-text-emphasis:#495057;--bs-primary-bg-subtle:#cfe2ff;--bs-secondary-bg-subtle:#e2e3e5;--bs-success-bg-subtle:#d1e7dd;--bs-info-bg-subtle:#cff4fc;--bs-warning-bg-subtle:#fff3cd;--bs-danger-bg-subtle:#f8d7da;--bs-light-bg-subtle:#fcfcfd;--bs-dark-bg-subtle:#ced4da;--bs-primary-border-subtle:#9ec5fe;--bs-secondary-border-subtle:#c4c8cb;--bs-success-border-subtle:#a3cfbb;--bs-info-border-subtle:#9eeaf9;--bs-warning-border-subtle:#ffe69c;--bs-danger-border-subtle:#f1aeb5;--bs-light-border-subtle:#e9ecef;--bs-dark-border-subtle:#adb5bd;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-color-rgb:33,37,41;--bs-body-bg:#fff;--bs-body-bg-rgb:255,255,255;--bs-emphasis-color:#000;--bs-emphasis-color-rgb:0,0,0;--bs-secondary-color:rgba(33, 37, 41, 0.75);--bs-secondary-color-rgb:33,37,41;--bs-secondary-bg:#e9ecef;--bs-secondary-bg-rgb:233,236,239;--bs-tertiary-color:rgba(33, 37, 41, 0.5);--bs-tertiary-color-rgb:33,37,41;--bs-tertiary-bg:#f8f9fa;--bs-tertiary-bg-rgb:248,249,250;--bs-heading-color:inherit;--bs-link-color:#0d6efd;--bs-link-color-rgb:13,110,253;--bs-link-decoration:underline;--bs-link-hover-color:#0a58ca;--bs-link-hover-color-rgb:10,88,202;--bs-code-color:#d63384;--bs-highlight-color:#212529;--bs-highlight-bg:#fff3cd;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-xxl:2rem;--bs-border-radius-2xl:var(--bs-border-radius-xxl);--bs-border-radius-pill:50rem;--bs-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-box-shadow-sm:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-box-shadow-lg:0 1rem 3rem rgba(0, 0, 0, 0.175);--bs-box-shadow-inset:inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-focus-ring-width:0.25rem;--bs-focus-ring-opacity:0.25;--bs-focus-ring-color:rgba(13, 110, 253, 0.25);--bs-form-valid-color:#198754;--bs-form-valid-border-color:#198754;--bs-form-invalid-color:#dc3545;--bs-form-invalid-border-color:#dc3545}[data-bs-theme=dark]{color-scheme:dark;--bs-body-color:#dee2e6;--bs-body-color-rgb:222,226,230;--bs-body-bg:#212529;--bs-body-bg-rgb:33,37,41;--bs-emphasis-color:#fff;--bs-emphasis-color-rgb:255,255,255;--bs-secondary-color:rgba(222, 226, 230, 0.75);--bs-secondary-color-rgb:222,226,230;--bs-secondary-bg:#343a40;--bs-secondary-bg-rgb:52,58,64;--bs-tertiary-color:rgba(222, 226, 230, 0.5);--bs-tertiary-color-rgb:222,226,230;--bs-tertiary-bg:#2b3035;--bs-tertiary-bg-rgb:43,48,53;--bs-primary-text-emphasis:#6ea8fe;--bs-secondary-text-emphasis:#a7acb1;--bs-success-text-emphasis:#75b798;--bs-info-text-emphasis:#6edff6;--bs-warning-text-emphasis:#ffda6a;--bs-danger-text-emphasis:#ea868f;--bs-light-text-emphasis:#f8f9fa;--bs-dark-text-emphasis:#dee2e6;--bs-primary-bg-subtle:#031633;--bs-secondary-bg-subtle:#161719;--bs-success-bg-subtle:#051b11;--bs-info-bg-subtle:#032830;--bs-warning-bg-subtle:#332701;--bs-danger-bg-subtle:#2c0b0e;--bs-light-bg-subtle:#343a40;--bs-dark-bg-subtle:#1a1d20;--bs-primary-border-subtle:#084298;--bs-secondary-border-subtle:#41464b;--bs-success-border-subtle:#0f5132;--bs-info-border-subtle:#087990;--bs-warning-border-subtle:#997404;--bs-danger-border-subtle:#842029;--bs-light-border-subtle:#495057;--bs-dark-border-subtle:#343a40;--bs-heading-color:inherit;--bs-link-color:#6ea8fe;--bs-link-hover-color:#8bb9fe;--bs-link-color-rgb:110,168,254;--bs-link-hover-color-rgb:139,185,254;--bs-code-color:#e685b5;--bs-highlight-color:#dee2e6;--bs-highlight-bg:#664d03;--bs-border-color:#495057;--bs-border-color-translucent:rgba(255, 255, 255, 0.15);--bs-form-valid-color:#75b798;--bs-form-valid-border-color:#75b798;--bs-form-invalid-color:#ea868f;--bs-form-invalid-border-color:#ea868f}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:var(--bs-border-width) solid;opacity:.25}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--bs-heading-color)}h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){h1{font-size:2.5rem}}h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){h2{font-size:2rem}}h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){h3{font-size:1.75rem}}h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){h4{font-size:1.5rem}}h5{font-size:1.25rem}h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:.1875em;color:var(--bs-highlight-color);background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,1));text-decoration:underline}a:hover{--bs-link-color-rgb:var(--bs-link-hover-color-rgb)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-secondary-color);text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important} 6 | /*# sourceMappingURL=bootstrap-reboot.min.css.map */ -------------------------------------------------------------------------------- /public/assets/vendor/bootstrap/css/bootstrap-reboot.rtl.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v5.3.2 (https://getbootstrap.com/) 3 | * Copyright 2011-2023 The Bootstrap Authors 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | */:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-primary-text-emphasis:#052c65;--bs-secondary-text-emphasis:#2b2f32;--bs-success-text-emphasis:#0a3622;--bs-info-text-emphasis:#055160;--bs-warning-text-emphasis:#664d03;--bs-danger-text-emphasis:#58151c;--bs-light-text-emphasis:#495057;--bs-dark-text-emphasis:#495057;--bs-primary-bg-subtle:#cfe2ff;--bs-secondary-bg-subtle:#e2e3e5;--bs-success-bg-subtle:#d1e7dd;--bs-info-bg-subtle:#cff4fc;--bs-warning-bg-subtle:#fff3cd;--bs-danger-bg-subtle:#f8d7da;--bs-light-bg-subtle:#fcfcfd;--bs-dark-bg-subtle:#ced4da;--bs-primary-border-subtle:#9ec5fe;--bs-secondary-border-subtle:#c4c8cb;--bs-success-border-subtle:#a3cfbb;--bs-info-border-subtle:#9eeaf9;--bs-warning-border-subtle:#ffe69c;--bs-danger-border-subtle:#f1aeb5;--bs-light-border-subtle:#e9ecef;--bs-dark-border-subtle:#adb5bd;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-color-rgb:33,37,41;--bs-body-bg:#fff;--bs-body-bg-rgb:255,255,255;--bs-emphasis-color:#000;--bs-emphasis-color-rgb:0,0,0;--bs-secondary-color:rgba(33, 37, 41, 0.75);--bs-secondary-color-rgb:33,37,41;--bs-secondary-bg:#e9ecef;--bs-secondary-bg-rgb:233,236,239;--bs-tertiary-color:rgba(33, 37, 41, 0.5);--bs-tertiary-color-rgb:33,37,41;--bs-tertiary-bg:#f8f9fa;--bs-tertiary-bg-rgb:248,249,250;--bs-heading-color:inherit;--bs-link-color:#0d6efd;--bs-link-color-rgb:13,110,253;--bs-link-decoration:underline;--bs-link-hover-color:#0a58ca;--bs-link-hover-color-rgb:10,88,202;--bs-code-color:#d63384;--bs-highlight-color:#212529;--bs-highlight-bg:#fff3cd;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-xxl:2rem;--bs-border-radius-2xl:var(--bs-border-radius-xxl);--bs-border-radius-pill:50rem;--bs-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-box-shadow-sm:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-box-shadow-lg:0 1rem 3rem rgba(0, 0, 0, 0.175);--bs-box-shadow-inset:inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-focus-ring-width:0.25rem;--bs-focus-ring-opacity:0.25;--bs-focus-ring-color:rgba(13, 110, 253, 0.25);--bs-form-valid-color:#198754;--bs-form-valid-border-color:#198754;--bs-form-invalid-color:#dc3545;--bs-form-invalid-border-color:#dc3545}[data-bs-theme=dark]{color-scheme:dark;--bs-body-color:#dee2e6;--bs-body-color-rgb:222,226,230;--bs-body-bg:#212529;--bs-body-bg-rgb:33,37,41;--bs-emphasis-color:#fff;--bs-emphasis-color-rgb:255,255,255;--bs-secondary-color:rgba(222, 226, 230, 0.75);--bs-secondary-color-rgb:222,226,230;--bs-secondary-bg:#343a40;--bs-secondary-bg-rgb:52,58,64;--bs-tertiary-color:rgba(222, 226, 230, 0.5);--bs-tertiary-color-rgb:222,226,230;--bs-tertiary-bg:#2b3035;--bs-tertiary-bg-rgb:43,48,53;--bs-primary-text-emphasis:#6ea8fe;--bs-secondary-text-emphasis:#a7acb1;--bs-success-text-emphasis:#75b798;--bs-info-text-emphasis:#6edff6;--bs-warning-text-emphasis:#ffda6a;--bs-danger-text-emphasis:#ea868f;--bs-light-text-emphasis:#f8f9fa;--bs-dark-text-emphasis:#dee2e6;--bs-primary-bg-subtle:#031633;--bs-secondary-bg-subtle:#161719;--bs-success-bg-subtle:#051b11;--bs-info-bg-subtle:#032830;--bs-warning-bg-subtle:#332701;--bs-danger-bg-subtle:#2c0b0e;--bs-light-bg-subtle:#343a40;--bs-dark-bg-subtle:#1a1d20;--bs-primary-border-subtle:#084298;--bs-secondary-border-subtle:#41464b;--bs-success-border-subtle:#0f5132;--bs-info-border-subtle:#087990;--bs-warning-border-subtle:#997404;--bs-danger-border-subtle:#842029;--bs-light-border-subtle:#495057;--bs-dark-border-subtle:#343a40;--bs-heading-color:inherit;--bs-link-color:#6ea8fe;--bs-link-hover-color:#8bb9fe;--bs-link-color-rgb:110,168,254;--bs-link-hover-color-rgb:139,185,254;--bs-code-color:#e685b5;--bs-highlight-color:#dee2e6;--bs-highlight-bg:#664d03;--bs-border-color:#495057;--bs-border-color-translucent:rgba(255, 255, 255, 0.15);--bs-form-valid-color:#75b798;--bs-form-valid-border-color:#75b798;--bs-form-invalid-color:#ea868f;--bs-form-invalid-border-color:#ea868f}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:var(--bs-border-width) solid;opacity:.25}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--bs-heading-color)}h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){h1{font-size:2.5rem}}h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){h2{font-size:2rem}}h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){h3{font-size:1.75rem}}h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){h4{font-size:1.5rem}}h5{font-size:1.25rem}h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-right:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-right:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:.1875em;color:var(--bs-highlight-color);background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,1));text-decoration:underline}a:hover{--bs-link-color-rgb:var(--bs-link-hover-color-rgb)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-secondary-color);text-align:right}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:right;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:right}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=email],[type=number],[type=tel],[type=url]{direction:ltr}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important} 6 | /*# sourceMappingURL=bootstrap-reboot.rtl.min.css.map */ -------------------------------------------------------------------------------- /public/css/pic (1).css: -------------------------------------------------------------------------------- 1 | -----@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap'); 2 | 3 | *{ 4 | margin: 0; 5 | padding: 0; 6 | box-sizing: border-box; 7 | list-style: none; 8 | text-decoration: none; 9 | font-family: 'Poppins', sans-serif; 10 | } 11 | :root{ 12 | --background: #d1deec; 13 | --foreground: #f1f3f5; 14 | --white: #fff; 15 | --black: #000; 16 | --gray: #6e6e6e; 17 | --shadow: #76767663; 18 | --border: #cfcfcf; 19 | } 20 | .dark-color{ 21 | --background: #222230; 22 | --foreground: #42435c; 23 | --white: #2b2c44; 24 | --black: #eeecff; 25 | --gray: #d5dfd5; 26 | --shadow: #00000063; 27 | --border: #3f4172; 28 | } 29 | 30 | .darkTheme.button-Active span{ 31 | margin-left: 16px; 32 | } 33 | 34 | body{ 35 | background: var(--background); 36 | -webkit-text-size-adjust: 100%; 37 | -webkit-tap-highlight-color: #ff0000; 38 | } 39 | button:focus, 40 | input:focus{ 41 | border: none; 42 | outline: none; 43 | } 44 | h1,h2,h3,h4,h5,h6,b{ 45 | color: var(--black); 46 | } 47 | 48 | a:focus, a:hover{ 49 | text-decoration: none; 50 | color: inherit; 51 | } 52 | 53 | /* header section style start here */ 54 | 55 | header{ 56 | width: 100%; 57 | height: 150px; 58 | display: flex; 59 | align-items: center; 60 | justify-content: center; 61 | } 62 | .header-container{ 63 | width: 95%; 64 | background: var(--white); 65 | height: 100px; 66 | overflow: hidden; 67 | padding: 20px; 68 | border-radius: 20px; 69 | box-shadow: 0 2px 5px 0 var(--shadow); 70 | } 71 | .header-wrapper{ 72 | display: flex; 73 | width: 100%; 74 | height: 100%; 75 | align-items: center; 76 | padding: 0 8px; 77 | justify-content: space-between; 78 | } 79 | .logoBox{ 80 | width: 7%; 81 | } 82 | .logoBox img{ 83 | width: 60px; 84 | } 85 | .searchBox{ 86 | width: 38%; 87 | position: relative; 88 | } 89 | .iconBox1{ 90 | width: 25%; 91 | display: flex; 92 | justify-content: space-between; 93 | padding: 0 25px; 94 | border-right: 2px solid var(--border); 95 | } 96 | .iconBox2{ 97 | width: 25%; 98 | display: flex; 99 | justify-content: space-between; 100 | padding: 0 25px; 101 | position: relative; 102 | } 103 | .searchBox input{ 104 | padding: 15px 45px 15px 15px; 105 | border-radius: 50px; 106 | width: 100%; 107 | background: var(--foreground); 108 | border: none; 109 | box-shadow: 0 2px 5px 0 var(--shadow); 110 | color: var(--black); 111 | } 112 | .searchBox i{ 113 | position: absolute; 114 | right: 20px; 115 | top: 19px; 116 | color: var(--black); 117 | cursor: pointer; 118 | transition: .4s; 119 | } 120 | .searchBox i:hover{ 121 | color: #ff0000; 122 | } 123 | 124 | .iconBox1 i, 125 | .iconBox2 i{ 126 | font-size: 20px; 127 | background: transparent; 128 | padding: 10px; 129 | border-radius: 10px; 130 | color: #ff0000; 131 | transition: .4s; 132 | } 133 | .iconBox1 i:hover, 134 | .iconBox2 i:hover{ 135 | background: #ff0000; 136 | color: #d1deec; 137 | cursor: pointer; 138 | } 139 | .iconBox2 label{ 140 | width: 45px; 141 | height: 45px; 142 | overflow: hidden; 143 | border-radius: 50px; 144 | } 145 | .iconBox2 label img{ 146 | width: 100%; 147 | } 148 | .iconBox2 .fa-caret-down{ 149 | position: absolute; 150 | right: 0; 151 | font-size: 16px; 152 | top: 7px; 153 | } 154 | .iconBox2 .fa-caret-down:hover{ 155 | background: transparent; 156 | } 157 | 158 | 159 | /* header section style end here */ 160 | 161 | /* home section start here */ 162 | 163 | .home{ 164 | display: flex; 165 | justify-content: center; 166 | } 167 | .container{ 168 | width: 95%; 169 | } 170 | .home-weapper{ 171 | width: 100%; 172 | display: flex; 173 | justify-content: space-between; 174 | } 175 | .home-left{ 176 | width: 20%; 177 | background: var(--white); 178 | box-shadow: 0 2px 5px 0 var(--shadow); 179 | border-radius: 20px; 180 | overflow: hidden; 181 | display: flex; 182 | flex-direction: column; 183 | padding: 15px; 184 | margin-bottom: 20px; 185 | } 186 | 187 | .profile{ 188 | overflow: hidden; 189 | display: flex; 190 | align-items: center; 191 | cursor: pointer; 192 | } 193 | .profile img{ 194 | float: left; 195 | width: 80px; 196 | height: 80px; 197 | border-radius: 50%; 198 | margin-bottom: 15px; 199 | } 200 | .profile h3{ 201 | font-size: 18px; 202 | font-weight: bold; 203 | color: var(--black); 204 | text-transform: capitalize; 205 | } 206 | 207 | .pages, 208 | .group, 209 | .games{ 210 | width: 100%; 211 | display: flex; 212 | flex-direction: column; 213 | margin-bottom: 30px; 214 | } 215 | .mini-headign{ 216 | text-transform: uppercase; 217 | color: var(--gray); 218 | margin-bottom: 15px; 219 | } 220 | .pages label, 221 | .group label, 222 | .games label{ 223 | margin-bottom: 15px; 224 | display: flex; 225 | align-items: center; 226 | cursor: pointer; 227 | } 228 | .pages label img, 229 | .group label img, 230 | .games label img{ 231 | width: 35px; 232 | margin-right: 8px; 233 | box-shadow: 0 2px 5px 0 var(--shadow); 234 | padding: 5px; 235 | border-radius: 8px; 236 | } 237 | .pages label span, 238 | .group label span, 239 | .games label span{ 240 | color: var(--gray); 241 | font-size: 14px; 242 | } 243 | .see-more-btn{ 244 | padding: 8px; 245 | background: var(--white); 246 | border: none; 247 | box-shadow: 0 2px 6px 0 var(--shadow); 248 | border-radius: 50px; 249 | color: #ff0000; 250 | font-weight: 600; 251 | font-size: 15px; 252 | margin-top: 10px; 253 | transition: .4s; 254 | } 255 | .see-more-btn i{ 256 | font-size: 12px; 257 | margin-left: 5px; 258 | } 259 | .see-more-btn:hover{ 260 | background: #f1f3f5; 261 | box-shadow: 0 5px 6px 0 #76767663; 262 | cursor: pointer; 263 | } 264 | .explore{ 265 | display: flex; 266 | flex-direction: column; 267 | } 268 | .explore a{ 269 | color: #ff0000; 270 | margin-bottom: 15px; 271 | font-weight: 600; 272 | } 273 | .explore a:hover{ 274 | color: #ff0000; 275 | } 276 | .explore a i{ 277 | margin-right: 10px; 278 | width: 25px; 279 | height: 25px; 280 | box-shadow: 0 2px 5px 0 var(--shadow); 281 | border-radius: 8px; 282 | text-align: center; 283 | line-height: 25px; 284 | transition: .4s; 285 | } 286 | .explore > div{ 287 | display: flex; 288 | align-items: center; 289 | margin-bottom: 15px; 290 | font-weight: 600; 291 | color: #ff0000; 292 | } 293 | .darkTheme{ 294 | width: 40px; 295 | height: 24px; 296 | background: #ff0000; 297 | margin-right: 12px; 298 | border-radius: 50px; 299 | position: relative; 300 | display: flex; 301 | align-items: center; 302 | cursor: pointer; 303 | } 304 | .darkTheme span{ 305 | position: absolute; 306 | width: 16px; 307 | height: 16px; 308 | background: white; 309 | border-radius: 50px; 310 | left: 4px; 311 | transition: .5s; 312 | } 313 | 314 | 315 | 316 | /* home section end here */ 317 | 318 | /* Home Center Section */ 319 | .home-center { 320 | width: 55%; 321 | background-color: #fff; 322 | padding: 20px; 323 | border-radius: 10px; 324 | box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); 325 | } 326 | 327 | .home-center-wrapper { 328 | display: flex; 329 | flex-direction: column; 330 | } 331 | 332 | .messenger { 333 | margin-bottom: 20px; 334 | } 335 | 336 | .messenger-search { 337 | display: flex; 338 | justify-content: space-between; 339 | align-items: center; 340 | margin-bottom: 15px; 341 | } 342 | 343 | .messenger-search h4 { 344 | font-size: 18px; 345 | font-weight: bold; 346 | color: #333; 347 | } 348 | 349 | .messenger-search input { 350 | width: 60%; 351 | padding: 10px; 352 | border: 1px solid #ddd; 353 | border-radius: 5px; 354 | } 355 | 356 | .messenger-search button { 357 | padding: 10px 15px; 358 | background-color: #ff4d4d; 359 | border: none; 360 | color: white; 361 | border-radius: 5px; 362 | cursor: pointer; 363 | } 364 | 365 | .messenger-search button:hover { 366 | background-color: #ff3333; 367 | } 368 | 369 | #map { 370 | width: 100%; 371 | height: 400px; 372 | margin-top: 20px; 373 | border-radius: 10px; 374 | border: 1px solid #ddd; 375 | } 376 | 377 | #cityDetail { 378 | margin-top: 20px; 379 | font-size: 16px; 380 | color: #555; 381 | } 382 | 383 | /* Home Right Section */ 384 | .home-right { 385 | width: 20%; 386 | background-color: #fff; 387 | padding: 20px; 388 | border-radius: 10px; 389 | box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); 390 | } 391 | 392 | .home-right-wrapper { 393 | display: flex; 394 | flex-direction: column; 395 | } 396 | 397 | .event-friend { 398 | margin-top: 20px; 399 | } 400 | 401 | .friend h3 { 402 | font-size: 18px; 403 | font-weight: bold; 404 | color: #333; 405 | margin-bottom: 10px; 406 | } 407 | 408 | .friend .container { 409 | display: flex; 410 | justify-content: space-between; 411 | align-items: center; 412 | margin-bottom: 20px; 413 | } 414 | 415 | .friend button { 416 | background-color: #ff4d4d; 417 | color: white; 418 | padding: 8px 15px; 419 | border: none; 420 | border-radius: 5px; 421 | margin-right: 10px; 422 | cursor: pointer; 423 | } 424 | 425 | .friend button:hover { 426 | background-color: #ff3333; 427 | } 428 | 429 | /* Dark Mode Styles */ 430 | .dark-color { 431 | background-color: #121212; 432 | color: #ddd; 433 | } 434 | 435 | .button-Active { 436 | background-color: #ff3333 !important; 437 | } 438 | 439 | button.darkTheme { 440 | background-color: #ff4d4d; 441 | color: white; 442 | padding: 10px; 443 | border-radius: 5px; 444 | border: none; 445 | cursor: pointer; 446 | } 447 | 448 | button.darkTheme:hover { 449 | background-color: #ff3333; 450 | } 451 | 452 | hr { 453 | border-top: 1px solid #ddd; 454 | margin: 20px 0; 455 | } 456 | .shop-card { 457 | background-color: #ffe5e5; /* Light red background */ 458 | border-radius: 8px; 459 | box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); 460 | padding: 20px; 461 | margin: 15px 0; 462 | max-width: 300px; 463 | border: 2px solid #ff4d4d; /* Red border */ 464 | } 465 | 466 | .shop-card h3 { 467 | font-size: 1.5em; 468 | color: #b30000; /* Dark red text */ 469 | margin-bottom: 10px; 470 | } 471 | 472 | .shop-card p { 473 | font-size: 1em; 474 | color: #800000; /* Deep red text for paragraphs */ 475 | margin-bottom: 8px; 476 | } 477 | 478 | .shop-card a { 479 | color: #ff3333; /* Bright red for links */ 480 | text-decoration: none; 481 | font-weight: bold; 482 | } 483 | 484 | .shop-card a:hover { 485 | text-decoration: underline; 486 | color: #cc0000; /* Darker red on hover */ 487 | } 488 | 489 | /* Responsive Styles */ 490 | @media screen and (max-width: 768px) { 491 | .home { 492 | flex-direction: column; 493 | } 494 | 495 | .home-left, .home-center, .home-right { 496 | width: 100%; 497 | margin-bottom: 20px; 498 | } 499 | } -------------------------------------------------------------------------------- /backend/main.bal: -------------------------------------------------------------------------------- 1 | import ballerina/email; 2 | import ballerina/http; 3 | import ballerina/uuid; 4 | import ballerinax/mongodb; 5 | 6 | configurable string host = "localhost"; 7 | configurable int port = 27017; 8 | 9 | final mongodb:Client mongoDb = check new ({ 10 | connection: { 11 | serverAddress: { 12 | host, 13 | port 14 | } 15 | } 16 | }); 17 | 18 | // Configure CORS globally 19 | @http:ServiceConfig { 20 | cors: { 21 | allowOrigins: ["*"], 22 | allowCredentials: true, 23 | allowMethods: ["POST", "GET"], 24 | allowHeaders: ["Content-Type"], 25 | exposeHeaders: ["Content-Length"], 26 | maxAge: 600 27 | } 28 | } 29 | 30 | //get city data from database this works on 9092 port 31 | service /api on new http:Listener(9092) { 32 | 33 | private final mongodb:Database city; 34 | 35 | function init() returns error? { 36 | self.city = check mongoDb->getDatabase("city"); 37 | } 38 | 39 | // Resource to get a single user by city 40 | resource function get city/[string city]() returns city_names|error { 41 | mongodb:Collection cityCollection = check self.city->getCollection("city"); 42 | stream resultStream = check cityCollection->find({city: city}); 43 | record {city_names value;}|error? result = resultStream.next(); 44 | 45 | if result is error? { 46 | return error(string `Cannot find the user with city: ${city}`); 47 | } 48 | return result.value; 49 | } 50 | 51 | // Resource to get all cities 52 | resource function get cities() returns city_names[]|error { 53 | mongodb:Collection cityCollection = check self.city->getCollection("city"); 54 | stream resultStream = check cityCollection->find({}); 55 | city_names[] citiesList = []; 56 | 57 | check from city_names city in resultStream 58 | do { 59 | citiesList.push(city); 60 | }; 61 | 62 | return citiesList; 63 | } 64 | } 65 | 66 | // Configure CORS globally 67 | @http:ServiceConfig { 68 | cors: { 69 | allowOrigins: ["*"], 70 | allowCredentials: true, 71 | allowMethods: ["POST", "GET"], 72 | allowHeaders: ["Content-Type"], 73 | exposeHeaders: ["Content-Length"], 74 | maxAge: 600 75 | } 76 | } 77 | //this use to get data from shop database and this works on 9091 port 78 | service /api on new http:Listener(9091) { 79 | 80 | private final mongodb:Database shopsDb; 81 | 82 | function init() returns error? { 83 | // Initialize shops database 84 | self.shopsDb = check mongoDb->getDatabase("shops"); 85 | } 86 | 87 | // Resource to get shops by city 88 | resource function get shops/[string city]() returns shop_details[]|error { 89 | mongodb:Collection shopsCollection = check self.shopsDb->getCollection("shops"); 90 | 91 | // Query shops by city name 92 | stream resultStream = check shopsCollection->find({city: city}); 93 | shop_details[] shopsList = []; 94 | 95 | check from shop_details shop in resultStream 96 | do { 97 | shopsList.push(shop); 98 | }; 99 | 100 | return shopsList; 101 | } 102 | } 103 | 104 | @http:ServiceConfig { 105 | cors: { 106 | allowOrigins: ["*"], 107 | allowCredentials: true, 108 | allowMethods: ["POST", "GET"], 109 | allowHeaders: ["Content-Type"], 110 | exposeHeaders: ["Content-Length"], 111 | maxAge: 600 112 | } 113 | } 114 | 115 | //this is the functions use to loging and signing this works on 9090 port 116 | service /api on new http:Listener(9090) { 117 | 118 | private final mongodb:Database userDb; 119 | 120 | // Initialize the MongoDB connection to the "userDb" database 121 | function init() returns error? { 122 | self.userDb = check mongoDb->getDatabase("userDb"); 123 | } 124 | 125 | // Resource to handle user signup and send confirmation email 126 | resource function post signup(UserInput input) returns http:Response|error { 127 | mongodb:Collection usersCollection = check self.userDb->getCollection("users"); 128 | 129 | // Check if username or email already exists 130 | stream findResult = check usersCollection->find({ 131 | \$or: [{username: input.username}, {email: input.email}] 132 | }); 133 | User[] existingUsers = check from User user in findResult 134 | select user; 135 | 136 | if existingUsers.length() > 0 { 137 | return error("Username or email already exists."); 138 | } 139 | 140 | // Set up SMTP Client (Configure your SMTP details properly) 141 | email:SmtpClient smtpClient = check new ("smtp.gmail.com", "nngeek195@gmail.com", "gnqt zacd ptak osja"); 142 | 143 | // Try to send the welcome email 144 | email:Message message = { 145 | to: [input.email ?: ""], 146 | subject: "Welcome to TOWO APP", 147 | body: "Dear " + input.username + ",\n\nWelcome to TOWO APP! We're glad to have you on board." 148 | }; 149 | 150 | // Try sending the email. If it fails, return error message and halt the signup process 151 | error? emailStatus = smtpClient->sendMessage(message); 152 | if emailStatus is error { 153 | http:Response response = new; 154 | response.statusCode = 400; 155 | response.setPayload({message: "Failed to send email. Please check the email address."}); 156 | return response; 157 | } 158 | 159 | // If email was successfully sent, store the user in the database 160 | string id = uuid:createType1AsString(); 161 | User user = { 162 | id: id, 163 | username: input.username, 164 | password: input.password, 165 | email: input.email ?: "" 166 | }; 167 | 168 | check usersCollection->insertOne(user); 169 | 170 | // Return success response 171 | http:Response response = new; 172 | response.setPayload({message: "Signup successful. Please proceed to login."}); 173 | return response; 174 | } 175 | 176 | // Resource to handle user login 177 | resource function post login(LoginInput input) returns http:Response|error { 178 | mongodb:Collection usersCollection = check self.userDb->getCollection("users"); 179 | 180 | // Check if username and password match the records 181 | stream findResult = check usersCollection->find({ 182 | username: input.username, 183 | password: input.password 184 | }); 185 | User[] users = check from User user in findResult 186 | select user; 187 | 188 | if users.length() == 0 { 189 | return error("Invalid username or password."); 190 | } 191 | 192 | // Login successful 193 | http:Response response = new; 194 | response.setPayload({message: "Login successful!"}); 195 | return response; 196 | } 197 | } 198 | 199 | @http:ServiceConfig { 200 | cors: { 201 | allowOrigins: ["*"], 202 | allowCredentials: true, 203 | allowMethods: ["POST", "GET"], 204 | allowHeaders: ["Content-Type"], 205 | exposeHeaders: ["Content-Length"], 206 | maxAge: 600 207 | } 208 | } 209 | //use to get idea from users 210 | service /api on new http:Listener(9094) { 211 | 212 | private final mongodb:Database idea; 213 | 214 | // Initialize the MongoDB connection to the "userDb" database 215 | function init() returns error? { 216 | self.idea = check mongoDb->getDatabase("idea"); 217 | } 218 | 219 | // Resource to handle user signup and send confirmation email 220 | resource function post msg(MsgInput input) returns http:Response|error { 221 | mongodb:Collection ideaCollection = check self.idea->getCollection("idea"); 222 | 223 | // Set up SMTP Client (Configure your SMTP details properly) 224 | email:SmtpClient smtpClient = check new ("smtp.gmail.com", "nngeek195@gmail.com", "gnqt zacd ptak osja"); 225 | 226 | // Try to send the welcome email 227 | email:Message message = { 228 | to: [input.email ?: ""], 229 | subject: "TOWO APP NOTIFICATION", 230 | body: "Dear " + input.username + ",\n\nThanks for your Feedback" 231 | }; 232 | 233 | // Try sending the email. If it fails, return error message and halt the signup process 234 | error? emailStatus = smtpClient->sendMessage(message); 235 | if emailStatus is error { 236 | http:Response response = new; 237 | response.statusCode = 400; 238 | response.setPayload({message: "Failed to send email."}); 239 | return response; 240 | } 241 | 242 | // If email was successfully sent, store the user in the database 243 | string id = uuid:createType1AsString(); 244 | Msg msg = { 245 | id: id, 246 | username: input.username, 247 | msg: input.msg, 248 | email: input.email ?: "" 249 | }; 250 | 251 | check ideaCollection->insertOne(msg); 252 | 253 | // Return success response 254 | http:Response response = new; 255 | response.setPayload({message: "successfull."}); 256 | return response; 257 | } 258 | } 259 | 260 | @http:ServiceConfig { 261 | cors: { 262 | allowOrigins: ["*"], 263 | allowCredentials: true, 264 | allowMethods: ["POST", "GET"], 265 | allowHeaders: ["Content-Type"], 266 | exposeHeaders: ["Content-Length"], 267 | maxAge: 600 268 | } 269 | } 270 | //use to give password to user when they foget it 271 | service /api on new http:Listener(9095) { 272 | 273 | private final mongodb:Database userDb; 274 | 275 | function init() returns error? { 276 | // Connect to the 'userDb' database 277 | self.userDb = check mongoDb->getDatabase("userDb"); 278 | } 279 | 280 | // Resource to handle "Forget Password" request 281 | resource function post foget(ReserPassUserInput input) returns http:Response|error { 282 | mongodb:Collection usersCollection = check self.userDb->getCollection("users"); 283 | 284 | // Query the MongoDB database for matching username and email 285 | stream resultStream = check usersCollection->find({ 286 | username: input.username, 287 | email: input.email 288 | }); 289 | 290 | User[] users = check from User user in resultStream 291 | select user; 292 | 293 | if users.length() == 0 { 294 | // No matching user found, return error response 295 | http:Response response = new; 296 | response.statusCode = 404; 297 | response.setPayload({message: "User not found with the given username and email."}); 298 | return response; 299 | } 300 | 301 | // Get the user's password 302 | User user = users[0]; 303 | string password = user.password; 304 | 305 | // Set up SMTP Client (Configure your SMTP details properly) 306 | email:SmtpClient smtpClient = check new ("smtp.gmail.com", "nngeek195@gmail.com", "gnqt zacd ptak osja"); 307 | 308 | // Create the email message with the user's password 309 | email:Message message = { 310 | to: [input.email], 311 | subject: "Your Password for TOWO APP", 312 | body: "Dear " + input.username + ",\n\nYour password is: " + password + "\n\nPlease keep it safe." 313 | }; 314 | 315 | // Send the email with the password 316 | error? emailStatus = smtpClient->sendMessage(message); 317 | if emailStatus is error { 318 | // If email sending fails, return error message 319 | http:Response response = new; 320 | response.statusCode = 500; 321 | response.setPayload({message: "Failed to send email. Please try again later."}); 322 | return response; 323 | } 324 | 325 | // Return success response 326 | http:Response response = new; 327 | response.setPayload({message: "Password has been sent to your email."}); 328 | return response; 329 | } 330 | } 331 | 332 | // User Input Type Definition for Forget Password 333 | type ReserPassUserInput record { 334 | string username; 335 | string email; 336 | }; 337 | 338 | // User Record 339 | type User record { 340 | string id; 341 | string username; 342 | string password; 343 | string email; 344 | }; 345 | 346 | type city_names record { 347 | string city; 348 | float latitude; 349 | float longitude; 350 | 351 | }; 352 | 353 | type shop_details record { 354 | string city; 355 | string name; 356 | string type1; 357 | string whatsapp; 358 | int local; 359 | float latitude?; 360 | float longitude?; 361 | }; 362 | 363 | // User Input Type Definition for Signup 364 | type UserInput record { 365 | string username; 366 | string password; 367 | string email?; 368 | }; 369 | 370 | // User Input Type Definition for Login 371 | type LoginInput record { 372 | string username; 373 | string password; 374 | }; 375 | 376 | // User Input msg 377 | type MsgInput record { 378 | string username; 379 | string email?; 380 | string msg; 381 | }; 382 | 383 | // massage Record 384 | type Msg record { 385 | string id; 386 | string username; 387 | string email; 388 | string msg; 389 | 390 | }; 391 | 392 | // User Input msg 393 | type ResetInput record { 394 | string username; 395 | string email?; 396 | }; 397 | 398 | // massage Record 399 | type Reset record { 400 | string id; 401 | string username; 402 | string email; 403 | 404 | }; 405 | 406 | -------------------------------------------------------------------------------- /public/assets/vendor/bootstrap/css/bootstrap-reboot.rtl.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v5.3.2 (https://getbootstrap.com/) 3 | * Copyright 2011-2023 The Bootstrap Authors 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | */ 6 | :root, 7 | [data-bs-theme=light] { 8 | --bs-blue: #0d6efd; 9 | --bs-indigo: #6610f2; 10 | --bs-purple: #6f42c1; 11 | --bs-pink: #d63384; 12 | --bs-red: #dc3545; 13 | --bs-orange: #fd7e14; 14 | --bs-yellow: #ffc107; 15 | --bs-green: #198754; 16 | --bs-teal: #20c997; 17 | --bs-cyan: #0dcaf0; 18 | --bs-black: #000; 19 | --bs-white: #fff; 20 | --bs-gray: #6c757d; 21 | --bs-gray-dark: #343a40; 22 | --bs-gray-100: #f8f9fa; 23 | --bs-gray-200: #e9ecef; 24 | --bs-gray-300: #dee2e6; 25 | --bs-gray-400: #ced4da; 26 | --bs-gray-500: #adb5bd; 27 | --bs-gray-600: #6c757d; 28 | --bs-gray-700: #495057; 29 | --bs-gray-800: #343a40; 30 | --bs-gray-900: #212529; 31 | --bs-primary: #0d6efd; 32 | --bs-secondary: #6c757d; 33 | --bs-success: #198754; 34 | --bs-info: #0dcaf0; 35 | --bs-warning: #ffc107; 36 | --bs-danger: #dc3545; 37 | --bs-light: #f8f9fa; 38 | --bs-dark: #212529; 39 | --bs-primary-rgb: 13, 110, 253; 40 | --bs-secondary-rgb: 108, 117, 125; 41 | --bs-success-rgb: 25, 135, 84; 42 | --bs-info-rgb: 13, 202, 240; 43 | --bs-warning-rgb: 255, 193, 7; 44 | --bs-danger-rgb: 220, 53, 69; 45 | --bs-light-rgb: 248, 249, 250; 46 | --bs-dark-rgb: 33, 37, 41; 47 | --bs-primary-text-emphasis: #052c65; 48 | --bs-secondary-text-emphasis: #2b2f32; 49 | --bs-success-text-emphasis: #0a3622; 50 | --bs-info-text-emphasis: #055160; 51 | --bs-warning-text-emphasis: #664d03; 52 | --bs-danger-text-emphasis: #58151c; 53 | --bs-light-text-emphasis: #495057; 54 | --bs-dark-text-emphasis: #495057; 55 | --bs-primary-bg-subtle: #cfe2ff; 56 | --bs-secondary-bg-subtle: #e2e3e5; 57 | --bs-success-bg-subtle: #d1e7dd; 58 | --bs-info-bg-subtle: #cff4fc; 59 | --bs-warning-bg-subtle: #fff3cd; 60 | --bs-danger-bg-subtle: #f8d7da; 61 | --bs-light-bg-subtle: #fcfcfd; 62 | --bs-dark-bg-subtle: #ced4da; 63 | --bs-primary-border-subtle: #9ec5fe; 64 | --bs-secondary-border-subtle: #c4c8cb; 65 | --bs-success-border-subtle: #a3cfbb; 66 | --bs-info-border-subtle: #9eeaf9; 67 | --bs-warning-border-subtle: #ffe69c; 68 | --bs-danger-border-subtle: #f1aeb5; 69 | --bs-light-border-subtle: #e9ecef; 70 | --bs-dark-border-subtle: #adb5bd; 71 | --bs-white-rgb: 255, 255, 255; 72 | --bs-black-rgb: 0, 0, 0; 73 | --bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; 74 | --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; 75 | --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0)); 76 | --bs-body-font-family: var(--bs-font-sans-serif); 77 | --bs-body-font-size: 1rem; 78 | --bs-body-font-weight: 400; 79 | --bs-body-line-height: 1.5; 80 | --bs-body-color: #212529; 81 | --bs-body-color-rgb: 33, 37, 41; 82 | --bs-body-bg: #fff; 83 | --bs-body-bg-rgb: 255, 255, 255; 84 | --bs-emphasis-color: #000; 85 | --bs-emphasis-color-rgb: 0, 0, 0; 86 | --bs-secondary-color: rgba(33, 37, 41, 0.75); 87 | --bs-secondary-color-rgb: 33, 37, 41; 88 | --bs-secondary-bg: #e9ecef; 89 | --bs-secondary-bg-rgb: 233, 236, 239; 90 | --bs-tertiary-color: rgba(33, 37, 41, 0.5); 91 | --bs-tertiary-color-rgb: 33, 37, 41; 92 | --bs-tertiary-bg: #f8f9fa; 93 | --bs-tertiary-bg-rgb: 248, 249, 250; 94 | --bs-heading-color: inherit; 95 | --bs-link-color: #0d6efd; 96 | --bs-link-color-rgb: 13, 110, 253; 97 | --bs-link-decoration: underline; 98 | --bs-link-hover-color: #0a58ca; 99 | --bs-link-hover-color-rgb: 10, 88, 202; 100 | --bs-code-color: #d63384; 101 | --bs-highlight-color: #212529; 102 | --bs-highlight-bg: #fff3cd; 103 | --bs-border-width: 1px; 104 | --bs-border-style: solid; 105 | --bs-border-color: #dee2e6; 106 | --bs-border-color-translucent: rgba(0, 0, 0, 0.175); 107 | --bs-border-radius: 0.375rem; 108 | --bs-border-radius-sm: 0.25rem; 109 | --bs-border-radius-lg: 0.5rem; 110 | --bs-border-radius-xl: 1rem; 111 | --bs-border-radius-xxl: 2rem; 112 | --bs-border-radius-2xl: var(--bs-border-radius-xxl); 113 | --bs-border-radius-pill: 50rem; 114 | --bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); 115 | --bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075); 116 | --bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175); 117 | --bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075); 118 | --bs-focus-ring-width: 0.25rem; 119 | --bs-focus-ring-opacity: 0.25; 120 | --bs-focus-ring-color: rgba(13, 110, 253, 0.25); 121 | --bs-form-valid-color: #198754; 122 | --bs-form-valid-border-color: #198754; 123 | --bs-form-invalid-color: #dc3545; 124 | --bs-form-invalid-border-color: #dc3545; 125 | } 126 | 127 | [data-bs-theme=dark] { 128 | color-scheme: dark; 129 | --bs-body-color: #dee2e6; 130 | --bs-body-color-rgb: 222, 226, 230; 131 | --bs-body-bg: #212529; 132 | --bs-body-bg-rgb: 33, 37, 41; 133 | --bs-emphasis-color: #fff; 134 | --bs-emphasis-color-rgb: 255, 255, 255; 135 | --bs-secondary-color: rgba(222, 226, 230, 0.75); 136 | --bs-secondary-color-rgb: 222, 226, 230; 137 | --bs-secondary-bg: #343a40; 138 | --bs-secondary-bg-rgb: 52, 58, 64; 139 | --bs-tertiary-color: rgba(222, 226, 230, 0.5); 140 | --bs-tertiary-color-rgb: 222, 226, 230; 141 | --bs-tertiary-bg: #2b3035; 142 | --bs-tertiary-bg-rgb: 43, 48, 53; 143 | --bs-primary-text-emphasis: #6ea8fe; 144 | --bs-secondary-text-emphasis: #a7acb1; 145 | --bs-success-text-emphasis: #75b798; 146 | --bs-info-text-emphasis: #6edff6; 147 | --bs-warning-text-emphasis: #ffda6a; 148 | --bs-danger-text-emphasis: #ea868f; 149 | --bs-light-text-emphasis: #f8f9fa; 150 | --bs-dark-text-emphasis: #dee2e6; 151 | --bs-primary-bg-subtle: #031633; 152 | --bs-secondary-bg-subtle: #161719; 153 | --bs-success-bg-subtle: #051b11; 154 | --bs-info-bg-subtle: #032830; 155 | --bs-warning-bg-subtle: #332701; 156 | --bs-danger-bg-subtle: #2c0b0e; 157 | --bs-light-bg-subtle: #343a40; 158 | --bs-dark-bg-subtle: #1a1d20; 159 | --bs-primary-border-subtle: #084298; 160 | --bs-secondary-border-subtle: #41464b; 161 | --bs-success-border-subtle: #0f5132; 162 | --bs-info-border-subtle: #087990; 163 | --bs-warning-border-subtle: #997404; 164 | --bs-danger-border-subtle: #842029; 165 | --bs-light-border-subtle: #495057; 166 | --bs-dark-border-subtle: #343a40; 167 | --bs-heading-color: inherit; 168 | --bs-link-color: #6ea8fe; 169 | --bs-link-hover-color: #8bb9fe; 170 | --bs-link-color-rgb: 110, 168, 254; 171 | --bs-link-hover-color-rgb: 139, 185, 254; 172 | --bs-code-color: #e685b5; 173 | --bs-highlight-color: #dee2e6; 174 | --bs-highlight-bg: #664d03; 175 | --bs-border-color: #495057; 176 | --bs-border-color-translucent: rgba(255, 255, 255, 0.15); 177 | --bs-form-valid-color: #75b798; 178 | --bs-form-valid-border-color: #75b798; 179 | --bs-form-invalid-color: #ea868f; 180 | --bs-form-invalid-border-color: #ea868f; 181 | } 182 | 183 | *, 184 | *::before, 185 | *::after { 186 | box-sizing: border-box; 187 | } 188 | 189 | @media (prefers-reduced-motion: no-preference) { 190 | :root { 191 | scroll-behavior: smooth; 192 | } 193 | } 194 | 195 | body { 196 | margin: 0; 197 | font-family: var(--bs-body-font-family); 198 | font-size: var(--bs-body-font-size); 199 | font-weight: var(--bs-body-font-weight); 200 | line-height: var(--bs-body-line-height); 201 | color: var(--bs-body-color); 202 | text-align: var(--bs-body-text-align); 203 | background-color: var(--bs-body-bg); 204 | -webkit-text-size-adjust: 100%; 205 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 206 | } 207 | 208 | hr { 209 | margin: 1rem 0; 210 | color: inherit; 211 | border: 0; 212 | border-top: var(--bs-border-width) solid; 213 | opacity: 0.25; 214 | } 215 | 216 | h6, h5, h4, h3, h2, h1 { 217 | margin-top: 0; 218 | margin-bottom: 0.5rem; 219 | font-weight: 500; 220 | line-height: 1.2; 221 | color: var(--bs-heading-color); 222 | } 223 | 224 | h1 { 225 | font-size: calc(1.375rem + 1.5vw); 226 | } 227 | @media (min-width: 1200px) { 228 | h1 { 229 | font-size: 2.5rem; 230 | } 231 | } 232 | 233 | h2 { 234 | font-size: calc(1.325rem + 0.9vw); 235 | } 236 | @media (min-width: 1200px) { 237 | h2 { 238 | font-size: 2rem; 239 | } 240 | } 241 | 242 | h3 { 243 | font-size: calc(1.3rem + 0.6vw); 244 | } 245 | @media (min-width: 1200px) { 246 | h3 { 247 | font-size: 1.75rem; 248 | } 249 | } 250 | 251 | h4 { 252 | font-size: calc(1.275rem + 0.3vw); 253 | } 254 | @media (min-width: 1200px) { 255 | h4 { 256 | font-size: 1.5rem; 257 | } 258 | } 259 | 260 | h5 { 261 | font-size: 1.25rem; 262 | } 263 | 264 | h6 { 265 | font-size: 1rem; 266 | } 267 | 268 | p { 269 | margin-top: 0; 270 | margin-bottom: 1rem; 271 | } 272 | 273 | abbr[title] { 274 | -webkit-text-decoration: underline dotted; 275 | text-decoration: underline dotted; 276 | cursor: help; 277 | -webkit-text-decoration-skip-ink: none; 278 | text-decoration-skip-ink: none; 279 | } 280 | 281 | address { 282 | margin-bottom: 1rem; 283 | font-style: normal; 284 | line-height: inherit; 285 | } 286 | 287 | ol, 288 | ul { 289 | padding-right: 2rem; 290 | } 291 | 292 | ol, 293 | ul, 294 | dl { 295 | margin-top: 0; 296 | margin-bottom: 1rem; 297 | } 298 | 299 | ol ol, 300 | ul ul, 301 | ol ul, 302 | ul ol { 303 | margin-bottom: 0; 304 | } 305 | 306 | dt { 307 | font-weight: 700; 308 | } 309 | 310 | dd { 311 | margin-bottom: 0.5rem; 312 | margin-right: 0; 313 | } 314 | 315 | blockquote { 316 | margin: 0 0 1rem; 317 | } 318 | 319 | b, 320 | strong { 321 | font-weight: bolder; 322 | } 323 | 324 | small { 325 | font-size: 0.875em; 326 | } 327 | 328 | mark { 329 | padding: 0.1875em; 330 | color: var(--bs-highlight-color); 331 | background-color: var(--bs-highlight-bg); 332 | } 333 | 334 | sub, 335 | sup { 336 | position: relative; 337 | font-size: 0.75em; 338 | line-height: 0; 339 | vertical-align: baseline; 340 | } 341 | 342 | sub { 343 | bottom: -0.25em; 344 | } 345 | 346 | sup { 347 | top: -0.5em; 348 | } 349 | 350 | a { 351 | color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1)); 352 | text-decoration: underline; 353 | } 354 | a:hover { 355 | --bs-link-color-rgb: var(--bs-link-hover-color-rgb); 356 | } 357 | 358 | a:not([href]):not([class]), a:not([href]):not([class]):hover { 359 | color: inherit; 360 | text-decoration: none; 361 | } 362 | 363 | pre, 364 | code, 365 | kbd, 366 | samp { 367 | font-family: var(--bs-font-monospace); 368 | font-size: 1em; 369 | } 370 | 371 | pre { 372 | display: block; 373 | margin-top: 0; 374 | margin-bottom: 1rem; 375 | overflow: auto; 376 | font-size: 0.875em; 377 | } 378 | pre code { 379 | font-size: inherit; 380 | color: inherit; 381 | word-break: normal; 382 | } 383 | 384 | code { 385 | font-size: 0.875em; 386 | color: var(--bs-code-color); 387 | word-wrap: break-word; 388 | } 389 | a > code { 390 | color: inherit; 391 | } 392 | 393 | kbd { 394 | padding: 0.1875rem 0.375rem; 395 | font-size: 0.875em; 396 | color: var(--bs-body-bg); 397 | background-color: var(--bs-body-color); 398 | border-radius: 0.25rem; 399 | } 400 | kbd kbd { 401 | padding: 0; 402 | font-size: 1em; 403 | } 404 | 405 | figure { 406 | margin: 0 0 1rem; 407 | } 408 | 409 | img, 410 | svg { 411 | vertical-align: middle; 412 | } 413 | 414 | table { 415 | caption-side: bottom; 416 | border-collapse: collapse; 417 | } 418 | 419 | caption { 420 | padding-top: 0.5rem; 421 | padding-bottom: 0.5rem; 422 | color: var(--bs-secondary-color); 423 | text-align: right; 424 | } 425 | 426 | th { 427 | text-align: inherit; 428 | text-align: -webkit-match-parent; 429 | } 430 | 431 | thead, 432 | tbody, 433 | tfoot, 434 | tr, 435 | td, 436 | th { 437 | border-color: inherit; 438 | border-style: solid; 439 | border-width: 0; 440 | } 441 | 442 | label { 443 | display: inline-block; 444 | } 445 | 446 | button { 447 | border-radius: 0; 448 | } 449 | 450 | button:focus:not(:focus-visible) { 451 | outline: 0; 452 | } 453 | 454 | input, 455 | button, 456 | select, 457 | optgroup, 458 | textarea { 459 | margin: 0; 460 | font-family: inherit; 461 | font-size: inherit; 462 | line-height: inherit; 463 | } 464 | 465 | button, 466 | select { 467 | text-transform: none; 468 | } 469 | 470 | [role=button] { 471 | cursor: pointer; 472 | } 473 | 474 | select { 475 | word-wrap: normal; 476 | } 477 | select:disabled { 478 | opacity: 1; 479 | } 480 | 481 | [list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator { 482 | display: none !important; 483 | } 484 | 485 | button, 486 | [type=button], 487 | [type=reset], 488 | [type=submit] { 489 | -webkit-appearance: button; 490 | } 491 | button:not(:disabled), 492 | [type=button]:not(:disabled), 493 | [type=reset]:not(:disabled), 494 | [type=submit]:not(:disabled) { 495 | cursor: pointer; 496 | } 497 | 498 | ::-moz-focus-inner { 499 | padding: 0; 500 | border-style: none; 501 | } 502 | 503 | textarea { 504 | resize: vertical; 505 | } 506 | 507 | fieldset { 508 | min-width: 0; 509 | padding: 0; 510 | margin: 0; 511 | border: 0; 512 | } 513 | 514 | legend { 515 | float: right; 516 | width: 100%; 517 | padding: 0; 518 | margin-bottom: 0.5rem; 519 | font-size: calc(1.275rem + 0.3vw); 520 | line-height: inherit; 521 | } 522 | @media (min-width: 1200px) { 523 | legend { 524 | font-size: 1.5rem; 525 | } 526 | } 527 | legend + * { 528 | clear: right; 529 | } 530 | 531 | ::-webkit-datetime-edit-fields-wrapper, 532 | ::-webkit-datetime-edit-text, 533 | ::-webkit-datetime-edit-minute, 534 | ::-webkit-datetime-edit-hour-field, 535 | ::-webkit-datetime-edit-day-field, 536 | ::-webkit-datetime-edit-month-field, 537 | ::-webkit-datetime-edit-year-field { 538 | padding: 0; 539 | } 540 | 541 | ::-webkit-inner-spin-button { 542 | height: auto; 543 | } 544 | 545 | [type=search] { 546 | -webkit-appearance: textfield; 547 | outline-offset: -2px; 548 | } 549 | 550 | [type="tel"], 551 | [type="url"], 552 | [type="email"], 553 | [type="number"] { 554 | direction: ltr; 555 | } 556 | ::-webkit-search-decoration { 557 | -webkit-appearance: none; 558 | } 559 | 560 | ::-webkit-color-swatch-wrapper { 561 | padding: 0; 562 | } 563 | 564 | ::-webkit-file-upload-button { 565 | font: inherit; 566 | -webkit-appearance: button; 567 | } 568 | 569 | ::file-selector-button { 570 | font: inherit; 571 | -webkit-appearance: button; 572 | } 573 | 574 | output { 575 | display: inline-block; 576 | } 577 | 578 | iframe { 579 | border: 0; 580 | } 581 | 582 | summary { 583 | display: list-item; 584 | cursor: pointer; 585 | } 586 | 587 | progress { 588 | vertical-align: baseline; 589 | } 590 | 591 | [hidden] { 592 | display: none !important; 593 | } 594 | /*# sourceMappingURL=bootstrap-reboot.rtl.css.map */ -------------------------------------------------------------------------------- /public/assets/vendor/bootstrap/css/bootstrap-reboot.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v5.3.2 (https://getbootstrap.com/) 3 | * Copyright 2011-2023 The Bootstrap Authors 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | */ 6 | :root, 7 | [data-bs-theme=light] { 8 | --bs-blue: #0d6efd; 9 | --bs-indigo: #6610f2; 10 | --bs-purple: #6f42c1; 11 | --bs-pink: #d63384; 12 | --bs-red: #dc3545; 13 | --bs-orange: #fd7e14; 14 | --bs-yellow: #ffc107; 15 | --bs-green: #198754; 16 | --bs-teal: #20c997; 17 | --bs-cyan: #0dcaf0; 18 | --bs-black: #000; 19 | --bs-white: #fff; 20 | --bs-gray: #6c757d; 21 | --bs-gray-dark: #343a40; 22 | --bs-gray-100: #f8f9fa; 23 | --bs-gray-200: #e9ecef; 24 | --bs-gray-300: #dee2e6; 25 | --bs-gray-400: #ced4da; 26 | --bs-gray-500: #adb5bd; 27 | --bs-gray-600: #6c757d; 28 | --bs-gray-700: #495057; 29 | --bs-gray-800: #343a40; 30 | --bs-gray-900: #212529; 31 | --bs-primary: #0d6efd; 32 | --bs-secondary: #6c757d; 33 | --bs-success: #198754; 34 | --bs-info: #0dcaf0; 35 | --bs-warning: #ffc107; 36 | --bs-danger: #dc3545; 37 | --bs-light: #f8f9fa; 38 | --bs-dark: #212529; 39 | --bs-primary-rgb: 13, 110, 253; 40 | --bs-secondary-rgb: 108, 117, 125; 41 | --bs-success-rgb: 25, 135, 84; 42 | --bs-info-rgb: 13, 202, 240; 43 | --bs-warning-rgb: 255, 193, 7; 44 | --bs-danger-rgb: 220, 53, 69; 45 | --bs-light-rgb: 248, 249, 250; 46 | --bs-dark-rgb: 33, 37, 41; 47 | --bs-primary-text-emphasis: #052c65; 48 | --bs-secondary-text-emphasis: #2b2f32; 49 | --bs-success-text-emphasis: #0a3622; 50 | --bs-info-text-emphasis: #055160; 51 | --bs-warning-text-emphasis: #664d03; 52 | --bs-danger-text-emphasis: #58151c; 53 | --bs-light-text-emphasis: #495057; 54 | --bs-dark-text-emphasis: #495057; 55 | --bs-primary-bg-subtle: #cfe2ff; 56 | --bs-secondary-bg-subtle: #e2e3e5; 57 | --bs-success-bg-subtle: #d1e7dd; 58 | --bs-info-bg-subtle: #cff4fc; 59 | --bs-warning-bg-subtle: #fff3cd; 60 | --bs-danger-bg-subtle: #f8d7da; 61 | --bs-light-bg-subtle: #fcfcfd; 62 | --bs-dark-bg-subtle: #ced4da; 63 | --bs-primary-border-subtle: #9ec5fe; 64 | --bs-secondary-border-subtle: #c4c8cb; 65 | --bs-success-border-subtle: #a3cfbb; 66 | --bs-info-border-subtle: #9eeaf9; 67 | --bs-warning-border-subtle: #ffe69c; 68 | --bs-danger-border-subtle: #f1aeb5; 69 | --bs-light-border-subtle: #e9ecef; 70 | --bs-dark-border-subtle: #adb5bd; 71 | --bs-white-rgb: 255, 255, 255; 72 | --bs-black-rgb: 0, 0, 0; 73 | --bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; 74 | --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; 75 | --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0)); 76 | --bs-body-font-family: var(--bs-font-sans-serif); 77 | --bs-body-font-size: 1rem; 78 | --bs-body-font-weight: 400; 79 | --bs-body-line-height: 1.5; 80 | --bs-body-color: #212529; 81 | --bs-body-color-rgb: 33, 37, 41; 82 | --bs-body-bg: #fff; 83 | --bs-body-bg-rgb: 255, 255, 255; 84 | --bs-emphasis-color: #000; 85 | --bs-emphasis-color-rgb: 0, 0, 0; 86 | --bs-secondary-color: rgba(33, 37, 41, 0.75); 87 | --bs-secondary-color-rgb: 33, 37, 41; 88 | --bs-secondary-bg: #e9ecef; 89 | --bs-secondary-bg-rgb: 233, 236, 239; 90 | --bs-tertiary-color: rgba(33, 37, 41, 0.5); 91 | --bs-tertiary-color-rgb: 33, 37, 41; 92 | --bs-tertiary-bg: #f8f9fa; 93 | --bs-tertiary-bg-rgb: 248, 249, 250; 94 | --bs-heading-color: inherit; 95 | --bs-link-color: #0d6efd; 96 | --bs-link-color-rgb: 13, 110, 253; 97 | --bs-link-decoration: underline; 98 | --bs-link-hover-color: #0a58ca; 99 | --bs-link-hover-color-rgb: 10, 88, 202; 100 | --bs-code-color: #d63384; 101 | --bs-highlight-color: #212529; 102 | --bs-highlight-bg: #fff3cd; 103 | --bs-border-width: 1px; 104 | --bs-border-style: solid; 105 | --bs-border-color: #dee2e6; 106 | --bs-border-color-translucent: rgba(0, 0, 0, 0.175); 107 | --bs-border-radius: 0.375rem; 108 | --bs-border-radius-sm: 0.25rem; 109 | --bs-border-radius-lg: 0.5rem; 110 | --bs-border-radius-xl: 1rem; 111 | --bs-border-radius-xxl: 2rem; 112 | --bs-border-radius-2xl: var(--bs-border-radius-xxl); 113 | --bs-border-radius-pill: 50rem; 114 | --bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); 115 | --bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075); 116 | --bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175); 117 | --bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075); 118 | --bs-focus-ring-width: 0.25rem; 119 | --bs-focus-ring-opacity: 0.25; 120 | --bs-focus-ring-color: rgba(13, 110, 253, 0.25); 121 | --bs-form-valid-color: #198754; 122 | --bs-form-valid-border-color: #198754; 123 | --bs-form-invalid-color: #dc3545; 124 | --bs-form-invalid-border-color: #dc3545; 125 | } 126 | 127 | [data-bs-theme=dark] { 128 | color-scheme: dark; 129 | --bs-body-color: #dee2e6; 130 | --bs-body-color-rgb: 222, 226, 230; 131 | --bs-body-bg: #212529; 132 | --bs-body-bg-rgb: 33, 37, 41; 133 | --bs-emphasis-color: #fff; 134 | --bs-emphasis-color-rgb: 255, 255, 255; 135 | --bs-secondary-color: rgba(222, 226, 230, 0.75); 136 | --bs-secondary-color-rgb: 222, 226, 230; 137 | --bs-secondary-bg: #343a40; 138 | --bs-secondary-bg-rgb: 52, 58, 64; 139 | --bs-tertiary-color: rgba(222, 226, 230, 0.5); 140 | --bs-tertiary-color-rgb: 222, 226, 230; 141 | --bs-tertiary-bg: #2b3035; 142 | --bs-tertiary-bg-rgb: 43, 48, 53; 143 | --bs-primary-text-emphasis: #6ea8fe; 144 | --bs-secondary-text-emphasis: #a7acb1; 145 | --bs-success-text-emphasis: #75b798; 146 | --bs-info-text-emphasis: #6edff6; 147 | --bs-warning-text-emphasis: #ffda6a; 148 | --bs-danger-text-emphasis: #ea868f; 149 | --bs-light-text-emphasis: #f8f9fa; 150 | --bs-dark-text-emphasis: #dee2e6; 151 | --bs-primary-bg-subtle: #031633; 152 | --bs-secondary-bg-subtle: #161719; 153 | --bs-success-bg-subtle: #051b11; 154 | --bs-info-bg-subtle: #032830; 155 | --bs-warning-bg-subtle: #332701; 156 | --bs-danger-bg-subtle: #2c0b0e; 157 | --bs-light-bg-subtle: #343a40; 158 | --bs-dark-bg-subtle: #1a1d20; 159 | --bs-primary-border-subtle: #084298; 160 | --bs-secondary-border-subtle: #41464b; 161 | --bs-success-border-subtle: #0f5132; 162 | --bs-info-border-subtle: #087990; 163 | --bs-warning-border-subtle: #997404; 164 | --bs-danger-border-subtle: #842029; 165 | --bs-light-border-subtle: #495057; 166 | --bs-dark-border-subtle: #343a40; 167 | --bs-heading-color: inherit; 168 | --bs-link-color: #6ea8fe; 169 | --bs-link-hover-color: #8bb9fe; 170 | --bs-link-color-rgb: 110, 168, 254; 171 | --bs-link-hover-color-rgb: 139, 185, 254; 172 | --bs-code-color: #e685b5; 173 | --bs-highlight-color: #dee2e6; 174 | --bs-highlight-bg: #664d03; 175 | --bs-border-color: #495057; 176 | --bs-border-color-translucent: rgba(255, 255, 255, 0.15); 177 | --bs-form-valid-color: #75b798; 178 | --bs-form-valid-border-color: #75b798; 179 | --bs-form-invalid-color: #ea868f; 180 | --bs-form-invalid-border-color: #ea868f; 181 | } 182 | 183 | *, 184 | *::before, 185 | *::after { 186 | box-sizing: border-box; 187 | } 188 | 189 | @media (prefers-reduced-motion: no-preference) { 190 | :root { 191 | scroll-behavior: smooth; 192 | } 193 | } 194 | 195 | body { 196 | margin: 0; 197 | font-family: var(--bs-body-font-family); 198 | font-size: var(--bs-body-font-size); 199 | font-weight: var(--bs-body-font-weight); 200 | line-height: var(--bs-body-line-height); 201 | color: var(--bs-body-color); 202 | text-align: var(--bs-body-text-align); 203 | background-color: var(--bs-body-bg); 204 | -webkit-text-size-adjust: 100%; 205 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 206 | } 207 | 208 | hr { 209 | margin: 1rem 0; 210 | color: inherit; 211 | border: 0; 212 | border-top: var(--bs-border-width) solid; 213 | opacity: 0.25; 214 | } 215 | 216 | h6, h5, h4, h3, h2, h1 { 217 | margin-top: 0; 218 | margin-bottom: 0.5rem; 219 | font-weight: 500; 220 | line-height: 1.2; 221 | color: var(--bs-heading-color); 222 | } 223 | 224 | h1 { 225 | font-size: calc(1.375rem + 1.5vw); 226 | } 227 | @media (min-width: 1200px) { 228 | h1 { 229 | font-size: 2.5rem; 230 | } 231 | } 232 | 233 | h2 { 234 | font-size: calc(1.325rem + 0.9vw); 235 | } 236 | @media (min-width: 1200px) { 237 | h2 { 238 | font-size: 2rem; 239 | } 240 | } 241 | 242 | h3 { 243 | font-size: calc(1.3rem + 0.6vw); 244 | } 245 | @media (min-width: 1200px) { 246 | h3 { 247 | font-size: 1.75rem; 248 | } 249 | } 250 | 251 | h4 { 252 | font-size: calc(1.275rem + 0.3vw); 253 | } 254 | @media (min-width: 1200px) { 255 | h4 { 256 | font-size: 1.5rem; 257 | } 258 | } 259 | 260 | h5 { 261 | font-size: 1.25rem; 262 | } 263 | 264 | h6 { 265 | font-size: 1rem; 266 | } 267 | 268 | p { 269 | margin-top: 0; 270 | margin-bottom: 1rem; 271 | } 272 | 273 | abbr[title] { 274 | -webkit-text-decoration: underline dotted; 275 | text-decoration: underline dotted; 276 | cursor: help; 277 | -webkit-text-decoration-skip-ink: none; 278 | text-decoration-skip-ink: none; 279 | } 280 | 281 | address { 282 | margin-bottom: 1rem; 283 | font-style: normal; 284 | line-height: inherit; 285 | } 286 | 287 | ol, 288 | ul { 289 | padding-left: 2rem; 290 | } 291 | 292 | ol, 293 | ul, 294 | dl { 295 | margin-top: 0; 296 | margin-bottom: 1rem; 297 | } 298 | 299 | ol ol, 300 | ul ul, 301 | ol ul, 302 | ul ol { 303 | margin-bottom: 0; 304 | } 305 | 306 | dt { 307 | font-weight: 700; 308 | } 309 | 310 | dd { 311 | margin-bottom: 0.5rem; 312 | margin-left: 0; 313 | } 314 | 315 | blockquote { 316 | margin: 0 0 1rem; 317 | } 318 | 319 | b, 320 | strong { 321 | font-weight: bolder; 322 | } 323 | 324 | small { 325 | font-size: 0.875em; 326 | } 327 | 328 | mark { 329 | padding: 0.1875em; 330 | color: var(--bs-highlight-color); 331 | background-color: var(--bs-highlight-bg); 332 | } 333 | 334 | sub, 335 | sup { 336 | position: relative; 337 | font-size: 0.75em; 338 | line-height: 0; 339 | vertical-align: baseline; 340 | } 341 | 342 | sub { 343 | bottom: -0.25em; 344 | } 345 | 346 | sup { 347 | top: -0.5em; 348 | } 349 | 350 | a { 351 | color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1)); 352 | text-decoration: underline; 353 | } 354 | a:hover { 355 | --bs-link-color-rgb: var(--bs-link-hover-color-rgb); 356 | } 357 | 358 | a:not([href]):not([class]), a:not([href]):not([class]):hover { 359 | color: inherit; 360 | text-decoration: none; 361 | } 362 | 363 | pre, 364 | code, 365 | kbd, 366 | samp { 367 | font-family: var(--bs-font-monospace); 368 | font-size: 1em; 369 | } 370 | 371 | pre { 372 | display: block; 373 | margin-top: 0; 374 | margin-bottom: 1rem; 375 | overflow: auto; 376 | font-size: 0.875em; 377 | } 378 | pre code { 379 | font-size: inherit; 380 | color: inherit; 381 | word-break: normal; 382 | } 383 | 384 | code { 385 | font-size: 0.875em; 386 | color: var(--bs-code-color); 387 | word-wrap: break-word; 388 | } 389 | a > code { 390 | color: inherit; 391 | } 392 | 393 | kbd { 394 | padding: 0.1875rem 0.375rem; 395 | font-size: 0.875em; 396 | color: var(--bs-body-bg); 397 | background-color: var(--bs-body-color); 398 | border-radius: 0.25rem; 399 | } 400 | kbd kbd { 401 | padding: 0; 402 | font-size: 1em; 403 | } 404 | 405 | figure { 406 | margin: 0 0 1rem; 407 | } 408 | 409 | img, 410 | svg { 411 | vertical-align: middle; 412 | } 413 | 414 | table { 415 | caption-side: bottom; 416 | border-collapse: collapse; 417 | } 418 | 419 | caption { 420 | padding-top: 0.5rem; 421 | padding-bottom: 0.5rem; 422 | color: var(--bs-secondary-color); 423 | text-align: left; 424 | } 425 | 426 | th { 427 | text-align: inherit; 428 | text-align: -webkit-match-parent; 429 | } 430 | 431 | thead, 432 | tbody, 433 | tfoot, 434 | tr, 435 | td, 436 | th { 437 | border-color: inherit; 438 | border-style: solid; 439 | border-width: 0; 440 | } 441 | 442 | label { 443 | display: inline-block; 444 | } 445 | 446 | button { 447 | border-radius: 0; 448 | } 449 | 450 | button:focus:not(:focus-visible) { 451 | outline: 0; 452 | } 453 | 454 | input, 455 | button, 456 | select, 457 | optgroup, 458 | textarea { 459 | margin: 0; 460 | font-family: inherit; 461 | font-size: inherit; 462 | line-height: inherit; 463 | } 464 | 465 | button, 466 | select { 467 | text-transform: none; 468 | } 469 | 470 | [role=button] { 471 | cursor: pointer; 472 | } 473 | 474 | select { 475 | word-wrap: normal; 476 | } 477 | select:disabled { 478 | opacity: 1; 479 | } 480 | 481 | [list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator { 482 | display: none !important; 483 | } 484 | 485 | button, 486 | [type=button], 487 | [type=reset], 488 | [type=submit] { 489 | -webkit-appearance: button; 490 | } 491 | button:not(:disabled), 492 | [type=button]:not(:disabled), 493 | [type=reset]:not(:disabled), 494 | [type=submit]:not(:disabled) { 495 | cursor: pointer; 496 | } 497 | 498 | ::-moz-focus-inner { 499 | padding: 0; 500 | border-style: none; 501 | } 502 | 503 | textarea { 504 | resize: vertical; 505 | } 506 | 507 | fieldset { 508 | min-width: 0; 509 | padding: 0; 510 | margin: 0; 511 | border: 0; 512 | } 513 | 514 | legend { 515 | float: left; 516 | width: 100%; 517 | padding: 0; 518 | margin-bottom: 0.5rem; 519 | font-size: calc(1.275rem + 0.3vw); 520 | line-height: inherit; 521 | } 522 | @media (min-width: 1200px) { 523 | legend { 524 | font-size: 1.5rem; 525 | } 526 | } 527 | legend + * { 528 | clear: left; 529 | } 530 | 531 | ::-webkit-datetime-edit-fields-wrapper, 532 | ::-webkit-datetime-edit-text, 533 | ::-webkit-datetime-edit-minute, 534 | ::-webkit-datetime-edit-hour-field, 535 | ::-webkit-datetime-edit-day-field, 536 | ::-webkit-datetime-edit-month-field, 537 | ::-webkit-datetime-edit-year-field { 538 | padding: 0; 539 | } 540 | 541 | ::-webkit-inner-spin-button { 542 | height: auto; 543 | } 544 | 545 | [type=search] { 546 | -webkit-appearance: textfield; 547 | outline-offset: -2px; 548 | } 549 | 550 | /* rtl:raw: 551 | [type="tel"], 552 | [type="url"], 553 | [type="email"], 554 | [type="number"] { 555 | direction: ltr; 556 | } 557 | */ 558 | ::-webkit-search-decoration { 559 | -webkit-appearance: none; 560 | } 561 | 562 | ::-webkit-color-swatch-wrapper { 563 | padding: 0; 564 | } 565 | 566 | ::-webkit-file-upload-button { 567 | font: inherit; 568 | -webkit-appearance: button; 569 | } 570 | 571 | ::file-selector-button { 572 | font: inherit; 573 | -webkit-appearance: button; 574 | } 575 | 576 | output { 577 | display: inline-block; 578 | } 579 | 580 | iframe { 581 | border: 0; 582 | } 583 | 584 | summary { 585 | display: list-item; 586 | cursor: pointer; 587 | } 588 | 589 | progress { 590 | vertical-align: baseline; 591 | } 592 | 593 | [hidden] { 594 | display: none !important; 595 | } 596 | 597 | /*# sourceMappingURL=bootstrap-reboot.css.map */ -------------------------------------------------------------------------------- /public/js/backend_map.js: -------------------------------------------------------------------------------- 1 | let map; 2 | let cityMarker = null; 3 | let markers = []; 4 | let userMarker; 5 | let allShops = []; // Store all the shops fetched from the API 6 | 7 | 8 | const apiUrl = 'http://localhost:9092/api'; 9 | 10 | function initMap() { 11 | const defaultLocation = { lat: 7.8731, lng: 80.7718 }; // Coordinates of Sri Lanka 12 | map = new google.maps.Map(document.getElementById("map"), { 13 | zoom: 8, 14 | center: defaultLocation 15 | }); 16 | } 17 | function clearMarkers() { 18 | for (let i = 0; i < markers.length; i++) { 19 | markers[i].setMap(null); // Remove the marker from the map 20 | } 21 | markers = []; // Clear the markers array 22 | } 23 | 24 | 25 | // Live location indicator 26 | async function getLocation() { 27 | navigator.geolocation.getCurrentPosition( 28 | async function (position) { 29 | const userLocation = { 30 | lat: position.coords.latitude, 31 | lng: position.coords.longitude 32 | }; 33 | 34 | map.setCenter(userLocation); 35 | clearMarkers(); 36 | // Add a marker for the user's location 37 | if (userMarker) userMarker.setMap(null); 38 | userMarker = new google.maps.Marker({ 39 | position: userLocation, 40 | map: map, 41 | title: "You are here!", 42 | icon: "http://maps.google.com/mapfiles/ms/icons/red-dot.png" // Green marker for user 43 | }); 44 | markers.push(userMarker); 45 | 46 | // Fetch the closest cities and display shops from those cities 47 | await findAndMarkClosestCities(userLocation.lat, userLocation.lng); 48 | }, 49 | function () { 50 | handleLocationError(true, map.getCenter()); 51 | } 52 | ); 53 | } 54 | 55 | // Function to calculate the distance between two coordinates. 56 | function calculateDistance(lon1, lat1, lon2, lat2) { 57 | const toRad = (value) => (value * Math.PI) / 180; 58 | const R = 6371; // Radius of the Earth in km 59 | 60 | const dLat = toRad(lat2 - lat1); 61 | const dLon = toRad(lon2 - lon1); 62 | const a = 63 | Math.sin(dLat / 2) * Math.sin(dLat / 2) + 64 | Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * 65 | Math.sin(dLon / 2) * Math.sin(dLon / 2); 66 | const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); 67 | return R * c; // Distance in km 68 | } 69 | 70 | async function findAndMarkClosestCities(lat, lng) { 71 | try { 72 | const response = await axios.get(`${apiUrl}/cities`); 73 | console.log(response.data); // Log the response data to check its structure 74 | const cities = response.data; 75 | 76 | // Check if cities is an array 77 | if (!Array.isArray(cities)) { 78 | throw new Error("Cities data is not an array"); 79 | } 80 | 81 | // Proceed with the logic if cities is an array 82 | let closestCity = null; 83 | let secondClosestCity = null; 84 | let closestDistance = Infinity; 85 | let secondClosestDistance = Infinity; 86 | 87 | cities.forEach(city => { 88 | const distance = calculateDistance(city.latitude, city.longitude, lat, lng); 89 | 90 | if (distance < closestDistance) { 91 | secondClosestDistance = closestDistance; 92 | secondClosestCity = closestCity; 93 | 94 | closestDistance = distance; 95 | closestCity = city; 96 | } else if (distance < secondClosestDistance) { 97 | secondClosestDistance = distance; 98 | secondClosestCity = city; 99 | } 100 | }); 101 | 102 | // After finding the two closest cities, search for shops in those cities 103 | if (closestCity && secondClosestCity) { 104 | await fetchShopsForCities([closestCity.city, secondClosestCity.city]); 105 | } else { 106 | document.getElementById('shops').innerHTML = "

No nearby cities found.

"; 107 | } 108 | } catch (error) { 109 | console.error("Error fetching cities:", error); 110 | } 111 | } 112 | //check the shops in my nearest two cities 113 | async function fetchShopsForCities(cities) { 114 | let output = ''; 115 | 116 | // Get the user's current position for distance calculation 117 | navigator.geolocation.getCurrentPosition(async function (position) { 118 | const userLocation = { 119 | lat: position.coords.latitude, 120 | lng: position.coords.longitude 121 | }; 122 | 123 | allShops = []; // Reset the global shop array 124 | for (const city of cities) { 125 | try { 126 | const response = await axios.get(`http://localhost:9091/api/shops/${city}`); 127 | const shops = response.data; 128 | 129 | if (shops.length === 0) { 130 | output += `

No shops found for ${city}.

`; 131 | } else { 132 | output += `

Shops in ${city}:

`; 133 | shops.forEach(shop => { 134 | // Store the shops in a global array for filtering 135 | allShops.push(shop); 136 | 137 | // Calculate distance between the user's location and each shop 138 | const distance = calculateDistance(userLocation.lng, userLocation.lat, shop.longitude, shop.latitude); // Corrected spelling for latitude 139 | const googleMapsLink = `https://maps.google.com/?q=${shop.latitude},${shop.longitude}`; 140 | 141 | 142 | 143 | output += ` 144 |
145 |

${shop.name}

146 |

${shop.city}

147 |

WhatsApp: Connect

148 |

Local:Call Now

149 |

Distance: ${distance.toFixed(2)} km

150 |

Navigate Me:Navigate Me

151 |
152 | `; 153 | 154 | // Place a marker for each shop on the map based on type 155 | const shopLatLng = { lat: shop.latitude, lng: shop.longitude }; // Fixed latitude/longitude 156 | if (shop.type1 === "tyre") { 157 | // Green marker for tyre shops 158 | new google.maps.Marker({ 159 | position: shopLatLng, 160 | map: map, 161 | title: shop.name, 162 | icon: "http://maps.google.com/mapfiles/ms/icons/green-dot.png" 163 | }); 164 | } else if (shop.type1 === "garage") { 165 | // Blue marker for garage shops 166 | new google.maps.Marker({ 167 | position: shopLatLng, 168 | map: map, 169 | title: shop.name, 170 | icon: "http://maps.google.com/mapfiles/ms/icons/blue-dot.png" 171 | }); 172 | } else { 173 | // Default marker for other shop types 174 | new google.maps.Marker({ 175 | position: shopLatLng, 176 | map: map, 177 | title: shop.name, 178 | icon: "http://maps.google.com/mapfiles/ms/icons/yellow-dot.png" 179 | }); 180 | } 181 | 182 | }); 183 | } 184 | } catch (error) { 185 | console.error(`Error fetching shops for city: ${city}`, error); 186 | output += `

Error fetching shops for ${city}.

`; 187 | } 188 | } 189 | 190 | document.getElementById('shops').innerHTML = output; 191 | }); 192 | } 193 | 194 | 195 | //search function. 196 | async function getAllShops() { 197 | try { 198 | const response = await fetch("http://localhost:9091/api/shops"); 199 | const shops = await response.json(); 200 | return shops; 201 | } catch (error) { 202 | console.error("Error fetching shops:", error); 203 | return []; 204 | } 205 | 206 | } 207 | 208 | // Async function to fetch shops for a specific city 209 | async function fetchShops() { 210 | const city = document.getElementById('city').value; 211 | clearMarkers(); 212 | 213 | 214 | try { 215 | const response = await axios.get(`http://localhost:9091/api/shops/${city}`); 216 | const shops = response.data; 217 | 218 | if (shops.length === 0) { 219 | document.getElementById('shops').innerHTML = "

No shops found for this city.

"; 220 | return; 221 | } 222 | 223 | allShops = shops; // Store the fetched shops for filtering 224 | 225 | let output = ''; 226 | shops.forEach(shop => { 227 | const shopLatLng = { lat: shop.latitude, lng: shop.longitude }; // Corrected spelling 228 | const googleMapsLink = `https://maps.google.com/?q=${shop.latitude},${shop.longitude}`; 229 | output += ` 230 |
231 |

${shop.name}

232 |

${shop.city}

233 |

WhatsApp: Connect

234 |

Local:Call Now

235 |

Navigate Me:Navigate Me

236 |
237 | `; 238 | 239 | // Place markers based on shop type 240 | if (shop.type1 === "tyre") { 241 | // Green marker for tyre shops 242 | new google.maps.Marker({ 243 | position: shopLatLng, 244 | map: map, 245 | title: shop.name, 246 | icon: "http://maps.google.com/mapfiles/ms/icons/green-dot.png" 247 | }); 248 | } else if (shop.type1 === "garage") { 249 | // Blue marker for garage shops 250 | new google.maps.Marker({ 251 | position: shopLatLng, 252 | map: map, 253 | title: shop.name, 254 | icon: "http://maps.google.com/mapfiles/ms/icons/blue-dot.png" 255 | }); 256 | } else { 257 | // Default marker for other shops 258 | new google.maps.Marker({ 259 | position: shopLatLng, 260 | map: map, 261 | title: shop.name, 262 | icon: "http://maps.google.com/mapfiles/ms/icons/yellow-dot.png" 263 | }); 264 | } 265 | }); 266 | 267 | document.getElementById('shops').innerHTML = output; 268 | } catch (error) { 269 | console.error('Error fetching shops:', error); 270 | document.getElementById('shops').innerHTML = "

"; 271 | } 272 | } 273 | 274 | // Function to filter shops 275 | function filterShops(type) { 276 | let filteredShops = []; 277 | 278 | // Filter the shops based on the selected type 279 | if (type === "all") { 280 | filteredShops = allShops; // Show all shops 281 | } else { 282 | filteredShops = allShops.filter(shop => shop.type1 === type); // Filter shops by type (garage/tyre) 283 | } 284 | 285 | 286 | // Get the user's current position for distance calculation and display filtered shops 287 | navigator.geolocation.getCurrentPosition(async function (position) { 288 | const userLocation = { 289 | lat: position.coords.latitude, 290 | lng: position.coords.longitude 291 | }; 292 | 293 | // Update the UI with filtered shops 294 | let output = ''; 295 | filteredShops.forEach(shop => { 296 | const googleMapsLink = `https://maps.google.com/?q=${shop.latitude},${shop.longitude}`; 297 | const distance = calculateDistance(userLocation.lng, userLocation.lat, shop.longitude, shop.latitude); // Calculate distance for each shop 298 | 299 | output += createShopCard(shop, googleMapsLink); 300 | 301 | // Add markers based on shop type 302 | const shopLatLng = { lat: shop.latitude, lng: shop.longitude }; 303 | let markerIcon = "http://maps.google.com/mapfiles/ms/icons/yellow-dot.png"; // Default marker 304 | 305 | if (shop.type1 === "tyre") { 306 | markerIcon = "http://maps.google.com/mapfiles/ms/icons/green-dot.png"; // Green for tyre shops 307 | } else if (shop.type1 === "garage") { 308 | markerIcon = "http://maps.google.com/mapfiles/ms/icons/blue-dot.png"; // Blue for garages 309 | } 310 | 311 | const marker = new google.maps.Marker({ 312 | position: shopLatLng, 313 | map: map, 314 | title: shop.name, 315 | icon: markerIcon 316 | }); 317 | markers.push(marker); 318 | }); 319 | 320 | document.getElementById('shops').innerHTML = output; 321 | }); 322 | } 323 | 324 | // Function to create a shop card for displaying in the UI 325 | function createShopCard(shop, googleMapsLink) { 326 | return ` 327 |
328 |

${shop.name}

329 |

${shop.city}

330 |

WhatsApp: Connect

331 |

Local: Call Now

332 |

Navigate Me: Navigate Me

333 |
334 | `; 335 | } 336 | 337 | // Adding event listeners to filter buttons 338 | document.getElementById("all").addEventListener('click', function () { 339 | filterShops("all"); 340 | }); 341 | 342 | document.getElementById("garage").addEventListener('click', function () { 343 | filterShops("garage"); 344 | }); 345 | 346 | document.getElementById("Tyre_houses").addEventListener('click', function () { 347 | filterShops("tyre"); 348 | }); 349 | 350 | // Initialize the map when the window loads 351 | window.onload = initMap; 352 | 353 | 354 | -------------------------------------------------------------------------------- /public/assets/vendor/swiper/swiper-bundle.min.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Swiper 8.4.7 3 | * Most modern mobile touch slider and framework with hardware accelerated transitions 4 | * https://swiperjs.com 5 | * 6 | * Copyright 2014-2023 Vladimir Kharlampidi 7 | * 8 | * Released under the MIT License 9 | * 10 | * Released on: January 30, 2023 11 | */ 12 | 13 | @font-face{font-family:swiper-icons;src:url('data:application/font-woff;charset=utf-8;base64, d09GRgABAAAAAAZgABAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAAGRAAAABoAAAAci6qHkUdERUYAAAWgAAAAIwAAACQAYABXR1BPUwAABhQAAAAuAAAANuAY7+xHU1VCAAAFxAAAAFAAAABm2fPczU9TLzIAAAHcAAAASgAAAGBP9V5RY21hcAAAAkQAAACIAAABYt6F0cBjdnQgAAACzAAAAAQAAAAEABEBRGdhc3AAAAWYAAAACAAAAAj//wADZ2x5ZgAAAywAAADMAAAD2MHtryVoZWFkAAABbAAAADAAAAA2E2+eoWhoZWEAAAGcAAAAHwAAACQC9gDzaG10eAAAAigAAAAZAAAArgJkABFsb2NhAAAC0AAAAFoAAABaFQAUGG1heHAAAAG8AAAAHwAAACAAcABAbmFtZQAAA/gAAAE5AAACXvFdBwlwb3N0AAAFNAAAAGIAAACE5s74hXjaY2BkYGAAYpf5Hu/j+W2+MnAzMYDAzaX6QjD6/4//Bxj5GA8AuRwMYGkAPywL13jaY2BkYGA88P8Agx4j+/8fQDYfA1AEBWgDAIB2BOoAeNpjYGRgYNBh4GdgYgABEMnIABJzYNADCQAACWgAsQB42mNgYfzCOIGBlYGB0YcxjYGBwR1Kf2WQZGhhYGBiYGVmgAFGBiQQkOaawtDAoMBQxXjg/wEGPcYDDA4wNUA2CCgwsAAAO4EL6gAAeNpj2M0gyAACqxgGNWBkZ2D4/wMA+xkDdgAAAHjaY2BgYGaAYBkGRgYQiAHyGMF8FgYHIM3DwMHABGQrMOgyWDLEM1T9/w8UBfEMgLzE////P/5//f/V/xv+r4eaAAeMbAxwIUYmIMHEgKYAYjUcsDAwsLKxc3BycfPw8jEQA/gZBASFhEVExcQlJKWkZWTl5BUUlZRVVNXUNTQZBgMAAMR+E+gAEQFEAAAAKgAqACoANAA+AEgAUgBcAGYAcAB6AIQAjgCYAKIArAC2AMAAygDUAN4A6ADyAPwBBgEQARoBJAEuATgBQgFMAVYBYAFqAXQBfgGIAZIBnAGmAbIBzgHsAAB42u2NMQ6CUAyGW568x9AneYYgm4MJbhKFaExIOAVX8ApewSt4Bic4AfeAid3VOBixDxfPYEza5O+Xfi04YADggiUIULCuEJK8VhO4bSvpdnktHI5QCYtdi2sl8ZnXaHlqUrNKzdKcT8cjlq+rwZSvIVczNiezsfnP/uznmfPFBNODM2K7MTQ45YEAZqGP81AmGGcF3iPqOop0r1SPTaTbVkfUe4HXj97wYE+yNwWYxwWu4v1ugWHgo3S1XdZEVqWM7ET0cfnLGxWfkgR42o2PvWrDMBSFj/IHLaF0zKjRgdiVMwScNRAoWUoH78Y2icB/yIY09An6AH2Bdu/UB+yxopYshQiEvnvu0dURgDt8QeC8PDw7Fpji3fEA4z/PEJ6YOB5hKh4dj3EvXhxPqH/SKUY3rJ7srZ4FZnh1PMAtPhwP6fl2PMJMPDgeQ4rY8YT6Gzao0eAEA409DuggmTnFnOcSCiEiLMgxCiTI6Cq5DZUd3Qmp10vO0LaLTd2cjN4fOumlc7lUYbSQcZFkutRG7g6JKZKy0RmdLY680CDnEJ+UMkpFFe1RN7nxdVpXrC4aTtnaurOnYercZg2YVmLN/d/gczfEimrE/fs/bOuq29Zmn8tloORaXgZgGa78yO9/cnXm2BpaGvq25Dv9S4E9+5SIc9PqupJKhYFSSl47+Qcr1mYNAAAAeNptw0cKwkAAAMDZJA8Q7OUJvkLsPfZ6zFVERPy8qHh2YER+3i/BP83vIBLLySsoKimrqKqpa2hp6+jq6RsYGhmbmJqZSy0sraxtbO3sHRydnEMU4uR6yx7JJXveP7WrDycAAAAAAAH//wACeNpjYGRgYOABYhkgZgJCZgZNBkYGLQZtIJsFLMYAAAw3ALgAeNolizEKgDAQBCchRbC2sFER0YD6qVQiBCv/H9ezGI6Z5XBAw8CBK/m5iQQVauVbXLnOrMZv2oLdKFa8Pjuru2hJzGabmOSLzNMzvutpB3N42mNgZGBg4GKQYzBhYMxJLMlj4GBgAYow/P/PAJJhLM6sSoWKfWCAAwDAjgbRAAB42mNgYGBkAIIbCZo5IPrmUn0hGA0AO8EFTQAA');font-weight:400;font-style:normal}:root{--swiper-theme-color:#007aff}.swiper{margin-left:auto;margin-right:auto;position:relative;overflow:hidden;list-style:none;padding:0;z-index:1}.swiper-vertical>.swiper-wrapper{flex-direction:column}.swiper-wrapper{position:relative;width:100%;height:100%;z-index:1;display:flex;transition-property:transform;box-sizing:content-box}.swiper-android .swiper-slide,.swiper-wrapper{transform:translate3d(0px,0,0)}.swiper-pointer-events{touch-action:pan-y}.swiper-pointer-events.swiper-vertical{touch-action:pan-x}.swiper-slide{flex-shrink:0;width:100%;height:100%;position:relative;transition-property:transform}.swiper-slide-invisible-blank{visibility:hidden}.swiper-autoheight,.swiper-autoheight .swiper-slide{height:auto}.swiper-autoheight .swiper-wrapper{align-items:flex-start;transition-property:transform,height}.swiper-backface-hidden .swiper-slide{transform:translateZ(0);-webkit-backface-visibility:hidden;backface-visibility:hidden}.swiper-3d,.swiper-3d.swiper-css-mode .swiper-wrapper{perspective:1200px}.swiper-3d .swiper-cube-shadow,.swiper-3d .swiper-slide,.swiper-3d .swiper-slide-shadow,.swiper-3d .swiper-slide-shadow-bottom,.swiper-3d .swiper-slide-shadow-left,.swiper-3d .swiper-slide-shadow-right,.swiper-3d .swiper-slide-shadow-top,.swiper-3d .swiper-wrapper{transform-style:preserve-3d}.swiper-3d .swiper-slide-shadow,.swiper-3d .swiper-slide-shadow-bottom,.swiper-3d .swiper-slide-shadow-left,.swiper-3d .swiper-slide-shadow-right,.swiper-3d .swiper-slide-shadow-top{position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none;z-index:10}.swiper-3d .swiper-slide-shadow{background:rgba(0,0,0,.15)}.swiper-3d .swiper-slide-shadow-left{background-image:linear-gradient(to left,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-3d .swiper-slide-shadow-right{background-image:linear-gradient(to right,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-3d .swiper-slide-shadow-top{background-image:linear-gradient(to top,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-3d .swiper-slide-shadow-bottom{background-image:linear-gradient(to bottom,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-css-mode>.swiper-wrapper{overflow:auto;scrollbar-width:none;-ms-overflow-style:none}.swiper-css-mode>.swiper-wrapper::-webkit-scrollbar{display:none}.swiper-css-mode>.swiper-wrapper>.swiper-slide{scroll-snap-align:start start}.swiper-horizontal.swiper-css-mode>.swiper-wrapper{scroll-snap-type:x mandatory}.swiper-vertical.swiper-css-mode>.swiper-wrapper{scroll-snap-type:y mandatory}.swiper-centered>.swiper-wrapper::before{content:'';flex-shrink:0;order:9999}.swiper-centered.swiper-horizontal>.swiper-wrapper>.swiper-slide:first-child{margin-inline-start:var(--swiper-centered-offset-before)}.swiper-centered.swiper-horizontal>.swiper-wrapper::before{height:100%;min-height:1px;width:var(--swiper-centered-offset-after)}.swiper-centered.swiper-vertical>.swiper-wrapper>.swiper-slide:first-child{margin-block-start:var(--swiper-centered-offset-before)}.swiper-centered.swiper-vertical>.swiper-wrapper::before{width:100%;min-width:1px;height:var(--swiper-centered-offset-after)}.swiper-centered>.swiper-wrapper>.swiper-slide{scroll-snap-align:center center;scroll-snap-stop:always}.swiper-virtual .swiper-slide{-webkit-backface-visibility:hidden;transform:translateZ(0)}.swiper-virtual.swiper-css-mode .swiper-wrapper::after{content:'';position:absolute;left:0;top:0;pointer-events:none}.swiper-virtual.swiper-css-mode.swiper-horizontal .swiper-wrapper::after{height:1px;width:var(--swiper-virtual-size)}.swiper-virtual.swiper-css-mode.swiper-vertical .swiper-wrapper::after{width:1px;height:var(--swiper-virtual-size)}:root{--swiper-navigation-size:44px}.swiper-button-next,.swiper-button-prev{position:absolute;top:50%;width:calc(var(--swiper-navigation-size)/ 44 * 27);height:var(--swiper-navigation-size);margin-top:calc(0px - (var(--swiper-navigation-size)/ 2));z-index:10;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--swiper-navigation-color,var(--swiper-theme-color))}.swiper-button-next.swiper-button-disabled,.swiper-button-prev.swiper-button-disabled{opacity:.35;cursor:auto;pointer-events:none}.swiper-button-next.swiper-button-hidden,.swiper-button-prev.swiper-button-hidden{opacity:0;cursor:auto;pointer-events:none}.swiper-navigation-disabled .swiper-button-next,.swiper-navigation-disabled .swiper-button-prev{display:none!important}.swiper-button-next:after,.swiper-button-prev:after{font-family:swiper-icons;font-size:var(--swiper-navigation-size);text-transform:none!important;letter-spacing:0;font-variant:initial;line-height:1}.swiper-button-prev,.swiper-rtl .swiper-button-next{left:10px;right:auto}.swiper-button-prev:after,.swiper-rtl .swiper-button-next:after{content:'prev'}.swiper-button-next,.swiper-rtl .swiper-button-prev{right:10px;left:auto}.swiper-button-next:after,.swiper-rtl .swiper-button-prev:after{content:'next'}.swiper-button-lock{display:none}.swiper-pagination{position:absolute;text-align:center;transition:.3s opacity;transform:translate3d(0,0,0);z-index:10}.swiper-pagination.swiper-pagination-hidden{opacity:0}.swiper-pagination-disabled>.swiper-pagination,.swiper-pagination.swiper-pagination-disabled{display:none!important}.swiper-horizontal>.swiper-pagination-bullets,.swiper-pagination-bullets.swiper-pagination-horizontal,.swiper-pagination-custom,.swiper-pagination-fraction{bottom:10px;left:0;width:100%}.swiper-pagination-bullets-dynamic{overflow:hidden;font-size:0}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{transform:scale(.33);position:relative}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active{transform:scale(1)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-main{transform:scale(1)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-prev{transform:scale(.66)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-prev-prev{transform:scale(.33)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-next{transform:scale(.66)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-next-next{transform:scale(.33)}.swiper-pagination-bullet{width:var(--swiper-pagination-bullet-width,var(--swiper-pagination-bullet-size,8px));height:var(--swiper-pagination-bullet-height,var(--swiper-pagination-bullet-size,8px));display:inline-block;border-radius:50%;background:var(--swiper-pagination-bullet-inactive-color,#000);opacity:var(--swiper-pagination-bullet-inactive-opacity, .2)}button.swiper-pagination-bullet{border:none;margin:0;padding:0;box-shadow:none;-webkit-appearance:none;appearance:none}.swiper-pagination-clickable .swiper-pagination-bullet{cursor:pointer}.swiper-pagination-bullet:only-child{display:none!important}.swiper-pagination-bullet-active{opacity:var(--swiper-pagination-bullet-opacity, 1);background:var(--swiper-pagination-color,var(--swiper-theme-color))}.swiper-pagination-vertical.swiper-pagination-bullets,.swiper-vertical>.swiper-pagination-bullets{right:10px;top:50%;transform:translate3d(0px,-50%,0)}.swiper-pagination-vertical.swiper-pagination-bullets .swiper-pagination-bullet,.swiper-vertical>.swiper-pagination-bullets .swiper-pagination-bullet{margin:var(--swiper-pagination-bullet-vertical-gap,6px) 0;display:block}.swiper-pagination-vertical.swiper-pagination-bullets.swiper-pagination-bullets-dynamic,.swiper-vertical>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic{top:50%;transform:translateY(-50%);width:8px}.swiper-pagination-vertical.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet,.swiper-vertical>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{display:inline-block;transition:.2s transform,.2s top}.swiper-horizontal>.swiper-pagination-bullets .swiper-pagination-bullet,.swiper-pagination-horizontal.swiper-pagination-bullets .swiper-pagination-bullet{margin:0 var(--swiper-pagination-bullet-horizontal-gap,4px)}.swiper-horizontal>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic,.swiper-pagination-horizontal.swiper-pagination-bullets.swiper-pagination-bullets-dynamic{left:50%;transform:translateX(-50%);white-space:nowrap}.swiper-horizontal>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet,.swiper-pagination-horizontal.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{transition:.2s transform,.2s left}.swiper-horizontal.swiper-rtl>.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{transition:.2s transform,.2s right}.swiper-pagination-progressbar{background:rgba(0,0,0,.25);position:absolute}.swiper-pagination-progressbar .swiper-pagination-progressbar-fill{background:var(--swiper-pagination-color,var(--swiper-theme-color));position:absolute;left:0;top:0;width:100%;height:100%;transform:scale(0);transform-origin:left top}.swiper-rtl .swiper-pagination-progressbar .swiper-pagination-progressbar-fill{transform-origin:right top}.swiper-horizontal>.swiper-pagination-progressbar,.swiper-pagination-progressbar.swiper-pagination-horizontal,.swiper-pagination-progressbar.swiper-pagination-vertical.swiper-pagination-progressbar-opposite,.swiper-vertical>.swiper-pagination-progressbar.swiper-pagination-progressbar-opposite{width:100%;height:4px;left:0;top:0}.swiper-horizontal>.swiper-pagination-progressbar.swiper-pagination-progressbar-opposite,.swiper-pagination-progressbar.swiper-pagination-horizontal.swiper-pagination-progressbar-opposite,.swiper-pagination-progressbar.swiper-pagination-vertical,.swiper-vertical>.swiper-pagination-progressbar{width:4px;height:100%;left:0;top:0}.swiper-pagination-lock{display:none}.swiper-scrollbar{border-radius:10px;position:relative;-ms-touch-action:none;background:rgba(0,0,0,.1)}.swiper-scrollbar-disabled>.swiper-scrollbar,.swiper-scrollbar.swiper-scrollbar-disabled{display:none!important}.swiper-horizontal>.swiper-scrollbar,.swiper-scrollbar.swiper-scrollbar-horizontal{position:absolute;left:1%;bottom:3px;z-index:50;height:5px;width:98%}.swiper-scrollbar.swiper-scrollbar-vertical,.swiper-vertical>.swiper-scrollbar{position:absolute;right:3px;top:1%;z-index:50;width:5px;height:98%}.swiper-scrollbar-drag{height:100%;width:100%;position:relative;background:rgba(0,0,0,.5);border-radius:10px;left:0;top:0}.swiper-scrollbar-cursor-drag{cursor:move}.swiper-scrollbar-lock{display:none}.swiper-zoom-container{width:100%;height:100%;display:flex;justify-content:center;align-items:center;text-align:center}.swiper-zoom-container>canvas,.swiper-zoom-container>img,.swiper-zoom-container>svg{max-width:100%;max-height:100%;object-fit:contain}.swiper-slide-zoomed{cursor:move}.swiper-lazy-preloader{width:42px;height:42px;position:absolute;left:50%;top:50%;margin-left:-21px;margin-top:-21px;z-index:10;transform-origin:50%;box-sizing:border-box;border:4px solid var(--swiper-preloader-color,var(--swiper-theme-color));border-radius:50%;border-top-color:transparent}.swiper-watch-progress .swiper-slide-visible .swiper-lazy-preloader,.swiper:not(.swiper-watch-progress) .swiper-lazy-preloader{animation:swiper-preloader-spin 1s infinite linear}.swiper-lazy-preloader-white{--swiper-preloader-color:#fff}.swiper-lazy-preloader-black{--swiper-preloader-color:#000}@keyframes swiper-preloader-spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.swiper .swiper-notification{position:absolute;left:0;top:0;pointer-events:none;opacity:0;z-index:-1000}.swiper-free-mode>.swiper-wrapper{transition-timing-function:ease-out;margin:0 auto}.swiper-grid>.swiper-wrapper{flex-wrap:wrap}.swiper-grid-column>.swiper-wrapper{flex-wrap:wrap;flex-direction:column}.swiper-fade.swiper-free-mode .swiper-slide{transition-timing-function:ease-out}.swiper-fade .swiper-slide{pointer-events:none;transition-property:opacity}.swiper-fade .swiper-slide .swiper-slide{pointer-events:none}.swiper-fade .swiper-slide-active,.swiper-fade .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-cube{overflow:visible}.swiper-cube .swiper-slide{pointer-events:none;-webkit-backface-visibility:hidden;backface-visibility:hidden;z-index:1;visibility:hidden;transform-origin:0 0;width:100%;height:100%}.swiper-cube .swiper-slide .swiper-slide{pointer-events:none}.swiper-cube.swiper-rtl .swiper-slide{transform-origin:100% 0}.swiper-cube .swiper-slide-active,.swiper-cube .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-cube .swiper-slide-active,.swiper-cube .swiper-slide-next,.swiper-cube .swiper-slide-next+.swiper-slide,.swiper-cube .swiper-slide-prev{pointer-events:auto;visibility:visible}.swiper-cube .swiper-slide-shadow-bottom,.swiper-cube .swiper-slide-shadow-left,.swiper-cube .swiper-slide-shadow-right,.swiper-cube .swiper-slide-shadow-top{z-index:0;-webkit-backface-visibility:hidden;backface-visibility:hidden}.swiper-cube .swiper-cube-shadow{position:absolute;left:0;bottom:0px;width:100%;height:100%;opacity:.6;z-index:0}.swiper-cube .swiper-cube-shadow:before{content:'';background:#000;position:absolute;left:0;top:0;bottom:0;right:0;filter:blur(50px)}.swiper-flip{overflow:visible}.swiper-flip .swiper-slide{pointer-events:none;-webkit-backface-visibility:hidden;backface-visibility:hidden;z-index:1}.swiper-flip .swiper-slide .swiper-slide{pointer-events:none}.swiper-flip .swiper-slide-active,.swiper-flip .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-flip .swiper-slide-shadow-bottom,.swiper-flip .swiper-slide-shadow-left,.swiper-flip .swiper-slide-shadow-right,.swiper-flip .swiper-slide-shadow-top{z-index:0;-webkit-backface-visibility:hidden;backface-visibility:hidden}.swiper-creative .swiper-slide{-webkit-backface-visibility:hidden;backface-visibility:hidden;overflow:hidden;transition-property:transform,opacity,height}.swiper-cards{overflow:visible}.swiper-cards .swiper-slide{transform-origin:center bottom;-webkit-backface-visibility:hidden;backface-visibility:hidden;overflow:hidden} -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Towo Tech 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | 20 | 23 | 24 | 25 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 65 | 66 |
67 |
68 |
69 |
70 |
71 | Image 72 |
73 |
74 |
75 |
76 |

Welcome to

77 |

Towo Tech Garage Helper

78 |
79 | 83 |
84 |
85 |
86 |
87 | 88 | 89 |
90 |
91 |
92 |
93 |
94 | Image 95 |
96 |
97 |
98 |
99 |

About Us

100 | 101 |
102 |
103 |

104 | At TowO Tech, we are more than just a 105 | garage—we’re 106 | a team of passionate automotive experts 107 | dedicated to keeping you and 108 | your vehicle on the road safely and efficiently. 109 | With years of experience 110 | in the industry, we offer a full range of 111 | services, from towing and roadside 112 | assistance to comprehensive repairs and 113 | maintenance. Our mission is simple: 114 | to provide reliable, high-quality service with a 115 | personal touch, ensuring 116 | every vehicle we work on leaves in top 117 | condition. Whether it's a minor 118 | repair or an urgent breakdown, our skilled 119 | technicians use the latest technology and 120 | techniques to get the job done right. At TowO 121 | Tech, your satisfaction and safety are our top 122 | priorities. 123 | 124 |

125 |
126 |
127 |
128 |
129 | 130 | 131 |
132 | 133 |
134 | 135 |
136 |
137 |

Our Team

138 | 139 |
140 |
141 | 142 |
143 | 144 |
147 |
148 | 154 | 155 | 161 |
162 |

Niranga Nayanjith

163 | Back-End & Front-End Developer 164 | 165 |

I work in both back-end and front-end 166 | development, but my main focus is on 167 | building efficient back-end systems that 168 | integrate well with the front end. I aim 169 | to ensure that the entire application 170 | runs smoothly for a great user 171 | experience. I always try understand the 172 | full stack and it helps me collaborate 173 | easily 174 | with 175 | designers and front-end developers to 176 | create user-friendly applications. 177 | 178 |

profile on 182 | LinkedIn

profile on 186 | GitHub

187 |
188 |
189 |
190 | 191 |
193 |
194 |
195 | 196 | 202 |
203 |
204 |

Thisara Chethani

205 | Frontend Developer 206 |

UI/UX Designer & Front-End Developer 207 | I specialize in creating intuitive user 208 | interfaces and developing responsive, 209 | user-centered designs. 210 | With a passion for both design and 211 | functionality, I bridge the 212 | gap between aesthetics and technology, 213 | ensuring a seamless user experience across 214 | all platforms.

215 |

profile on 219 | LinkedIn

profile on 223 | Behance

224 |
225 |
226 |
227 | 228 |
230 |
231 |
232 | 233 | 239 |
240 |
241 |

Sahan Lochana

242 | BackEnd & FrontEnd Developer 243 |

I work on both front-end and back-end 244 | development 245 | to create user-friendly and efficient web 246 | applications. 247 | I design clean, responsive interfaces while 248 | ensuring smooth 249 | functionality behind the scenes. My focus is 250 | on delivering websites 251 | that not only look good but also perform 252 | well across various devices and platforms. 253 |

254 |

profile on 258 | LinkedIn

profile on 262 | GitHub

263 |
264 |
265 |
266 | 267 |
269 |
270 |
271 | 272 | 278 |
279 |
280 |

Jithmi Pranamya

281 | FrontEnd Developer 282 |

I am an IT undergraduate passionate about 283 | programming, innovation, 284 | and emerging technologies. I thrive on 285 | solving challenges, continuously learning, 286 | and applying creative solutions to 287 | real-world problems through code and 288 | technology.

289 |

profile on 293 | LinkedIn

profile on 297 | GitHub

298 |
299 |
300 |
301 | 302 |
303 | 304 |
305 | 306 |
307 | 308 | 309 | 346 | 347 | 348 | 349 | 350 | 351 | 352 |
353 |
354 |
355 | 356 | 357 | 358 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | script:src 372 | 373 | 374 | -------------------------------------------------------------------------------- /public/css/style.css: -------------------------------------------------------------------------------- 1 | /*******************************/ 2 | /********* General CSS *********/ 3 | /*******************************/ 4 | body { 5 | color: #444444; 6 | font-weight: 400; 7 | background: #ffffff; 8 | font-family: 'Barlow', sans-serif; 9 | } 10 | 11 | h1, 12 | h2, 13 | h3, 14 | h4, 15 | h5, 16 | h6 { 17 | color: #000000; 18 | } 19 | #map { 20 | height: 400px; 21 | width: 100%; 22 | } 23 | #coordinates { 24 | margin-top: 20px; 25 | font-size: 18px; 26 | } 27 | 28 | a { 29 | color: #ffffff; 30 | transition: .3s; 31 | } 32 | 33 | a:hover, 34 | a:active, 35 | a:focus { 36 | color: #ff0000; 37 | outline: none; 38 | text-decoration: none; 39 | } 40 | 41 | .user-pic{ 42 | width: 40px; 43 | border-radius: 50%; 44 | cursor: pointer; 45 | margin-left: 30px; 46 | } 47 | .btn.btn-custom { 48 | padding: 10px 30px 12px 30px; 49 | text-align: center; 50 | font-size: 16px; 51 | font-weight: 500; 52 | color: #ffffff; 53 | background: #ff0000 ; 54 | border: none; 55 | border-radius: 60px; 56 | box-shadow: inset 0 0 0 0 #ff0000; 57 | transition: ease-out 0.5s; 58 | -webkit-transition: ease-out 0.5s; 59 | -moz-transition: ease-out 0.5s; 60 | } 61 | 62 | .btn.btn-custom:hover { 63 | color: #ffffff; 64 | background: #ff0000; 65 | box-shadow: inset 200px 0 0 0 #ff0000; 66 | } 67 | 68 | .btn:focus, 69 | .form-control:focus { 70 | box-shadow: none; 71 | } 72 | 73 | .container-fluid { 74 | max-width: 1366px; 75 | } 76 | 77 | [class^="flaticon-"]:before, [class*=" flaticon-"]:before, 78 | [class^="flaticon-"]:after, [class*=" flaticon-"]:after { 79 | font-size: inherit; 80 | margin-left: 0; 81 | } 82 | 83 | 84 | /**********************************/ 85 | /****** Loader & Back to Top ******/ 86 | /**********************************/ 87 | #loader { 88 | position: fixed; 89 | top: 0; 90 | right: 0; 91 | bottom: 0; 92 | left: 0; 93 | display: flex; 94 | align-items: center; 95 | justify-content: center; 96 | background: #ffffff; 97 | opacity: 0; 98 | visibility: hidden; 99 | -webkit-transition: opacity .3s ease-out, visibility 0s linear .3s; 100 | -o-transition: opacity .3s ease-out, visibility 0s linear .3s; 101 | transition: opacity .3s ease-out, visibility 0s linear .3s; 102 | z-index: 999; 103 | } 104 | 105 | #loader.show { 106 | -webkit-transition: opacity .6s ease-out, visibility 0s linear 0s; 107 | -o-transition: opacity .6s ease-out, visibility 0s linear 0s; 108 | transition: opacity .6s ease-out, visibility 0s linear 0s; 109 | visibility: visible; 110 | opacity: 1; 111 | } 112 | 113 | #loader .loader { 114 | position: relative; 115 | width: 45px; 116 | height: 45px; 117 | border: 5px solid #dddddd; 118 | border-top: 5px solid #E81C2E; 119 | border-radius: 50%; 120 | -webkit-animation: spin 2s linear infinite; 121 | animation: spin 2s linear infinite; 122 | } 123 | 124 | @-webkit-keyframes spin { 125 | 0% { -webkit-transform: rotate(0deg); } 126 | 100% { -webkit-transform: rotate(360deg); } 127 | } 128 | 129 | @keyframes spin { 130 | 0% { transform: rotate(0deg); } 131 | 100% { transform: rotate(360deg); } 132 | } 133 | 134 | .back-to-top { 135 | position: fixed; 136 | display: none; 137 | width: 44px; 138 | height: 44px; 139 | text-align: center; 140 | line-height: 1; 141 | font-size: 22px; 142 | right: 15px; 143 | bottom: 15px; 144 | transition: .5s; 145 | background: #ff0000; 146 | border-radius: 44px; 147 | z-index: 9; 148 | } 149 | 150 | .back-to-top i { 151 | color: #ffffff; 152 | padding-top: 10px; 153 | } 154 | 155 | .back-to-top:hover { 156 | background: #202C45; 157 | } 158 | 159 | 160 | /**********************************/ 161 | /********** Top Bar CSS ***********/ 162 | /**********************************/ 163 | .top-bar { 164 | position: relative; 165 | height: 75px; 166 | display: flex; 167 | align-items: center; 168 | background: #ffffff; 169 | } 170 | 171 | .top-bar .logo { 172 | text-align:left; 173 | overflow: hidden; 174 | } 175 | 176 | .top-bar .logo h1 { 177 | margin: -4px 0 0 0; 178 | color: #2E86C1; 179 | font-size: 50px; 180 | line-height: 50px; 181 | font-weight: 800; 182 | letter-spacing: 1px; 183 | font-style: italic; 184 | } 185 | 186 | .top-bar .logo h1 span { 187 | color: #797D7F; 188 | } 189 | 190 | .top-bar .logo img { 191 | max-width: 100%; 192 | max-height: 60px; 193 | position: absolute; 194 | margin-top: 15px; 195 | margin-right: 500px; 196 | 197 | } 198 | 199 | .top-bar .top-bar-item { 200 | display: flex; 201 | align-items: center; 202 | justify-content: flex-end; 203 | } 204 | 205 | .top-bar .top-bar-icon { 206 | width: 40px; 207 | height: 40px; 208 | display: flex; 209 | align-items: center; 210 | justify-content: center; 211 | background: #202C45; 212 | border-radius: 40px; 213 | } 214 | 215 | .top-bar .top-bar-icon i { 216 | margin: 0; 217 | color: #ffffff; 218 | font-size: 16px; 219 | } 220 | 221 | .top-bar .top-bar-text { 222 | padding-left: 15px; 223 | } 224 | 225 | .top-bar .top-bar-text h3 { 226 | margin: 0 0 5px 0; 227 | font-size: 18px; 228 | font-weight: 600; 229 | } 230 | 231 | .top-bar .top-bar-text p { 232 | margin: 0; 233 | font-size: 14px; 234 | font-weight: 400; 235 | } 236 | 237 | @media (max-width: 991.98px) { 238 | .top-bar .logo { 239 | text-align:center; 240 | } 241 | } 242 | 243 | 244 | /**********************************/ 245 | /*********** Nav Bar CSS **********/ 246 | /**********************************/ 247 | .nav-bar { 248 | position: relative; 249 | background: #ff0000; 250 | } 251 | 252 | .nav-bar.nav-sticky { 253 | position: left; 254 | width: 100%; 255 | top: 0; 256 | left: 0; 257 | box-shadow: 0 2px 5px rgba(0, 0, 0, .3); 258 | z-index: 999; 259 | } 260 | 261 | .nav-bar .navbar { 262 | padding: 20px 0; 263 | background: #ff0000 !important; 264 | transition: .3s; 265 | } 266 | 267 | .nav-bar.nav-sticky .navbar { 268 | padding: 5px 0; 269 | } 270 | 271 | .navbar-dark .navbar-nav .nav-link, 272 | .navbar-dark .navbar-nav .nav-link:focus, 273 | .navbar-dark .navbar-nav .nav-link:hover, 274 | .navbar-dark .navbar-nav .nav-link.active { 275 | color: #ffffff; 276 | padding: 15px; 277 | font-weight: 500; 278 | letter-spacing: 1px; 279 | } 280 | 281 | .navbar-dark .navbar-nav .nav-link:hover, 282 | .navbar-dark .navbar-nav .nav-link.active { 283 | color:#ffffff; 284 | } 285 | 286 | .nav-bar .dropdown-menu { 287 | margin-top: 0; 288 | border: 0; 289 | border-radius: 0; 290 | background: #ffffff; 291 | } 292 | 293 | .nav-bar .btn.btn-custom { 294 | color: #ff0000; 295 | background:#ffffff; 296 | 297 | } 298 | 299 | .nav-bar .btn:hover { 300 | color: #ff0000; 301 | background: #ffffff; 302 | box-shadow: inset 200px 0 0 0 #ffffff; 303 | } 304 | 305 | @media (min-width: 992px) { 306 | .nav-bar .navbar-brand { 307 | display: none; 308 | } 309 | } 310 | 311 | @media (max-width: 991.98px) { 312 | .navbar-dark .navbar-nav .nav-link, 313 | .navbar-dark .navbar-nav .nav-link:focus, 314 | .navbar-dark .navbar-nav .nav-link:hover, 315 | .navbar-dark .navbar-nav .nav-link.active { 316 | padding: 5px 0; 317 | } 318 | 319 | .nav-bar .dropdown-menu { 320 | box-shadow: none; 321 | } 322 | 323 | .nav-bar .btn { 324 | display: none; 325 | } 326 | } 327 | 328 | 329 | /*******************************/ 330 | /********** Hero CSS ***********/ 331 | /*******************************/ 332 | .carousel { 333 | position: relative; 334 | width: 50%; 335 | min-height: 100px; 336 | background: #ffffff; 337 | margin-bottom: 45px; 338 | } 339 | 340 | .carousel .container-fluid { 341 | padding: 0; 342 | } 343 | 344 | .carousel .carousel-item { 345 | position: relative; 346 | width: 100%; 347 | min-height: 400px; 348 | display: flex; 349 | align-items: center; 350 | justify-content: center; 351 | flex-direction: column; 352 | } 353 | 354 | .carousel .carousel-img { 355 | position: relative; 356 | width: 100%; 357 | height: 100%; 358 | min-height: 400px; 359 | text-align: right; 360 | overflow: hidden; 361 | } 362 | 363 | .carousel .carousel-img::after { 364 | position: absolute; 365 | content: ""; 366 | top: 0; 367 | right: 0; 368 | bottom: 0; 369 | left: 0; 370 | background: rgba(0, 0, 0, .5); 371 | z-index: 1; 372 | } 373 | 374 | .carousel .carousel-img img { 375 | width: 100%; 376 | height: 100%; 377 | object-fit: cover; 378 | } 379 | 380 | .carousel .carousel-text { 381 | position: absolute; 382 | max-width: 992px; 383 | padding: 0 15px; 384 | text-align: center; 385 | display: flex; 386 | align-items: center; 387 | justify-content: center; 388 | flex-direction: column; 389 | z-index: 2; 390 | } 391 | 392 | .carousel .carousel-text h3 { 393 | color: #ffffff; 394 | font-size: 20px; 395 | font-weight: 700; 396 | letter-spacing: 4px; 397 | text-transform: uppercase; 398 | margin-bottom: 0px; 399 | } 400 | 401 | .carousel .carousel-text h1 { 402 | color: #ffffff; 403 | font-size: 90px; 404 | font-weight: 700; 405 | margin-bottom: 20px; 406 | text-transform: capitalize; 407 | } 408 | 409 | .carousel .carousel-text p { 410 | max-width: 500px; 411 | color: #ffffff; 412 | font-size: 18px; 413 | margin-bottom: 40px; 414 | } 415 | 416 | .carousel .btn.btn-custom { 417 | padding: 20px 45px 22px 45px; 418 | color: #ffffff; 419 | background-color: #0D47A1; 420 | } 421 | 422 | .carousel .btn.btn-custom:hover { 423 | color: #0D47A1; 424 | } 425 | 426 | .carousel .owl-nav { 427 | position: absolute; 428 | width: 100%; 429 | height: 50px; 430 | top: calc(50% - 25px); 431 | left: 0; 432 | display: flex; 433 | justify-content: space-between; 434 | z-index: 9; 435 | } 436 | 437 | .carousel .owl-nav .owl-prev, 438 | .carousel .owl-nav .owl-next { 439 | width: 50px; 440 | height: 50px; 441 | display: flex; 442 | align-items: center; 443 | justify-content: center; 444 | color: #ffffff; 445 | border-radius: 50px; 446 | background: rgba(256, 256, 256, .2); 447 | font-size: 22px; 448 | transition: .5s; 449 | } 450 | 451 | .carousel .owl-nav .owl-prev { 452 | margin-left: 30px; 453 | } 454 | 455 | .carousel .owl-nav .owl-next { 456 | margin-right: 30px; 457 | } 458 | 459 | .carousel .owl-nav .owl-prev:hover, 460 | .carousel .owl-nav .owl-next:hover { 461 | color: #ffffff; 462 | background: #0D47A1 ; 463 | } 464 | 465 | .carousel .animated { 466 | -webkit-animation-duration: 1s; 467 | animation-duration: 1s; 468 | } 469 | 470 | @media (max-width: 991.98px) { 471 | .carousel .carousel-text h3 { 472 | margin-bottom: 5px; 473 | } 474 | 475 | .carousel .carousel-text h1 { 476 | font-size: 60px; 477 | } 478 | 479 | .carousel .carousel-text p { 480 | font-size: 16px; 481 | } 482 | 483 | .carousel .carousel-text .btn { 484 | padding: 12px 30px; 485 | font-size: 15px; 486 | letter-spacing: 0; 487 | } 488 | } 489 | 490 | @media (max-width: 767.98px) { 491 | .carousel .carousel-text h3 { 492 | font-size: 18px; 493 | letter-spacing: 2px; 494 | margin-bottom: 15px; 495 | } 496 | 497 | .carousel .carousel-text h1 { 498 | font-size: 45px; 499 | } 500 | 501 | .carousel .carousel-text .btn { 502 | padding: 10px 25px; 503 | font-size: 15px; 504 | letter-spacing: 0; 505 | } 506 | } 507 | 508 | @media (max-width: 575.98px) { 509 | .carousel .carousel-text h3 { 510 | font-size: 14px; 511 | letter-spacing: 1px; 512 | margin-bottom: 10px; 513 | } 514 | 515 | .carousel .carousel-text h1 { 516 | font-size: 30px; 517 | margin-bottom: 15px; 518 | } 519 | 520 | .carousel .carousel-text p { 521 | margin-bottom: 25px; 522 | } 523 | 524 | .carousel .carousel-text .btn { 525 | padding: 8px 20px; 526 | font-size: 14px; 527 | letter-spacing: 0; 528 | } 529 | } 530 | 531 | 532 | /*******************************/ 533 | /******* Page Header CSS *******/ 534 | /*******************************/ 535 | .page-header { 536 | position: relative; 537 | margin-bottom: 45px; 538 | padding: 90px 0; 539 | text-align: center; 540 | background: #3498DB; 541 | border-top: 1px dotted #ffffff; 542 | } 543 | 544 | .page-header h2 { 545 | position: relative; 546 | color: #ffffff; 547 | font-size: 60px; 548 | font-weight: 700; 549 | margin-bottom: 20px; 550 | padding-bottom: 5px; 551 | } 552 | 553 | .page-header h2::after { 554 | position: absolute; 555 | content: ""; 556 | width: 100px; 557 | height: 2px; 558 | left: calc(50% - 50px); 559 | bottom: 0; 560 | background: #ffffff; 561 | } 562 | 563 | .page-header a { 564 | position: relative; 565 | padding: 0 12px; 566 | font-size: 22px; 567 | color: #ffffff; 568 | } 569 | 570 | .page-header a:hover { 571 | color: #0D47A1; 572 | } 573 | 574 | .page-header a::after { 575 | position: absolute; 576 | content: "/"; 577 | width: 8px; 578 | height: 8px; 579 | top: -2px; 580 | right: -7px; 581 | text-align: center; 582 | color: #ffffff; 583 | } 584 | 585 | .page-header a:last-child::after { 586 | display: none; 587 | } 588 | 589 | @media (max-width: 991.98px) { 590 | .page-header { 591 | padding: 60px 0; 592 | } 593 | 594 | .page-header h2 { 595 | font-size: 45px; 596 | } 597 | 598 | .page-header a { 599 | font-size: 20px; 600 | } 601 | } 602 | 603 | @media (max-width: 767.98px) { 604 | .page-header { 605 | padding: 45px 0; 606 | } 607 | 608 | .page-header h2 { 609 | font-size: 35px; 610 | } 611 | 612 | .page-header a { 613 | font-size: 18px; 614 | } 615 | } 616 | 617 | 618 | /*******************************/ 619 | /******* Section Header ********/ 620 | /*******************************/ 621 | .section-header { 622 | position: relative; 623 | width: 100%; 624 | max-width: 700px; 625 | margin: 0 auto 45px auto; 626 | } 627 | 628 | .section-header p { 629 | display: inline-block; 630 | margin-bottom: 10px; 631 | padding-bottom: 5px; 632 | position: relative; 633 | font-size: 16px; 634 | font-weight: 700; 635 | letter-spacing: 4px; 636 | text-transform: uppercase; 637 | color: #a10d0d; 638 | } 639 | 640 | .section-header p::after { 641 | position: absolute; 642 | content: ""; 643 | width: 50%; 644 | height: 2px; 645 | left: 25%; 646 | bottom: 0; 647 | background: #0D47A1; 648 | } 649 | 650 | .section-header.text-left p::after { 651 | left: 0; 652 | } 653 | 654 | .section-header.text-right p::after { 655 | left: 50%; 656 | } 657 | 658 | .section-header h2 { 659 | margin: 0; 660 | font-size: 45px; 661 | font-weight: 700; 662 | text-transform: capitalize; 663 | } 664 | 665 | @media (max-width: 991.98px) { 666 | .section-header h2 { 667 | font-size: 45px; 668 | } 669 | } 670 | 671 | @media (max-width: 767.98px) { 672 | .section-header h2 { 673 | font-size: 40px; 674 | } 675 | } 676 | 677 | @media (max-width: 575.98px) { 678 | .section-header h2 { 679 | font-size: 35px; 680 | } 681 | } 682 | 683 | 684 | /*******************************/ 685 | /********** About CSS **********/ 686 | /*******************************/ 687 | .about { 688 | position: relative; 689 | width: 100%; 690 | padding: 45px 0 15px 0; 691 | } 692 | 693 | .about .section-header { 694 | margin-bottom: 30px; 695 | margin-left: 0; 696 | } 697 | 698 | 699 | 700 | .about .about-img img { 701 | width: 100%; 702 | border-radius: 5px; 703 | margin-bottom: 30px; 704 | } 705 | 706 | .about .about-content { 707 | margin-bottom: 30px; 708 | } 709 | 710 | .about .about-content ul { 711 | margin: 0; 712 | padding: 0; 713 | list-style: none; 714 | margin-bottom: 25px; 715 | } 716 | 717 | .about .about-content ul li { 718 | margin-bottom: 5px; 719 | } 720 | 721 | .about .about-content ul li i { 722 | margin-right: 8px; 723 | color: #ff0000; 724 | } 725 | /*-------------------------------------------------------------- 726 | # Team 727 | --------------------------------------------------------------*/ 728 | .team { 729 | background: #fff; 730 | padding: 60px 0; 731 | } 732 | 733 | .team .member { 734 | overflow: hidden; 735 | text-align: center; 736 | border-radius: 5px; 737 | background: #fff; 738 | box-shadow: 0px 0 30px rgba(1, 41, 112, 0.08); 739 | transition: 0.3s; 740 | } 741 | 742 | .team .member .member-img { 743 | position: relative; 744 | overflow: hidden; 745 | } 746 | 747 | .team .member .member-img:after { 748 | position: absolute; 749 | content: ""; 750 | left: 0; 751 | bottom: 0; 752 | height: 100%; 753 | width: 100%; 754 | background: url(../img/team-shape.svg) no-repeat center bottom; 755 | background-size: contain; 756 | z-index: 1; 757 | } 758 | 759 | .team .member .social { 760 | position: absolute; 761 | right: -100%; 762 | top: 30px; 763 | opacity: 0; 764 | border-radius: 4px; 765 | transition: 0.5s; 766 | background: rgba(255, 255, 255, 0.3); 767 | z-index: 2; 768 | } 769 | 770 | .team .member .social a { 771 | transition: color 0.3s; 772 | color: rgba(243, 0, 0, 0.5); 773 | margin: 15px 12px; 774 | display: block; 775 | line-height: 0; 776 | text-align: center; 777 | } 778 | 779 | .team .member .social a:hover { 780 | color: rgba(255, 0, 0, 0.8); 781 | } 782 | 783 | .team .member .social i { 784 | font-size: 18px; 785 | } 786 | 787 | .team .member .member-info { 788 | padding: 10px 15px 20px 15px; 789 | } 790 | 791 | .team .member .member-info h4 { 792 | font-weight: 700; 793 | margin-bottom: 5px; 794 | font-size: 20px; 795 | color: #ff0000; 796 | } 797 | 798 | .team .member .member-info span { 799 | display: block; 800 | font-size: 14px; 801 | font-weight: 400; 802 | color: #aaaaaa; 803 | } 804 | 805 | .team .member .member-info p { 806 | font-style: italic; 807 | font-size: 14px; 808 | padding-top: 15px; 809 | line-height: 26px; 810 | color: #5e5e5e; 811 | } 812 | 813 | .team .member:hover { 814 | transform: scale(1.08); 815 | box-shadow: 0px 0 30px rgba(255, 0, 0, 0.1); 816 | } 817 | 818 | .team .member:hover .social { 819 | right: 8px; 820 | opacity: 1; 821 | } 822 | 823 | 824 | /*******************************/ 825 | /********* Footer CSS **********/ 826 | /*******************************/ 827 | .footer { 828 | margin-top: 50px; 829 | margin: 0; 830 | padding: 0; 831 | background: #ffffff; 832 | 833 | } 834 | 835 | .footer .footer-contact, 836 | .footer .footer-link, 837 | .footer .footer-newsletter { 838 | position: relative; 839 | margin-bottom: 45px; 840 | color: #ffffff; 841 | } 842 | 843 | .footer .footer-contact h2, 844 | .footer .footer-link h2, 845 | .footer .footer-newsletter h2 { 846 | margin-bottom: 40px; 847 | scroll-padding-right: 40px; 848 | font-size: 20px; 849 | font-weight: 700; 850 | letter-spacing: 2px; 851 | color: #ffffff; 852 | } 853 | 854 | .footer .footer-link a { 855 | display: block; 856 | margin-bottom: 10px; 857 | color: #ffffff; 858 | transition: .3s; 859 | } 860 | 861 | .footer .footer-link a::before { 862 | position: relative; 863 | content: "\f105"; 864 | font-family: "Font Awesome 5 Free"; 865 | font-weight: 900; 866 | margin-right: 10px; 867 | } 868 | 869 | .footer .footer-link a:hover { 870 | color: #ffffff; 871 | letter-spacing: 1px; 872 | } 873 | 874 | .footer .footer-contact p i { 875 | width: 25px; 876 | } 877 | 878 | .footer .footer-social { 879 | position: relative; 880 | margin-top: 20px; 881 | display: flex; 882 | } 883 | 884 | .footer .footer-social a { 885 | width: 40px; 886 | height: 40px; 887 | display: flex; 888 | align-items: center; 889 | justify-content: center; 890 | color: #ff0000; 891 | background: #ffffff; 892 | border-radius: 40px; 893 | margin-right: 5px; 894 | transition: .5s; 895 | } 896 | 897 | .footer .footer-social a:last-child { 898 | margin: 0; 899 | } 900 | 901 | .footer .footer-social a:hover { 902 | color: #ffffff; 903 | background: #ffffff; 904 | } 905 | 906 | .footer .footer-newsletter form { 907 | position: relative; 908 | width: 100%; 909 | } 910 | 911 | .footer .footer-newsletter input { 912 | margin-bottom: 15px; 913 | height: 45px; 914 | background: transparent; 915 | border: 1px solid #ffffff; 916 | border-radius: 5px; 917 | } 918 | 919 | .footer .footer-newsletter label { 920 | margin-top: 5px; 921 | color: #777777; 922 | font-size: 14px; 923 | letter-spacing: 1px; 924 | } 925 | 926 | .footer .footer-newsletter .btn.btn-custom { 927 | width: 100%; 928 | color: #920000; 929 | background: #ffffff; 930 | box-shadow: inset 0 0 0 0 #ffffff; 931 | } 932 | 933 | .footer .footer-newsletter .btn:hover { 934 | color: #ffffff; 935 | background: #E81C2E; 936 | box-shadow: inset 200px 0 0 0 #E81C2E; 937 | } 938 | 939 | .footer .copyright { 940 | text-align: center; 941 | padding-top: 15px; 942 | padding-bottom: 45px; 943 | } 944 | 945 | .footer .copyright p { 946 | margin: 0; 947 | color: #ffffff; 948 | } 949 | 950 | .footer .copyright p a { 951 | color: #090909; 952 | font-weight: 700; 953 | letter-spacing: 1px; 954 | } 955 | 956 | .footer .copyright p a:hover { 957 | color: #ffffff; 958 | } 959 | --------------------------------------------------------------------------------