├── .apiConfig.example ├── .gitignore ├── README.md ├── assets └── style.css ├── go.mod ├── index.html └── main.go /.apiConfig.example: -------------------------------------------------------------------------------- 1 | { 2 | "OpenWeatherMapApiKey":"[put your open weather map api key here]" 3 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .apiConfig -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Weather Tracker 2 | 3 | Weather Tracker is a web application that allows users to search for the weather conditions of a specific city. The application fetches data from the OpenWeatherMap API and displays it in a user-friendly format. 4 | 5 | ## Features 6 | 7 | - Search for the current weather of any city. 8 | - Display temperature in Celsius. 9 | - Show additional weather details such as humidity, wind speed, and rain possibility. 10 | - Display weather icons and country flags. 11 | 12 | ## Installation 13 | 14 | ### Prerequisites 15 | 16 | - Go (version 1.22 or later) 17 | - OpenWeatherMap API key 18 | 19 | ### Steps 20 | 21 | 1. Clone the repository: 22 | 23 | ```sh 24 | git clone https://github.com/hamzamaach/weather-tracker.git 25 | cd weather-tracker 26 | ``` 27 | 28 | 2. Rename the `.apiConfig.example` file to `.apiConfig` and add your OpenWeatherMap API key: 29 | 30 | ```sh 31 | mv .apiConfig.example .apiConfig 32 | ``` 33 | 34 | Edit the `.apiConfig` file to include your OpenWeatherMap API key: 35 | 36 | ```json 37 | { 38 | "OpenWeatherMapApiKey": "[put your open weather map api key here]" 39 | } 40 | ``` 41 | 48 | 3. Run the application: 49 | 50 | ```sh 51 | go run main.go 52 | ``` 53 | 54 | The application will be accessible at `http://localhost:8080`. 55 | 56 | ## Usage 57 | 58 | 1. Open your web browser and go to `http://localhost:8080`. 59 | 2. Enter the name of a city in the search box and click the search button. 60 | 3. The weather information for the city will be displayed. 61 | 62 | ## Project Structure 63 | 64 | - `main.go`: The main Go file containing the server and handler functions. 65 | - `assets/`: Directory containing static assets like CSS files. 66 | - `index.html`: The main HTML template for the web application. 67 | - `.apiConfig`: Configuration file for storing the OpenWeatherMap API key. 68 | 69 | ## API Endpoints 70 | 71 | - `/`: The main endpoint for searching and displaying weather information. 72 | 73 | 74 | ## Contributing 75 | 76 | 1. Fork the repository. 77 | 2. Create your feature branch (`git checkout -b feature/AmazingFeature`). 78 | 3. Commit your changes (`git commit -m 'Add some AmazingFeature'`). 79 | 4. Push to the branch (`git push origin feature/AmazingFeature`). 80 | 5. Open a pull request. 81 | 82 | ## Acknowledgements 83 | 84 | - OpenWeatherMap for providing the weather data API. 85 | - Flagcdn for providing country flag images. 86 | 87 | --- 88 | 89 | Feel free to reach out if you have any questions or suggestions! -------------------------------------------------------------------------------- /assets/style.css: -------------------------------------------------------------------------------- 1 | html { 2 | font-family: 'Roboto Slab', sans-serif; 3 | } 4 | 5 | body { 6 | background: #55D6F4; 7 | color: #313E48; 8 | } 9 | 10 | img { 11 | max-width: 100%; 12 | } 13 | 14 | .box { 15 | margin: 1em auto; 16 | background: #f0f0f0; 17 | padding: 2em 0; 18 | width: 50%; 19 | border-radius: 1rem; 20 | box-shadow: 0px 1px 7px rgba(0, 0, 0, 0.25); 21 | } 22 | 23 | .box:hover { 24 | box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.5); 25 | } 26 | 27 | input:focus { 28 | outline: none; 29 | } 30 | 31 | 32 | .box h1 { 33 | font-size: 2em; 34 | text-align: center; 35 | } 36 | 37 | .box .temp { 38 | font-size: 7em; 39 | line-height: 1; 40 | text-align: center; 41 | display: block; 42 | padding-left: 30px; 43 | margin-bottom: 24px; 44 | } 45 | 46 | .box .high-low { 47 | font-size: 2em; 48 | color: lighten(#313E48, 20%); 49 | text-align: center; 50 | display: block; 51 | font-weight: 100; 52 | } 53 | 54 | .weather .icon { 55 | position: relative; 56 | margin: 0 auto; 57 | } 58 | 59 | .spin { 60 | position: absolute; 61 | top: 16px; 62 | right: 18px; 63 | text-align: center; 64 | width: 65px; 65 | } 66 | 67 | .city { 68 | margin-top: 0px; 69 | } 70 | 71 | .local-time { 72 | color: orangered; 73 | margin-top: 25px; 74 | text-align: center; 75 | display: block; 76 | } 77 | 78 | .details-div { 79 | display: grid; 80 | grid-template-columns: 1fr 1fr; 81 | grid-gap: 10px; 82 | border-left: solid orangered 3px; 83 | margin: 1rem 0 0 6rem; 84 | padding-left: 1rem; 85 | } 86 | 87 | .details { 88 | display: block; 89 | } 90 | .sun{ 91 | text-align: center; 92 | display: flex; 93 | gap: 25px; 94 | margin: 1rem 0 0 0; 95 | justify-content: end; 96 | padding-right: 2rem; 97 | } 98 | .sun-title { 99 | display: block; 100 | color: orangered; 101 | font-size: 0.8rem; 102 | margin: auto; 103 | } 104 | .sun-value{ 105 | display: block; 106 | margin-top: 7px; 107 | font-weight: 600; 108 | } 109 | 110 | .bubble.black { 111 | background-color: #8f8f8f; 112 | position: relative; 113 | width: 100px; 114 | height: 100px; 115 | padding: 0px; 116 | border-radius: 50px; 117 | } 118 | 119 | .bubble.black:after { 120 | content: ""; 121 | position: absolute; 122 | bottom: -14px; 123 | left: 14px; 124 | border-style: solid; 125 | border-width: 29px 15px 0; 126 | border-color: #8f8f8f transparent; 127 | display: block; 128 | width: 0; 129 | z-index: 1; 130 | transform: rotate(30deg); 131 | } 132 | 133 | .spin img { 134 | animation: spin 5s linear infinite; 135 | animation-play-state: paused; 136 | } 137 | 138 | .box:hover .spin img { 139 | animation-play-state: running; 140 | } 141 | 142 | .tb { 143 | display: table; 144 | width: 100%; 145 | } 146 | 147 | .td { 148 | display: table-cell; 149 | vertical-align: middle; 150 | } 151 | 152 | input, 153 | button { 154 | color: #fff; 155 | font-family: Nunito; 156 | padding: 0; 157 | margin: 0; 158 | border: 0; 159 | background-color: transparent; 160 | } 161 | 162 | #cover { 163 | width: 550px; 164 | padding: 35px; 165 | margin: auto; 166 | background-color: orangered; 167 | border-radius: 20px; 168 | box-shadow: 0 10px 40px orangered, 0 0 0 20px #ffffffeb; 169 | transform: scale(0.6); 170 | } 171 | 172 | form { 173 | height: 96px; 174 | } 175 | 176 | input[type="text"] { 177 | width: 100%; 178 | height: 96px; 179 | font-size: 60px; 180 | line-height: 1; 181 | } 182 | 183 | input[type="text"]::placeholder { 184 | color: #e16868; 185 | } 186 | 187 | #s-cover { 188 | width: 1px; 189 | padding-left: 35px; 190 | } 191 | 192 | button { 193 | position: relative; 194 | display: block; 195 | width: 84px; 196 | height: 96px; 197 | cursor: pointer; 198 | } 199 | 200 | #s-circle { 201 | position: relative; 202 | top: -8px; 203 | left: 0; 204 | width: 43px; 205 | height: 43px; 206 | margin-top: 0; 207 | border-width: 15px; 208 | border: 15px solid #fff; 209 | background-color: transparent; 210 | border-radius: 50%; 211 | transition: 0.5s ease all; 212 | } 213 | 214 | .not-found { 215 | display: flex; 216 | justify-content: center; 217 | } 218 | 219 | button span { 220 | position: absolute; 221 | top: 68px; 222 | left: 43px; 223 | display: block; 224 | width: 45px; 225 | height: 15px; 226 | background-color: transparent; 227 | border-radius: 10px; 228 | transform: rotateZ(52deg); 229 | transition: 0.5s ease all; 230 | } 231 | 232 | button span:before, 233 | button span:after { 234 | content: ""; 235 | position: absolute; 236 | bottom: 0; 237 | right: 0; 238 | width: 45px; 239 | height: 15px; 240 | background-color: #fff; 241 | border-radius: 10px; 242 | transform: rotateZ(0); 243 | transition: 0.5s ease all; 244 | } 245 | 246 | #s-cover:hover #s-circle { 247 | top: -1px; 248 | width: 67px; 249 | height: 15px; 250 | border-width: 0; 251 | background-color: #fff; 252 | border-radius: 20px; 253 | } 254 | 255 | #s-cover:hover span { 256 | top: 50%; 257 | left: 56px; 258 | width: 25px; 259 | margin-top: -9px; 260 | transform: rotateZ(0); 261 | } 262 | 263 | #s-cover:hover button span:before { 264 | bottom: 11px; 265 | transform: rotateZ(52deg); 266 | } 267 | 268 | #s-cover:hover button span:after { 269 | bottom: -11px; 270 | transform: rotateZ(-52deg); 271 | } 272 | 273 | #s-cover:hover button span:before, 274 | #s-cover:hover button span:after { 275 | right: -6px; 276 | width: 40px; 277 | background-color: #fff; 278 | } -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/hamzamaach/weather-tracker-go 2 | 3 | go 1.22.3 4 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 |