├── script ├── config │ └── config.JSON ├── package-lock.json ├── time.js ├── themes.js └── weather.js ├── img ├── gold.WebP ├── guts.WebP ├── alcest.WebP ├── griffith.WebP └── pastel.WebP ├── README.md ├── index.html └── css └── styles.css /script/config/config.JSON: -------------------------------------------------------------------------------- 1 | { 2 | "weatherToken": "" 3 | } -------------------------------------------------------------------------------- /img/gold.WebP: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmeerMoustafa/Forbidden-startpage/HEAD/img/gold.WebP -------------------------------------------------------------------------------- /img/guts.WebP: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmeerMoustafa/Forbidden-startpage/HEAD/img/guts.WebP -------------------------------------------------------------------------------- /img/alcest.WebP: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmeerMoustafa/Forbidden-startpage/HEAD/img/alcest.WebP -------------------------------------------------------------------------------- /img/griffith.WebP: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmeerMoustafa/Forbidden-startpage/HEAD/img/griffith.WebP -------------------------------------------------------------------------------- /img/pastel.WebP: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmeerMoustafa/Forbidden-startpage/HEAD/img/pastel.WebP -------------------------------------------------------------------------------- /script/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "script", 3 | "lockfileVersion": 3, 4 | "requires": true, 5 | "packages": {} 6 | } 7 | -------------------------------------------------------------------------------- /script/time.js: -------------------------------------------------------------------------------- 1 | // Formats and Displays the current Day and Time 2 | const displayDate = setInterval(() => { 3 | const date = new Date() 4 | const day = date.getDay() 5 | const dayOfWeek = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] 6 | const today = dayOfWeek[day] 7 | 8 | document.getElementsByClassName("date")[0].innerHTML = today 9 | document.getElementsByClassName("time")[0].innerHTML = date.toLocaleTimeString([], { 10 | hour: 'numeric', 11 | minute: 'numeric' 12 | }) 13 | }, 1000) -------------------------------------------------------------------------------- /script/themes.js: -------------------------------------------------------------------------------- 1 | themeRandomizer = () => { 2 | const theme = ["gold", "pastel", "alcest", "griffith", "guts"] 3 | const random = theme[Math.floor(Math.random() * theme.length)] 4 | return random 5 | } 6 | 7 | setTheme = () => { 8 | const selector = document.getElementsByClassName("image")[0] 9 | savedTheme = localStorage.getItem('theme') 10 | if(savedTheme) { 11 | document.documentElement.className = savedTheme 12 | } 13 | 14 | 15 | 16 | selector.addEventListener("click", () => { 17 | theme = themeRandomizer() 18 | document.documentElement.className = theme 19 | localStorage.setItem('theme', theme) 20 | }) 21 | } 22 | 23 | setTheme() -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Forbidden-startpage 2 | A simple startpage with a few themes to choose from. Made for personal use, practice and fun. Been learning web development for a few months. I am very open for suggestions on improving this project and will very much appreciate feedback.

3 | ![](http://ForTheBadge.com/images/badges/built-with-love.svg)

4 | [live Preview](https://forbidden-startpage.pages.dev/) 5 | 6 | ### features: 7 | 8 | - Multiple Themes 9 | - Get a random theme from the list by clicking on the image 10 | - Localstorage support to save selected theme 11 | - Date/Time and Weather 12 | 13 | 14 | # Themes 15 | 16 | ## Guts 17 | ![guts](https://github.com/ForbiddenShadow/Forbidden-startpage/assets/9211143/c8f331b9-05db-4fa7-86c2-d2bab8b98e8a) 18 | 19 | ## Griffith 20 | ![griffith](https://github.com/ForbiddenShadow/Forbidden-startpage/assets/9211143/fd30d62f-33fd-4c78-bc40-ea44dfc27386) 21 | 22 | ## Gold 23 | ![gold](https://github.com/ForbiddenShadow/Forbidden-startpage/assets/9211143/a9321af0-5f7f-43da-9793-2d78b5ea4ef1) 24 | 25 | ## Pastel 26 | ![pastel](https://github.com/ForbiddenShadow/Forbidden-startpage/assets/9211143/9d72ae80-2ed3-4820-b998-6c709d6a282c) 27 | 28 | ## Alcest 29 | ![alcest](https://github.com/ForbiddenShadow/Forbidden-startpage/assets/9211143/f4f75030-f3a9-4d5a-bdbe-359d7ff3579c) 30 | 31 | ### How to add weather suppot 32 | 33 | Simply go to the config.JSON file in your config folder and paster your openweatherAPI key there. -------------------------------------------------------------------------------- /script/weather.js: -------------------------------------------------------------------------------- 1 | const { weatherAPI } = require('./config/config.JSON') 2 | 3 | 4 | // Initial API call 5 | const getWeather = async () => { 6 | const res = await fetch(`https://api.openweathermap.org/data/2.5/weather?lat=33.8938&lon=35.5018&appid=${weatherAPI}&units=metric`) 7 | const weather = await res.json() 8 | return weather 9 | } 10 | 11 | //regex to return the first number from the API's weather condition ID 12 | const conditionChecker = async() => { 13 | const weather = await getWeather() 14 | const re = new RegExp(/\d/) 15 | const weatherCondition = weather.weather[0].id.toString() 16 | const firstInt = weatherCondition.match(re).toString() 17 | return firstInt 18 | } 19 | 20 | 21 | //Displays a different FontAwesome Icon on night/day rain/shine 22 | const displayWeather = async () => { 23 | weather = await getWeather() 24 | weatherCondition = await conditionChecker() 25 | const date = new Date 26 | hours = date.getHours() 27 | if(hours >= 18 || hours <= 6){ 28 | document.getElementsByClassName("weather")[0].innerHTML = ` ${weather.main.temp}°` 29 | 30 | if(weatherCondition == 2 || weatherCondition == 3 || weatherCondition == 5) { 31 | document.getElementsByClassName("weather")[0].innerHTML = ` ${weather.main.temp}°` 32 | } 33 | 34 | } 35 | 36 | else { 37 | document.getElementsByClassName("weather")[0].innerHTML = ` ${weather.main.temp}°` 38 | if(weatherCondition === 2 || weatherCondition === 3 || weatherCondition === 5) { 39 | document.getElementsByClassName("weather")[0].innerHTML = ` ${weather.main.temp}°` 40 | } 41 | } 42 | } 43 | 44 | displayWeather() -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Welcome 13 | 14 | 15 | 16 | main image 17 | 18 | 19 |
20 | 21 |
22 |

Welcome, Ameer

23 |
24 | 25 | | 26 | 27 | | 28 | 29 |
30 |
31 | 32 | 33 |
34 | 35 |
36 |

37 | 38 | Social 39 |

40 | 41 | Twitter 42 | Reddit 43 | Dev.to 44 | Proton 45 | 46 |
47 | 48 | 49 | 50 |
51 |

52 | 53 | Dev 54 |

55 | 56 | Codecademy 57 | Github 58 | MDN Docs 59 | Javascript.info 60 | 61 |
62 | 63 | 64 | 65 |
66 |

67 | 68 | Read 69 |

70 | 71 | Goodreads 72 | Medium 73 | Libgen 74 | CreepyPasta 75 | 76 |
77 | 78 | 79 |
80 |

81 | 82 | Linux 83 |

84 | 85 | Explainshell 86 | Arch Wiki 87 | Distrowatch 88 | Unix Porn 89 | 90 |
91 | 92 | 93 |
94 |

95 | 96 | Hack 97 |

98 | 99 | HTB 100 | TryHackMe 101 | OWASP Top 10 102 | Any.run 103 | 104 |
105 |
106 |
107 | 108 | -------------------------------------------------------------------------------- /css/styles.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Overpass:ital@0;1&family=Space+Mono:wght@700&display=swap'); 2 | 3 | 4 | :root, 5 | :root.guts { 6 | --background-color: #060505ff; 7 | --header-color: #A60E10ff; 8 | --status-color: #F0F0F0ff; 9 | --title-color: #A60E10ff; 10 | --link-color: #F0F0F0ff; 11 | --hover-color: #1C1C1Cff; 12 | --image: url("/img/guts.WebP") 13 | } 14 | 15 | :root.pastel { 16 | --background-color: #FDF4F5; 17 | --header-color: #BA90C6; 18 | --status-color: #BA90C6; 19 | --title-color: #E8A0BF; 20 | --link-color: #BA90C6; 21 | --hover-color: #C0DBEA; 22 | --image: url("/img/pastel.WebP") 23 | } 24 | 25 | :root.alcest { 26 | --background-color: #08151Dff; 27 | --header-color: #7A8996ff; 28 | --status-color: #475464ff; 29 | --title-color: #7A8996ff; 30 | --link-color: #D4DED6ff; 31 | --hover-color: #7A8996ff; 32 | --image: url("/img/alcest.WebP") 33 | } 34 | 35 | :root.griffith { 36 | --background-color: #75989Aff; 37 | --header-color: #353636ff; 38 | --status-color: #F0F0F0ff; 39 | --title-color: #353636ff; 40 | --link-color: #F0F0F0ff; 41 | --hover-color: #353636ff; 42 | --image: url("/img/griffith.WebP") 43 | } 44 | 45 | 46 | 47 | :root.gold { 48 | --background-color: #18122B; 49 | --header-color: #D99433; 50 | --status-color: #EDF0E8; 51 | --title-color: #D99433; 52 | --link-color: #EDF0E8; 53 | --hover-color: #433F57; 54 | --image: url("/img/gold.WebP") 55 | } 56 | 57 | 58 | 59 | * { 60 | padding: 0; 61 | margin: 0; 62 | } 63 | 64 | body { 65 | display: grid; 66 | grid-template-columns: repeat(2, 1fr); 67 | grid-template-rows: repeat(3, 1fr); 68 | gap: 20px; 69 | height: 100vh; 70 | background-color: var(--background-color); 71 | } 72 | 73 | .content-container{ 74 | grid-column: 2; 75 | grid-row: 2; 76 | } 77 | 78 | .header-container{ 79 | text-align: center; 80 | } 81 | 82 | h1 { 83 | color: var(--header-color); 84 | font-family: 'Space Mono', monospace; 85 | font-size: 5rem; 86 | margin-right: 14vh; 87 | } 88 | 89 | .status-strip { 90 | margin-right: 14vh; 91 | margin-top: 1vh; 92 | margin-bottom: 8vh; 93 | color:var(--status-color); 94 | font-family: 'Overpass', sans-serif; 95 | font-size: 1.5rem; 96 | } 97 | 98 | span { 99 | margin-left: 2vh; 100 | } 101 | 102 | .card-container { 103 | height: 30vh; 104 | display: flex; 105 | flex-flow: row wrap; 106 | gap: 20px; 107 | } 108 | 109 | .container { 110 | display: flex; 111 | flex-direction: column; 112 | align-items: center; 113 | gap: 2%; 114 | width: 15vh; 115 | height: 30vh; 116 | text-align: center; 117 | } 118 | 119 | 120 | 121 | .title { 122 | margin-top: 2vh; 123 | font-family: 'Space Mono', monospace; 124 | color: var(--title-color); 125 | font-size: 1.3rem; 126 | } 127 | 128 | a { 129 | font-family: 'Overpass', sans-serif; 130 | text-decoration: none; 131 | font-size: 1.2rem; 132 | color: var(--link-color); 133 | margin-top: 2vh; 134 | } 135 | 136 | a:hover { 137 | 138 | color: var(--hover-color); 139 | } 140 | 141 | img { 142 | grid-column: 1; 143 | border-radius: 8px; 144 | grid-row: 2; 145 | justify-self: end; 146 | width: 60vh; 147 | height: 60vh; 148 | margin-right: 15vh; 149 | content: var(--image); 150 | box-shadow: 0 10px 20px rgba(0, 0, 0, 0.25), 0 5px 5px rgba(0, 0, 0, 0.12); 151 | } 152 | 153 | .grow { 154 | transition: all .2s ease-in-out; 155 | cursor: pointer; 156 | } 157 | 158 | .grow:hover { 159 | transform: scale(1.1); 160 | cursor: pointer; 161 | } 162 | --------------------------------------------------------------------------------