├── .prettierignore ├── .gitignore ├── images ├── large.png └── vscode.png ├── .github └── workflows │ └── jekyll-docker.yml ├── LICENSE ├── README.md ├── css └── styles.css ├── index.html └── js └── scripts.js /.prettierignore: -------------------------------------------------------------------------------- 1 | *.html -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .vscode -------------------------------------------------------------------------------- /images/large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BobsProgrammingAcademy/responsive-sales-dashboard/HEAD/images/large.png -------------------------------------------------------------------------------- /images/vscode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BobsProgrammingAcademy/responsive-sales-dashboard/HEAD/images/vscode.png -------------------------------------------------------------------------------- /.github/workflows/jekyll-docker.yml: -------------------------------------------------------------------------------- 1 | name: Jekyll site CI 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | 7 | pull_request: 8 | branches: [master] 9 | 10 | jobs: 11 | build: 12 | 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - name: Checkout source Git branch 17 | uses: actions/checkout@v4 18 | 19 | - name: Build the site in the jekyll/builder container 20 | run: | 21 | docker run \ 22 | -v ${{ github.workspace }}:/srv/jekyll -v ${{ github.workspace }}/_site:/srv/jekyll/_site \ 23 | jekyll/builder:latest /bin/bash -c "chmod -R 777 /srv/jekyll && jekyll build --future" 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Bob's Programming Academy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Responsive Sales Dashboard 2 | 3 | This is a responsive sales dashboard built using **HTML 5**, **CSS 3**, and **JavaScript**. Charts were built using **ApexCharts 3**. 4 | 5 | ![plot](https://github.com/BobsProgrammingAcademy/responsive-sales-dashboard/blob/master/images/large.png?raw=true) 6 | 7 | ## Table of Contents 8 | 9 | - [Prerequisites](#prerequisites) 10 | - [Running the application](#run-the-application) 11 | - [Copyright and License](#copyright-and-license) 12 | 13 | ## Prerequisites 14 | 15 | Install the following prerequisites: 16 | 17 | - [Visual Studio Code](https://code.visualstudio.com/download) with the **Live Server** extension. 18 | 19 | [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer) allows us to launch a local development server that enables a live reload of our project. 20 | 21 | ## Run the application 22 | 23 | To run the application, start the **Live Server** by clicking **Go Live** in the bottom right corner of the status bar in Visual Studio Code. This action will load the website in your default web browser. 24 | 25 | ![plot](https://github.com/BobsProgrammingAcademy/responsive-sales-dashboard/blob/master/images/vscode.png?raw=true) 26 | 27 | ## View the application 28 | 29 | Once the **Live Server** is up and running, go to http://127.0.0.1:5500/index.html to view the application. 30 | 31 | ## Copyright and License 32 | 33 | Copyright © 2022 Bob's Programming Academy. Code released under the MIT license. 34 | -------------------------------------------------------------------------------- /css/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | background-color: #1d2634; 5 | color: #9e9ea4; 6 | font-family: 'Montserrat', sans-serif; 7 | } 8 | 9 | .material-icons-outlined { 10 | vertical-align: middle; 11 | line-height: 1px; 12 | font-size: 35px; 13 | } 14 | 15 | .grid-container { 16 | display: grid; 17 | grid-template-columns: 260px 1fr 1fr 1fr; 18 | grid-template-rows: 0.2fr 3fr; 19 | grid-template-areas: 20 | 'sidebar header header header' 21 | 'sidebar main main main'; 22 | height: 100vh; 23 | } 24 | 25 | /* ---------- HEADER ---------- */ 26 | .header { 27 | grid-area: header; 28 | height: 70px; 29 | display: flex; 30 | align-items: center; 31 | justify-content: space-between; 32 | padding: 0 30px 0 30px; 33 | box-shadow: 0 6px 7px -3px rgba(0, 0, 0, 0.35); 34 | } 35 | 36 | .menu-icon { 37 | display: none; 38 | } 39 | 40 | /* ---------- SIDEBAR ---------- */ 41 | 42 | #sidebar { 43 | grid-area: sidebar; 44 | height: 100%; 45 | background-color: #263043; 46 | overflow-y: auto; 47 | transition: all 0.5s; 48 | -webkit-transition: all 0.5s; 49 | } 50 | 51 | .sidebar-title { 52 | display: flex; 53 | justify-content: space-between; 54 | align-items: center; 55 | padding: 30px 30px 30px 30px; 56 | margin-bottom: 30px; 57 | } 58 | 59 | .sidebar-title > span { 60 | display: none; 61 | } 62 | 63 | .sidebar-brand { 64 | margin-top: 15px; 65 | font-size: 20px; 66 | font-weight: 700; 67 | } 68 | 69 | .sidebar-list { 70 | padding: 0; 71 | margin-top: 15px; 72 | list-style-type: none; 73 | } 74 | 75 | .sidebar-list-item { 76 | padding: 20px 20px 20px 20px; 77 | font-size: 18px; 78 | } 79 | 80 | .sidebar-list-item:hover { 81 | background-color: rgba(255, 255, 255, 0.2); 82 | cursor: pointer; 83 | } 84 | 85 | .sidebar-list-item > a { 86 | text-decoration: none; 87 | color: #9e9ea4; 88 | } 89 | 90 | .sidebar-responsive { 91 | display: inline !important; 92 | position: absolute; 93 | /* 94 | the z-index of the ApexCharts is 11 95 | we want the z-index of the sidebar higher so that 96 | the charts are not showing over the sidebar 97 | on small screens 98 | */ 99 | z-index: 12 !important; 100 | } 101 | 102 | /* ---------- MAIN ---------- */ 103 | 104 | .main-container { 105 | grid-area: main; 106 | overflow-y: auto; 107 | padding: 20px 20px; 108 | color: rgba(255, 255, 255, 0.95); 109 | } 110 | 111 | .main-title { 112 | display: flex; 113 | justify-content: space-between; 114 | } 115 | 116 | .main-cards { 117 | display: grid; 118 | grid-template-columns: 1fr 1fr 1fr 1fr; 119 | gap: 20px; 120 | margin: 20px 0; 121 | } 122 | 123 | .card { 124 | display: flex; 125 | flex-direction: column; 126 | justify-content: space-around; 127 | padding: 25px; 128 | border-radius: 5px; 129 | } 130 | 131 | .card:first-child { 132 | background-color: #2962ff; 133 | } 134 | 135 | .card:nth-child(2) { 136 | background-color: #ff6d00; 137 | } 138 | 139 | .card:nth-child(3) { 140 | background-color: #2e7d32; 141 | } 142 | 143 | .card:nth-child(4) { 144 | background-color: #d50000; 145 | } 146 | 147 | .card-inner { 148 | display: flex; 149 | align-items: center; 150 | justify-content: space-between; 151 | } 152 | 153 | .card-inner > .material-icons-outlined { 154 | font-size: 45px; 155 | } 156 | 157 | .charts { 158 | display: grid; 159 | grid-template-columns: 1fr 1fr; 160 | gap: 20px; 161 | margin-top: 60px; 162 | } 163 | 164 | .charts-card { 165 | background-color: #263043; 166 | margin-bottom: 20px; 167 | padding: 25px; 168 | box-sizing: border-box; 169 | -webkit-column-break-inside: avoid; 170 | border-radius: 5px; 171 | box-shadow: 0 6px 7px -4px rgba(0, 0, 0, 0.2); 172 | } 173 | 174 | .chart-title { 175 | display: flex; 176 | align-items: center; 177 | justify-content: center; 178 | } 179 | 180 | /* ---------- MEDIA QUERIES ---------- */ 181 | 182 | /* Medium <= 992px */ 183 | 184 | @media screen and (max-width: 992px) { 185 | .grid-container { 186 | grid-template-columns: 1fr; 187 | grid-template-rows: 0.2fr 3fr; 188 | grid-template-areas: 189 | 'header' 190 | 'main'; 191 | } 192 | 193 | #sidebar { 194 | display: none; 195 | } 196 | 197 | .menu-icon { 198 | display: inline; 199 | } 200 | 201 | .sidebar-title > span { 202 | display: inline; 203 | } 204 | } 205 | 206 | /* Small <= 768px */ 207 | 208 | @media screen and (max-width: 768px) { 209 | .main-cards { 210 | grid-template-columns: 1fr; 211 | gap: 10px; 212 | margin-bottom: 0; 213 | } 214 | 215 | .charts { 216 | grid-template-columns: 1fr; 217 | margin-top: 30px; 218 | } 219 | } 220 | 221 | /* Extra Small <= 576px */ 222 | 223 | @media screen and (max-width: 576px) { 224 | .hedaer-left { 225 | display: none; 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Admin Dashboard 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 |
22 | 25 |
26 | search 27 |
28 |
29 | notifications 30 | email 31 | account_circle 32 |
33 |
34 | 35 | 36 | 37 | 83 | 84 | 85 | 86 |
87 |
88 |

DASHBOARD

89 |
90 | 91 |
92 | 93 |
94 |
95 |

PRODUCTS

96 | inventory_2 97 |
98 |

249

99 |
100 | 101 |
102 |
103 |

CATEGORIES

104 | category 105 |
106 |

25

107 |
108 | 109 |
110 |
111 |

CUSTOMERS

112 | groups 113 |
114 |

1500

115 |
116 | 117 |
118 |
119 |

ALERTS

120 | notification_important 121 |
122 |

56

123 |
124 | 125 |
126 | 127 |
128 | 129 |
130 |

Top 5 Products

131 |
132 |
133 | 134 |
135 |

Purchase and Sales Orders

136 |
137 |
138 | 139 |
140 |
141 | 142 | 143 |
144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /js/scripts.js: -------------------------------------------------------------------------------- 1 | // SIDEBAR TOGGLE 2 | 3 | let sidebarOpen = false; 4 | const sidebar = document.getElementById('sidebar'); 5 | 6 | function openSidebar() { 7 | if (!sidebarOpen) { 8 | sidebar.classList.add('sidebar-responsive'); 9 | sidebarOpen = true; 10 | } 11 | } 12 | 13 | function closeSidebar() { 14 | if (sidebarOpen) { 15 | sidebar.classList.remove('sidebar-responsive'); 16 | sidebarOpen = false; 17 | } 18 | } 19 | 20 | // ---------- CHARTS ---------- 21 | 22 | // BAR CHART 23 | const barChartOptions = { 24 | series: [ 25 | { 26 | data: [10, 8, 6, 4, 2], 27 | name: 'Products', 28 | }, 29 | ], 30 | chart: { 31 | type: 'bar', 32 | background: 'transparent', 33 | height: 350, 34 | toolbar: { 35 | show: false, 36 | }, 37 | }, 38 | colors: ['#2962ff', '#d50000', '#2e7d32', '#ff6d00', '#583cb3'], 39 | plotOptions: { 40 | bar: { 41 | distributed: true, 42 | borderRadius: 4, 43 | horizontal: false, 44 | columnWidth: '40%', 45 | }, 46 | }, 47 | dataLabels: { 48 | enabled: false, 49 | }, 50 | fill: { 51 | opacity: 1, 52 | }, 53 | grid: { 54 | borderColor: '#55596e', 55 | yaxis: { 56 | lines: { 57 | show: true, 58 | }, 59 | }, 60 | xaxis: { 61 | lines: { 62 | show: true, 63 | }, 64 | }, 65 | }, 66 | legend: { 67 | labels: { 68 | colors: '#f5f7ff', 69 | }, 70 | show: true, 71 | position: 'top', 72 | }, 73 | stroke: { 74 | colors: ['transparent'], 75 | show: true, 76 | width: 2, 77 | }, 78 | tooltip: { 79 | shared: true, 80 | intersect: false, 81 | theme: 'dark', 82 | }, 83 | xaxis: { 84 | categories: ['Laptop', 'Phone', 'Monitor', 'Headphones', 'Camera'], 85 | title: { 86 | style: { 87 | color: '#f5f7ff', 88 | }, 89 | }, 90 | axisBorder: { 91 | show: true, 92 | color: '#55596e', 93 | }, 94 | axisTicks: { 95 | show: true, 96 | color: '#55596e', 97 | }, 98 | labels: { 99 | style: { 100 | colors: '#f5f7ff', 101 | }, 102 | }, 103 | }, 104 | yaxis: { 105 | title: { 106 | text: 'Count', 107 | style: { 108 | color: '#f5f7ff', 109 | }, 110 | }, 111 | axisBorder: { 112 | color: '#55596e', 113 | show: true, 114 | }, 115 | axisTicks: { 116 | color: '#55596e', 117 | show: true, 118 | }, 119 | labels: { 120 | style: { 121 | colors: '#f5f7ff', 122 | }, 123 | }, 124 | }, 125 | }; 126 | 127 | const barChart = new ApexCharts( 128 | document.querySelector('#bar-chart'), 129 | barChartOptions 130 | ); 131 | barChart.render(); 132 | 133 | // AREA CHART 134 | const areaChartOptions = { 135 | series: [ 136 | { 137 | name: 'Purchase Orders', 138 | data: [31, 40, 28, 51, 42, 109, 100], 139 | }, 140 | { 141 | name: 'Sales Orders', 142 | data: [11, 32, 45, 32, 34, 52, 41], 143 | }, 144 | ], 145 | chart: { 146 | type: 'area', 147 | background: 'transparent', 148 | height: 350, 149 | stacked: false, 150 | toolbar: { 151 | show: false, 152 | }, 153 | }, 154 | colors: ['#00ab57', '#d50000'], 155 | labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul'], 156 | dataLabels: { 157 | enabled: false, 158 | }, 159 | fill: { 160 | gradient: { 161 | opacityFrom: 0.4, 162 | opacityTo: 0.1, 163 | shadeIntensity: 1, 164 | stops: [0, 100], 165 | type: 'vertical', 166 | }, 167 | type: 'gradient', 168 | }, 169 | grid: { 170 | borderColor: '#55596e', 171 | yaxis: { 172 | lines: { 173 | show: true, 174 | }, 175 | }, 176 | xaxis: { 177 | lines: { 178 | show: true, 179 | }, 180 | }, 181 | }, 182 | legend: { 183 | labels: { 184 | colors: '#f5f7ff', 185 | }, 186 | show: true, 187 | position: 'top', 188 | }, 189 | markers: { 190 | size: 6, 191 | strokeColors: '#1b2635', 192 | strokeWidth: 3, 193 | }, 194 | stroke: { 195 | curve: 'smooth', 196 | }, 197 | xaxis: { 198 | axisBorder: { 199 | color: '#55596e', 200 | show: true, 201 | }, 202 | axisTicks: { 203 | color: '#55596e', 204 | show: true, 205 | }, 206 | labels: { 207 | offsetY: 5, 208 | style: { 209 | colors: '#f5f7ff', 210 | }, 211 | }, 212 | }, 213 | yaxis: [ 214 | { 215 | title: { 216 | text: 'Purchase Orders', 217 | style: { 218 | color: '#f5f7ff', 219 | }, 220 | }, 221 | labels: { 222 | style: { 223 | colors: ['#f5f7ff'], 224 | }, 225 | }, 226 | }, 227 | { 228 | opposite: true, 229 | title: { 230 | text: 'Sales Orders', 231 | style: { 232 | color: '#f5f7ff', 233 | }, 234 | }, 235 | labels: { 236 | style: { 237 | colors: ['#f5f7ff'], 238 | }, 239 | }, 240 | }, 241 | ], 242 | tooltip: { 243 | shared: true, 244 | intersect: false, 245 | theme: 'dark', 246 | }, 247 | }; 248 | 249 | const areaChart = new ApexCharts( 250 | document.querySelector('#area-chart'), 251 | areaChartOptions 252 | ); 253 | areaChart.render(); 254 | --------------------------------------------------------------------------------