├── .gitignore ├── .prettierrc ├── CHANGELOG.md ├── LICENSE ├── README.md ├── package-lock.json ├── package.json ├── postcss.config.js ├── public ├── assets │ ├── css │ │ ├── tailwind.css │ │ └── tailwind.output.css │ ├── img │ │ ├── create-account-office-dark.jpeg │ │ ├── create-account-office.jpeg │ │ ├── dashboard.png │ │ ├── forgot-password-office-dark.jpeg │ │ ├── forgot-password-office.jpeg │ │ ├── github.svg │ │ ├── login-office-dark.jpeg │ │ ├── login-office.jpeg │ │ └── twitter.svg │ └── js │ │ ├── charts-bars.js │ │ ├── charts-lines.js │ │ ├── charts-pie.js │ │ ├── focus-trap.js │ │ └── init-alpine.js ├── buttons.html ├── cards.html ├── charts.html ├── forms.html ├── index.html ├── modals.html ├── pages │ ├── 404.html │ ├── blank.html │ ├── create-account.html │ ├── forgot-password.html │ └── login.html └── tables.html └── tailwind.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "htmlWhitespaceSensitivity": "ignore", 3 | "singleQuote": true, 4 | "semi": false 5 | } 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [1.0.2](https://github.com/estevanmaito/windmill-dashboard/compare/1.0.1...1.0.2) (2020-07-18) 2 | 3 | This is the first real "release". Nothing has changed, except for some SEO meta tags, that are no longer needed as the project is no longer hosted isolated. 4 | 5 | This way you don't have to delete almost half of the `index.html` head just to start a project. 6 | 7 | ## 1.0.1 (2020-07-01) 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Estevan Maito 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 | # Windmill Dashboard 2 | 3 | A multi theme, completely accessible, with components and pages examples, ready for production dashboard. 4 | 5 | 🧪 [See it live](https://windmillui.com/dashboard-html) 6 | 7 | - 🦮 Thoroughly accessible 8 | - 🌗 Light and dark themes 9 | - 💅 Styled with Tailwind CSS 10 | - 🧩 Various components 11 | - ❄ [React version](https://windmillui.com/dashboard-react) 12 | 13 | ## 🚀 Usage 14 | 15 | Clone or download this repo and everything you need is inside the `public` folder. 16 | 17 | ## 🦮 Accessibility 18 | 19 | This dashboard was developed with a11y in mind since the beginning. 20 | 21 | 1. Every text passes the WCAG Level AA (at least) 22 | 2. It is completely keyboard navigable 23 | 3. I actually used [NVDA](https://www.nvaccess.org/) to read my screen during development 24 | 25 | Everybody can benefit with good accessibility practices, like the modal, for example ([test it live](https://windmill-dashboard.vercel.app/modals.html)). It uses focus trap techniques to not loose focus when navigating via keyboard and thinking of mobile users with large screen devices, it is placed in the bottom of the screen. 26 | 27 | ## 🌗 Multi theme 28 | 29 | It uses Tailwind CSS for styling, and some may say it is totally biased, but it uses the most simple theming plugin there is for it, [Tailwind Multi Theme plugin](https://github.com/estevanmaito/tailwindcss-multi-theme#tailwind-css-multi-theme) (made by me). The result is that, as with regular Tailwind, you have control over every style in your pages. 30 | 31 | You can see that by navigating through the examples, changing theme and going visiting pages like login or create account, to see different images served for different themes. 32 | 33 | Theme auto detection based on user's OS preferences and local settings storage are enabled by default. 34 | 35 | ## 🔮 Future 36 | 37 | TODO 38 | 39 | - [ ] Make charts accessible through hidden data 40 | - [ ] Refactor and split `shadow-outline-` plugin 41 | - [ ] Paginate tables with Alpine 42 | - [ ] Focus first element when dropdowns are opened 43 | 44 | ## OSS used 45 | 46 | - [Tailwind CSS](https://tailwindcss.com/) 47 | - [Tailwind Multi Theme](https://github.com/estevanmaito/tailwindcss-multi-theme) 48 | - [Tailwind Custom Forms](https://github.com/tailwindlabs/tailwindcss-custom-forms) 49 | - [PostCSS](https://postcss.org/) 50 | - [Alpine.js](https://github.com/alpinejs/alpine) 51 | - [Chart.js (charts)](https://www.chartjs.org/) 52 | - [UI Faces (avatars)](https://uifaces.co/) 53 | - [Heroicons (icons)](https://heroicons.dev/) 54 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "windmill-dashboard", 3 | "version": "1.0.2", 4 | "description": "A multi theme, completely accessible, with components and pages examples, ready for production dashboard.", 5 | "scripts": { 6 | "tailwind": "tailwindcss build public/assets/css/tailwind.css -o public/assets/css/tailwind.output.css", 7 | "build": "env NODE_ENV=production postcss public/assets/css/tailwind.css -o public/assets/css/tailwind.output.css", 8 | "cz": "git-cz", 9 | "release": "release-it" 10 | }, 11 | "author": "Estevan Maito ", 12 | "license": "MIT", 13 | "devDependencies": { 14 | "@release-it/conventional-changelog": "1.1.4", 15 | "@tailwindcss/custom-forms": "0.2.1", 16 | "autoprefixer": "9.8.0", 17 | "color": "3.1.2", 18 | "commitizen": "4.1.2", 19 | "cssnano": "4.1.10", 20 | "cz-conventional-changelog": "3.2.0", 21 | "postcss-cli": "7.1.1", 22 | "release-it": "13.6.4", 23 | "tailwindcss": "1.4.6", 24 | "tailwindcss-multi-theme": "1.0.3" 25 | }, 26 | "keywords": [ 27 | "tailwind", 28 | "windmill", 29 | "dashboard", 30 | "template", 31 | "admin" 32 | ], 33 | "release-it": { 34 | "github": { 35 | "release": true 36 | }, 37 | "npm": { 38 | "publish": false 39 | }, 40 | "plugins": { 41 | "@release-it/conventional-changelog": { 42 | "preset": "angular", 43 | "infile": "CHANGELOG.md" 44 | } 45 | } 46 | }, 47 | "config": { 48 | "commitizen": { 49 | "path": "./node_modules/cz-conventional-changelog" 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | require('tailwindcss'), 4 | require('autoprefixer'), 5 | require('cssnano')({ 6 | preset: 'default', 7 | }), 8 | ], 9 | } 10 | -------------------------------------------------------------------------------- /public/assets/css/tailwind.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /public/assets/css/tailwind.output.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}button{background-color:transparent;background-image:none;padding:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}fieldset,ol,ul{margin:0;padding:0}ol,ul{list-style:none}html{font-family:Inter,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}*,:after,:before{box-sizing:border-box;border:0 solid #d5d6d7}hr{border-top-width:1px}img{border-style:solid}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#a0aec0}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#a0aec0}input::-ms-input-placeholder,textarea::-ms-input-placeholder{color:#a0aec0}input::placeholder,textarea::placeholder{color:#a0aec0}[role=button],button{cursor:pointer}table{border-collapse:collapse}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}button,input,optgroup,select,textarea{padding:0;line-height:inherit;color:inherit}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}.form-input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-color:#e2e8f0;border-width:1px;border-radius:.25rem;padding:.5rem .75rem;font-size:1rem;line-height:1.5}.form-input::-moz-placeholder{color:#9e9e9e;opacity:1}.form-input:-ms-input-placeholder{color:#9e9e9e;opacity:1}.form-input::-ms-input-placeholder{color:#9e9e9e;opacity:1}.form-input::placeholder{color:#9e9e9e;opacity:1}.form-input:focus{outline:none;box-shadow:0 0 0 3px rgba(66,153,225,.5);border-color:#63b3ed}.form-textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-color:#e2e8f0;border-width:1px;border-radius:.25rem;padding:.5rem .75rem;font-size:1rem;line-height:1.5}.form-textarea::-moz-placeholder{color:#9e9e9e;opacity:1}.form-textarea:-ms-input-placeholder{color:#9e9e9e;opacity:1}.form-textarea::-ms-input-placeholder{color:#9e9e9e;opacity:1}.form-textarea::placeholder{color:#9e9e9e;opacity:1}.form-textarea:focus{outline:none;box-shadow:0 0 0 3px rgba(66,153,225,.5);border-color:#63b3ed}.form-multiselect{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-color:#e2e8f0;border-width:1px;border-radius:.25rem;padding:.5rem .75rem;font-size:1rem;line-height:1.5}.form-multiselect:focus{outline:none;box-shadow:0 0 0 3px rgba(66,153,225,.5);border-color:#63b3ed}.form-select{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23a0aec0'%3E%3Cpath d='M15.3 9.3a1 1 0 011.4 1.4l-4 4a1 1 0 01-1.4 0l-4-4a1 1 0 011.4-1.4l3.3 3.29 3.3-3.3z'/%3E%3C/svg%3E");-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-print-color-adjust:exact;color-adjust:exact;background-repeat:no-repeat;background-color:#fff;border-color:#e2e8f0;border-width:1px;border-radius:.25rem;padding:.5rem 2.5rem .5rem .75rem;font-size:1rem;line-height:1.5;background-position:right .5rem center;background-size:1.5em 1.5em}.form-select::-ms-expand{color:#a0aec0;border:none}@media not print{.form-select::-ms-expand{display:none}}@media print and (-ms-high-contrast:active),print and (-ms-high-contrast:none){.form-select{padding-right:.75rem}}.form-select:focus{outline:none;box-shadow:0 0 0 3px rgba(66,153,225,.5);border-color:#63b3ed}.form-checkbox{-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-print-color-adjust:exact;color-adjust:exact;display:inline-block;vertical-align:middle;background-origin:border-box;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;flex-shrink:0;height:1em;width:1em;color:#4299e1;background-color:#fff;border-color:#e2e8f0;border-width:1px;border-radius:.25rem}.form-checkbox:checked{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 16 16' fill='%23fff' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M5.707 7.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4a1 1 0 00-1.414-1.414L7 8.586 5.707 7.293z'/%3E%3C/svg%3E");border-color:transparent;background-color:currentColor;background-size:100% 100%;background-position:50%;background-repeat:no-repeat}@media not print{.form-checkbox::-ms-check{border-width:1px;color:transparent;background:inherit;border-color:inherit;border-radius:inherit}}.form-checkbox:focus{outline:none;box-shadow:0 0 0 3px rgba(66,153,225,.5);border-color:#63b3ed}.form-radio{-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-print-color-adjust:exact;color-adjust:exact;display:inline-block;vertical-align:middle;background-origin:border-box;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;flex-shrink:0;border-radius:100%;height:1em;width:1em;color:#4299e1;background-color:#fff;border-color:#e2e8f0;border-width:1px}.form-radio:checked{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 16 16' fill='%23fff' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='8' cy='8' r='3'/%3E%3C/svg%3E");border-color:transparent;background-color:currentColor;background-size:100% 100%;background-position:50%;background-repeat:no-repeat}@media not print{.form-radio::-ms-check{border-width:1px;color:transparent;background:inherit;border-color:inherit;border-radius:inherit}}.form-radio:focus{outline:none;box-shadow:0 0 0 3px rgba(66,153,225,.5);border-color:#63b3ed}.space-y-2>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(0.5rem*(1 - var(--space-y-reverse)));margin-bottom:calc(0.5rem*var(--space-y-reverse))}.space-x-3>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(0.75rem*var(--space-x-reverse));margin-left:calc(0.75rem*(1 - var(--space-x-reverse)))}.space-y-4>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1rem*(1 - var(--space-y-reverse)));margin-bottom:calc(1rem*var(--space-y-reverse))}.space-x-4>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1rem*var(--space-x-reverse));margin-left:calc(1rem*(1 - var(--space-x-reverse)))}.space-x-6>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1.5rem*var(--space-x-reverse));margin-left:calc(1.5rem*(1 - var(--space-x-reverse)))}.divide-y>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(1px*(1 - var(--divide-y-reverse)));border-bottom-width:calc(1px*var(--divide-y-reverse))}.theme-dark .dark\:divide-gray-700>:not(template)~:not(template){--divide-opacity:1;border-color:#24262d;border-color:rgba(36,38,45,var(--divide-opacity))}.bg-white{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.bg-black{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.bg-gray-50{--bg-opacity:1;background-color:#f9fafb;background-color:rgba(249,250,251,var(--bg-opacity))}.bg-gray-100{--bg-opacity:1;background-color:#f4f5f7;background-color:rgba(244,245,247,var(--bg-opacity))}.bg-red-100{--bg-opacity:1;background-color:#fde8e8;background-color:rgba(253,232,232,var(--bg-opacity))}.bg-red-600{--bg-opacity:1;background-color:#e02424;background-color:rgba(224,36,36,var(--bg-opacity))}.bg-orange-100{--bg-opacity:1;background-color:#feecdc;background-color:rgba(254,236,220,var(--bg-opacity))}.bg-green-100{--bg-opacity:1;background-color:#def7ec;background-color:rgba(222,247,236,var(--bg-opacity))}.bg-teal-100{--bg-opacity:1;background-color:#d5f5f6;background-color:rgba(213,245,246,var(--bg-opacity))}.bg-teal-500{--bg-opacity:1;background-color:#0694a2;background-color:rgba(6,148,162,var(--bg-opacity))}.bg-teal-600{--bg-opacity:1;background-color:#047481;background-color:rgba(4,116,129,var(--bg-opacity))}.bg-blue-100{--bg-opacity:1;background-color:#e1effe;background-color:rgba(225,239,254,var(--bg-opacity))}.bg-blue-500{--bg-opacity:1;background-color:#3f83f8;background-color:rgba(63,131,248,var(--bg-opacity))}.bg-blue-600{--bg-opacity:1;background-color:#1c64f2;background-color:rgba(28,100,242,var(--bg-opacity))}.bg-purple-600{--bg-opacity:1;background-color:#7e3af2;background-color:rgba(126,58,242,var(--bg-opacity))}.hover\:bg-gray-100:hover{--bg-opacity:1;background-color:#f4f5f7;background-color:rgba(244,245,247,var(--bg-opacity))}.hover\:bg-purple-700:hover{--bg-opacity:1;background-color:#6c2bd9;background-color:rgba(108,43,217,var(--bg-opacity))}.focus\:bg-white:focus{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.active\:bg-transparent:active{background-color:transparent}.active\:bg-purple-600:active{--bg-opacity:1;background-color:#7e3af2;background-color:rgba(126,58,242,var(--bg-opacity))}.theme-dark .dark\:bg-gray-700{--bg-opacity:1;background-color:#24262d;background-color:rgba(36,38,45,var(--bg-opacity))}.theme-dark .dark\:bg-gray-800{--bg-opacity:1;background-color:#1a1c23;background-color:rgba(26,28,35,var(--bg-opacity))}.theme-dark .dark\:bg-gray-900{--bg-opacity:1;background-color:#121317;background-color:rgba(18,19,23,var(--bg-opacity))}.theme-dark .dark\:bg-red-600{--bg-opacity:1;background-color:#e02424;background-color:rgba(224,36,36,var(--bg-opacity))}.theme-dark .dark\:bg-red-700{--bg-opacity:1;background-color:#c81e1e;background-color:rgba(200,30,30,var(--bg-opacity))}.theme-dark .dark\:bg-orange-500{--bg-opacity:1;background-color:#ff5a1f;background-color:rgba(255,90,31,var(--bg-opacity))}.theme-dark .dark\:bg-orange-600{--bg-opacity:1;background-color:#d03801;background-color:rgba(208,56,1,var(--bg-opacity))}.theme-dark .dark\:bg-green-500{--bg-opacity:1;background-color:#0e9f6e;background-color:rgba(14,159,110,var(--bg-opacity))}.theme-dark .dark\:bg-green-700{--bg-opacity:1;background-color:#046c4e;background-color:rgba(4,108,78,var(--bg-opacity))}.theme-dark .dark\:bg-teal-500{--bg-opacity:1;background-color:#0694a2;background-color:rgba(6,148,162,var(--bg-opacity))}.theme-dark .dark\:bg-blue-500{--bg-opacity:1;background-color:#3f83f8;background-color:rgba(63,131,248,var(--bg-opacity))}.theme-dark .dark\:hover\:bg-gray-800:hover{--bg-opacity:1;background-color:#1a1c23;background-color:rgba(26,28,35,var(--bg-opacity))}.bg-opacity-50{--bg-opacity:0.5}.border-transparent{border-color:transparent}.border-white{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.border-gray-100{--border-opacity:1;border-color:#f4f5f7;border-color:rgba(244,245,247,var(--border-opacity))}.border-gray-300{--border-opacity:1;border-color:#d5d6d7;border-color:rgba(213,214,215,var(--border-opacity))}.border-red-600{--border-opacity:1;border-color:#e02424;border-color:rgba(224,36,36,var(--border-opacity))}.border-green-600{--border-opacity:1;border-color:#057a55;border-color:rgba(5,122,85,var(--border-opacity))}.border-purple-600{--border-opacity:1;border-color:#7e3af2;border-color:rgba(126,58,242,var(--border-opacity))}.focus\:border-gray-500:focus{--border-opacity:1;border-color:#707275;border-color:rgba(112,114,117,var(--border-opacity))}.focus\:border-red-400:focus{--border-opacity:1;border-color:#f98080;border-color:rgba(249,128,128,var(--border-opacity))}.focus\:border-green-400:focus{--border-opacity:1;border-color:#31c48d;border-color:rgba(49,196,141,var(--border-opacity))}.focus\:border-purple-300:focus{--border-opacity:1;border-color:#cabffd;border-color:rgba(202,191,253,var(--border-opacity))}.focus\:border-purple-400:focus{--border-opacity:1;border-color:#ac94fa;border-color:rgba(172,148,250,var(--border-opacity))}.hover\:border-gray-500:hover{--border-opacity:1;border-color:#707275;border-color:rgba(112,114,117,var(--border-opacity))}.theme-dark .dark\:border-gray-600{--border-opacity:1;border-color:#4c4f52;border-color:rgba(76,79,82,var(--border-opacity))}.theme-dark .dark\:border-gray-700{--border-opacity:1;border-color:#24262d;border-color:rgba(36,38,45,var(--border-opacity))}.theme-dark .dark\:border-gray-800{--border-opacity:1;border-color:#1a1c23;border-color:rgba(26,28,35,var(--border-opacity))}.rounded{border-radius:.25rem}.rounded-md{border-radius:.375rem}.rounded-lg{border-radius:.5rem}.rounded-full{border-radius:9999px}.rounded-r-md{border-top-right-radius:.375rem;border-bottom-right-radius:.375rem}.rounded-l-md{border-top-left-radius:.375rem;border-bottom-left-radius:.375rem}.rounded-t-lg{border-top-left-radius:.5rem}.rounded-r-lg,.rounded-t-lg{border-top-right-radius:.5rem}.rounded-r-lg{border-bottom-right-radius:.5rem}.rounded-l-lg{border-top-left-radius:.5rem;border-bottom-left-radius:.5rem}.rounded-tr-lg{border-top-right-radius:.5rem}.rounded-br-lg{border-bottom-right-radius:.5rem}.border-0{border-width:0}.border-2{border-width:2px}.border{border-width:1px}.border-r-0{border-right-width:0}.border-t{border-top-width:1px}.border-b{border-bottom-width:1px}.cursor-not-allowed{cursor:not-allowed}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.theme-dark .dark\:block{display:block}.theme-dark .dark\:hidden{display:none}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-end{align-items:flex-end}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.font-medium{font-weight:500}.font-semibold{font-weight:600}.font-bold{font-weight:700}.h-3{height:.75rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-8{height:2rem}.h-12{height:3rem}.h-32{height:8rem}.h-full{height:100%}.h-screen{height:100vh}.text-xs{font-size:.75rem}.text-sm{font-size:.875rem}.text-lg{font-size:1.125rem}.text-xl{font-size:1.25rem}.text-2xl{font-size:1.5rem}.text-6xl{font-size:4rem}.leading-5{line-height:1.25rem}.leading-none{line-height:1}.leading-tight{line-height:1.25}.my-6{margin-top:1.5rem;margin-bottom:1.5rem}.my-8{margin-top:2rem;margin-bottom:2rem}.mx-auto{margin-left:auto;margin-right:auto}.-mx-6{margin-left:-1.5rem;margin-right:-1.5rem}.mt-1{margin-top:.25rem}.mr-1{margin-right:.25rem}.mt-2{margin-top:.5rem}.mr-2{margin-right:.5rem}.mb-2{margin-bottom:.5rem}.ml-2{margin-left:.5rem}.mr-3{margin-right:.75rem}.ml-3{margin-left:.75rem}.mt-4{margin-top:1rem}.mr-4{margin-right:1rem}.mb-4{margin-bottom:1rem}.ml-4{margin-left:1rem}.mr-5{margin-right:1.25rem}.mt-6{margin-top:1.5rem}.mr-6{margin-right:1.5rem}.mb-6{margin-bottom:1.5rem}.ml-6{margin-left:1.5rem}.mt-8{margin-top:2rem}.mb-8{margin-bottom:2rem}.mt-16{margin-top:4rem}.-mr-1{margin-right:-.25rem}.-ml-1{margin-left:-.25rem}.-mb-4{margin-bottom:-1rem}.max-h-0{max-height:0}.max-h-xl{max-height:36rem}.max-w-xl{max-width:36rem}.max-w-2xl{max-width:42rem}.max-w-4xl{max-width:56rem}.min-h-screen{min-height:100vh}.min-w-0{min-width:0}.object-cover{-o-object-fit:cover;object-fit:cover}.opacity-0{opacity:0}.opacity-25{opacity:.25}.opacity-50{opacity:.5}.opacity-100{opacity:1}.focus\:outline-none:focus{outline:0}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.px-3{padding-left:.75rem;padding-right:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-10{padding-left:2.5rem;padding-right:2.5rem}.pr-2{padding-right:.5rem}.pl-2{padding-left:.5rem}.pl-8{padding-left:2rem}.pr-10{padding-right:2.5rem}.pl-10{padding-left:2.5rem}.pb-16{padding-bottom:4rem}.pr-20{padding-right:5rem}.pl-20{padding-left:5rem}.placeholder-gray-600::-moz-placeholder{--placeholder-opacity:1;color:#4c4f52;color:rgba(76,79,82,var(--placeholder-opacity))}.placeholder-gray-600:-ms-input-placeholder{--placeholder-opacity:1;color:#4c4f52;color:rgba(76,79,82,var(--placeholder-opacity))}.placeholder-gray-600::-ms-input-placeholder{--placeholder-opacity:1;color:#4c4f52;color:rgba(76,79,82,var(--placeholder-opacity))}.placeholder-gray-600::placeholder{--placeholder-opacity:1;color:#4c4f52;color:rgba(76,79,82,var(--placeholder-opacity))}.focus\:placeholder-gray-500:focus::-moz-placeholder{--placeholder-opacity:1;color:#707275;color:rgba(112,114,117,var(--placeholder-opacity))}.focus\:placeholder-gray-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#707275;color:rgba(112,114,117,var(--placeholder-opacity))}.focus\:placeholder-gray-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#707275;color:rgba(112,114,117,var(--placeholder-opacity))}.focus\:placeholder-gray-500:focus::placeholder{--placeholder-opacity:1;color:#707275;color:rgba(112,114,117,var(--placeholder-opacity))}.theme-dark .dark\:placeholder-gray-500::-moz-placeholder{--placeholder-opacity:1;color:#707275;color:rgba(112,114,117,var(--placeholder-opacity))}.theme-dark .dark\:placeholder-gray-500:-ms-input-placeholder{--placeholder-opacity:1;color:#707275;color:rgba(112,114,117,var(--placeholder-opacity))}.theme-dark .dark\:placeholder-gray-500::-ms-input-placeholder{--placeholder-opacity:1;color:#707275;color:rgba(112,114,117,var(--placeholder-opacity))}.theme-dark .dark\:placeholder-gray-500::placeholder{--placeholder-opacity:1;color:#707275;color:rgba(112,114,117,var(--placeholder-opacity))}.theme-dark .dark\:focus\:placeholder-gray-600:focus::-moz-placeholder{--placeholder-opacity:1;color:#4c4f52;color:rgba(76,79,82,var(--placeholder-opacity))}.theme-dark .dark\:focus\:placeholder-gray-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4c4f52;color:rgba(76,79,82,var(--placeholder-opacity))}.theme-dark .dark\:focus\:placeholder-gray-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4c4f52;color:rgba(76,79,82,var(--placeholder-opacity))}.theme-dark .dark\:focus\:placeholder-gray-600:focus::placeholder{--placeholder-opacity:1;color:#4c4f52;color:rgba(76,79,82,var(--placeholder-opacity))}.pointer-events-none{pointer-events:none}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{right:0;left:0}.inset-0,.inset-y-0{top:0;bottom:0}.top-0{top:0}.right-0{right:0}.left-0{left:0}.shadow-xs{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.shadow{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.shadow-md{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.shadow-xl{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.shadow-inner{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.fill-current{fill:currentColor}.text-left{text-align:left}.text-center{text-align:center}.text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.text-black{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.text-gray-400{--text-opacity:1;color:#9e9e9e;color:rgba(158,158,158,var(--text-opacity))}.text-gray-500{--text-opacity:1;color:#707275;color:rgba(112,114,117,var(--text-opacity))}.text-gray-600{--text-opacity:1;color:#4c4f52;color:rgba(76,79,82,var(--text-opacity))}.text-gray-700{--text-opacity:1;color:#24262d;color:rgba(36,38,45,var(--text-opacity))}.text-gray-800{--text-opacity:1;color:#1a1c23;color:rgba(26,28,35,var(--text-opacity))}.text-red-600{--text-opacity:1;color:#e02424;color:rgba(224,36,36,var(--text-opacity))}.text-red-700{--text-opacity:1;color:#c81e1e;color:rgba(200,30,30,var(--text-opacity))}.text-orange-500{--text-opacity:1;color:#ff5a1f;color:rgba(255,90,31,var(--text-opacity))}.text-orange-700{--text-opacity:1;color:#b43403;color:rgba(180,52,3,var(--text-opacity))}.text-green-500{--text-opacity:1;color:#0e9f6e;color:rgba(14,159,110,var(--text-opacity))}.text-green-600{--text-opacity:1;color:#057a55;color:rgba(5,122,85,var(--text-opacity))}.text-green-700{--text-opacity:1;color:#046c4e;color:rgba(4,108,78,var(--text-opacity))}.text-teal-500{--text-opacity:1;color:#0694a2;color:rgba(6,148,162,var(--text-opacity))}.text-blue-500{--text-opacity:1;color:#3f83f8;color:rgba(63,131,248,var(--text-opacity))}.text-purple-100{--text-opacity:1;color:#edebfe;color:rgba(237,235,254,var(--text-opacity))}.text-purple-200{--text-opacity:1;color:#dcd7fe;color:rgba(220,215,254,var(--text-opacity))}.text-purple-600{--text-opacity:1;color:#7e3af2;color:rgba(126,58,242,var(--text-opacity))}.focus-within\:text-purple-500:focus-within{--text-opacity:1;color:#9061f9;color:rgba(144,97,249,var(--text-opacity))}.focus-within\:text-purple-600:focus-within{--text-opacity:1;color:#7e3af2;color:rgba(126,58,242,var(--text-opacity))}.hover\:text-gray-700:hover{--text-opacity:1;color:#24262d;color:rgba(36,38,45,var(--text-opacity))}.hover\:text-gray-800:hover{--text-opacity:1;color:#1a1c23;color:rgba(26,28,35,var(--text-opacity))}.active\:text-gray-500:active{--text-opacity:1;color:#707275;color:rgba(112,114,117,var(--text-opacity))}.theme-dark .dark\:text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.theme-dark .dark\:text-gray-100{--text-opacity:1;color:#f4f5f7;color:rgba(244,245,247,var(--text-opacity))}.theme-dark .dark\:text-gray-200{--text-opacity:1;color:#e5e7eb;color:rgba(229,231,235,var(--text-opacity))}.theme-dark .dark\:text-gray-300{--text-opacity:1;color:#d5d6d7;color:rgba(213,214,215,var(--text-opacity))}.theme-dark .dark\:text-gray-400{--text-opacity:1;color:#9e9e9e;color:rgba(158,158,158,var(--text-opacity))}.theme-dark .dark\:text-red-100{--text-opacity:1;color:#fde8e8;color:rgba(253,232,232,var(--text-opacity))}.theme-dark .dark\:text-red-400{--text-opacity:1;color:#f98080;color:rgba(249,128,128,var(--text-opacity))}.theme-dark .dark\:text-orange-100{--text-opacity:1;color:#feecdc;color:rgba(254,236,220,var(--text-opacity))}.theme-dark .dark\:text-green-100{--text-opacity:1;color:#def7ec;color:rgba(222,247,236,var(--text-opacity))}.theme-dark .dark\:text-green-400{--text-opacity:1;color:#31c48d;color:rgba(49,196,141,var(--text-opacity))}.theme-dark .dark\:text-teal-100{--text-opacity:1;color:#d5f5f6;color:rgba(213,245,246,var(--text-opacity))}.theme-dark .dark\:text-blue-100{--text-opacity:1;color:#e1effe;color:rgba(225,239,254,var(--text-opacity))}.theme-dark .dark\:text-purple-300{--text-opacity:1;color:#cabffd;color:rgba(202,191,253,var(--text-opacity))}.theme-dark .dark\:text-purple-400{--text-opacity:1;color:#ac94fa;color:rgba(172,148,250,var(--text-opacity))}.theme-dark .dark\:focus-within\:text-purple-400:focus-within{--text-opacity:1;color:#ac94fa;color:rgba(172,148,250,var(--text-opacity))}.theme-dark .dark\:hover\:text-gray-200:hover{--text-opacity:1;color:#e5e7eb;color:rgba(229,231,235,var(--text-opacity))}.uppercase{text-transform:uppercase}.hover\:underline:hover,.underline{text-decoration:underline}.tracking-wide{letter-spacing:.025em}.align-middle{vertical-align:middle}.whitespace-no-wrap{white-space:nowrap}.w-1{width:.25rem}.w-3{width:.75rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-8{width:2rem}.w-12{width:3rem}.w-56{width:14rem}.w-64{width:16rem}.w-full{width:100%}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.gap-6{grid-gap:1.5rem;gap:1.5rem}.col-span-2{grid-column:span 2/span 2}.col-span-3{grid-column:span 3/span 3}.col-span-4{grid-column:span 4/span 4}.transform{--transform-translate-x:0;--transform-translate-y:0;--transform-rotate:0;--transform-skew-x:0;--transform-skew-y:0;--transform-scale-x:1;--transform-scale-y:1;transform:translateX(var(--transform-translate-x)) translateY(var(--transform-translate-y)) rotate(var(--transform-rotate)) skewX(var(--transform-skew-x)) skewY(var(--transform-skew-y)) scaleX(var(--transform-scale-x)) scaleY(var(--transform-scale-y))}.translate-x-1{--transform-translate-x:0.25rem}.-translate-x-20{--transform-translate-x:-5rem}.-translate-y-1{--transform-translate-y:-0.25rem}.translate-y-1\/2{--transform-translate-y:50%}.transition-all{transition-property:all}.transition{transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform}.transition-colors{transition-property:background-color,border-color,color,fill,stroke}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-150{transition-duration:.15s}.duration-300{transition-duration:.3s}.focus\:shadow-outline-gray:focus{box-shadow:0 0 0 3px rgba(213,214,215,.45)}.focus\:shadow-outline-red:focus{box-shadow:0 0 0 3px rgba(248,180,180,.45)}.focus\:shadow-outline-green:focus{box-shadow:0 0 0 3px rgba(132,225,188,.45)}.focus\:shadow-outline-purple:focus{box-shadow:0 0 0 3px rgba(202,191,253,.45)}.theme-dark .dark\:focus\:shadow-outline-gray:focus{box-shadow:0 0 0 3px rgba(213,214,215,.45)}@media (min-width:640px){.sm\:space-y-0>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(0px*(1 - var(--space-y-reverse)));margin-bottom:calc(0px*var(--space-y-reverse))}.sm\:space-x-6>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1.5rem*var(--space-x-reverse));margin-left:calc(1.5rem*(1 - var(--space-x-reverse)))}.sm\:rounded-lg{border-radius:.5rem}.sm\:flex-row{flex-direction:row}.sm\:items-center{align-items:center}.sm\:justify-end{justify-content:flex-end}.sm\:justify-center{justify-content:center}.sm\:m-4{margin:1rem}.sm\:mt-auto{margin-top:auto}.sm\:max-w-xl{max-width:36rem}.sm\:p-12{padding:3rem}.sm\:py-2{padding-top:.5rem;padding-bottom:.5rem}.sm\:px-4{padding-left:1rem;padding-right:1rem}.sm\:w-auto{width:auto}.sm\:grid-cols-9{grid-template-columns:repeat(9,minmax(0,1fr))}}@media (min-width:768px){.md\:space-x-4>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1rem*var(--space-x-reverse));margin-left:calc(1rem*(1 - var(--space-x-reverse)))}.md\:block{display:block}.md\:hidden{display:none}.md\:flex-row{flex-direction:row}.md\:items-end{align-items:flex-end}.md\:h-auto{height:auto}.md\:w-1\/2{width:50%}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:1024px){.lg\:mr-32{margin-right:8rem}}@media (min-width:1280px){.xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}} -------------------------------------------------------------------------------- /public/assets/img/create-account-office-dark.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/estevanmaito/windmill-dashboard/e05267588134ca2f4129087cc65a59c38a9c36b5/public/assets/img/create-account-office-dark.jpeg -------------------------------------------------------------------------------- /public/assets/img/create-account-office.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/estevanmaito/windmill-dashboard/e05267588134ca2f4129087cc65a59c38a9c36b5/public/assets/img/create-account-office.jpeg -------------------------------------------------------------------------------- /public/assets/img/dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/estevanmaito/windmill-dashboard/e05267588134ca2f4129087cc65a59c38a9c36b5/public/assets/img/dashboard.png -------------------------------------------------------------------------------- /public/assets/img/forgot-password-office-dark.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/estevanmaito/windmill-dashboard/e05267588134ca2f4129087cc65a59c38a9c36b5/public/assets/img/forgot-password-office-dark.jpeg -------------------------------------------------------------------------------- /public/assets/img/forgot-password-office.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/estevanmaito/windmill-dashboard/e05267588134ca2f4129087cc65a59c38a9c36b5/public/assets/img/forgot-password-office.jpeg -------------------------------------------------------------------------------- /public/assets/img/github.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/assets/img/login-office-dark.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/estevanmaito/windmill-dashboard/e05267588134ca2f4129087cc65a59c38a9c36b5/public/assets/img/login-office-dark.jpeg -------------------------------------------------------------------------------- /public/assets/img/login-office.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/estevanmaito/windmill-dashboard/e05267588134ca2f4129087cc65a59c38a9c36b5/public/assets/img/login-office.jpeg -------------------------------------------------------------------------------- /public/assets/img/twitter.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/assets/js/charts-bars.js: -------------------------------------------------------------------------------- 1 | /** 2 | * For usage, visit Chart.js docs https://www.chartjs.org/docs/latest/ 3 | */ 4 | const barConfig = { 5 | type: 'bar', 6 | data: { 7 | labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], 8 | datasets: [ 9 | { 10 | label: 'Shoes', 11 | backgroundColor: '#0694a2', 12 | // borderColor: window.chartColors.red, 13 | borderWidth: 1, 14 | data: [-3, 14, 52, 74, 33, 90, 70], 15 | }, 16 | { 17 | label: 'Bags', 18 | backgroundColor: '#7e3af2', 19 | // borderColor: window.chartColors.blue, 20 | borderWidth: 1, 21 | data: [66, 33, 43, 12, 54, 62, 84], 22 | }, 23 | ], 24 | }, 25 | options: { 26 | responsive: true, 27 | legend: { 28 | display: false, 29 | }, 30 | }, 31 | } 32 | 33 | const barsCtx = document.getElementById('bars') 34 | window.myBar = new Chart(barsCtx, barConfig) 35 | -------------------------------------------------------------------------------- /public/assets/js/charts-lines.js: -------------------------------------------------------------------------------- 1 | /** 2 | * For usage, visit Chart.js docs https://www.chartjs.org/docs/latest/ 3 | */ 4 | const lineConfig = { 5 | type: 'line', 6 | data: { 7 | labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], 8 | datasets: [ 9 | { 10 | label: 'Organic', 11 | /** 12 | * These colors come from Tailwind CSS palette 13 | * https://tailwindcss.com/docs/customizing-colors/#default-color-palette 14 | */ 15 | backgroundColor: '#0694a2', 16 | borderColor: '#0694a2', 17 | data: [43, 48, 40, 54, 67, 73, 70], 18 | fill: false, 19 | }, 20 | { 21 | label: 'Paid', 22 | fill: false, 23 | /** 24 | * These colors come from Tailwind CSS palette 25 | * https://tailwindcss.com/docs/customizing-colors/#default-color-palette 26 | */ 27 | backgroundColor: '#7e3af2', 28 | borderColor: '#7e3af2', 29 | data: [24, 50, 64, 74, 52, 51, 65], 30 | }, 31 | ], 32 | }, 33 | options: { 34 | responsive: true, 35 | /** 36 | * Default legends are ugly and impossible to style. 37 | * See examples in charts.html to add your own legends 38 | * */ 39 | legend: { 40 | display: false, 41 | }, 42 | tooltips: { 43 | mode: 'index', 44 | intersect: false, 45 | }, 46 | hover: { 47 | mode: 'nearest', 48 | intersect: true, 49 | }, 50 | scales: { 51 | x: { 52 | display: true, 53 | scaleLabel: { 54 | display: true, 55 | labelString: 'Month', 56 | }, 57 | }, 58 | y: { 59 | display: true, 60 | scaleLabel: { 61 | display: true, 62 | labelString: 'Value', 63 | }, 64 | }, 65 | }, 66 | }, 67 | } 68 | 69 | // change this to the id of your chart element in HMTL 70 | const lineCtx = document.getElementById('line') 71 | window.myLine = new Chart(lineCtx, lineConfig) 72 | -------------------------------------------------------------------------------- /public/assets/js/charts-pie.js: -------------------------------------------------------------------------------- 1 | /** 2 | * For usage, visit Chart.js docs https://www.chartjs.org/docs/latest/ 3 | */ 4 | const pieConfig = { 5 | type: 'doughnut', 6 | data: { 7 | datasets: [ 8 | { 9 | data: [33, 33, 33], 10 | /** 11 | * These colors come from Tailwind CSS palette 12 | * https://tailwindcss.com/docs/customizing-colors/#default-color-palette 13 | */ 14 | backgroundColor: ['#0694a2', '#1c64f2', '#7e3af2'], 15 | label: 'Dataset 1', 16 | }, 17 | ], 18 | labels: ['Shoes', 'Shirts', 'Bags'], 19 | }, 20 | options: { 21 | responsive: true, 22 | cutoutPercentage: 80, 23 | /** 24 | * Default legends are ugly and impossible to style. 25 | * See examples in charts.html to add your own legends 26 | * */ 27 | legend: { 28 | display: false, 29 | }, 30 | }, 31 | } 32 | 33 | // change this to the id of your chart element in HMTL 34 | const pieCtx = document.getElementById('pie') 35 | window.myPie = new Chart(pieCtx, pieConfig) 36 | -------------------------------------------------------------------------------- /public/assets/js/focus-trap.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Limit focus to focusable elements inside `element` 3 | * @param {HTMLElement} element - DOM element to focus trap inside 4 | * @return {Function} cleanup function 5 | */ 6 | function focusTrap(element) { 7 | const focusableElements = getFocusableElements(element) 8 | const firstFocusableEl = focusableElements[0] 9 | const lastFocusableEl = focusableElements[focusableElements.length - 1] 10 | 11 | // Wait for the case the element was not yet rendered 12 | setTimeout(() => firstFocusableEl.focus(), 50) 13 | 14 | /** 15 | * Get all focusable elements inside `element` 16 | * @param {HTMLElement} element - DOM element to focus trap inside 17 | * @return {HTMLElement[]} List of focusable elements 18 | */ 19 | function getFocusableElements(element = document) { 20 | return [ 21 | ...element.querySelectorAll( 22 | 'a, button, details, input, select, textarea, [tabindex]:not([tabindex="-1"])' 23 | ), 24 | ].filter((e) => !e.hasAttribute('disabled')) 25 | } 26 | 27 | function handleKeyDown(e) { 28 | const TAB = 9 29 | const isTab = e.key.toLowerCase() === 'tab' || e.keyCode === TAB 30 | 31 | if (!isTab) return 32 | 33 | if (e.shiftKey) { 34 | if (document.activeElement === firstFocusableEl) { 35 | lastFocusableEl.focus() 36 | e.preventDefault() 37 | } 38 | } else { 39 | if (document.activeElement === lastFocusableEl) { 40 | firstFocusableEl.focus() 41 | e.preventDefault() 42 | } 43 | } 44 | } 45 | 46 | element.addEventListener('keydown', handleKeyDown) 47 | 48 | return function cleanup() { 49 | element.removeEventListener('keydown', handleKeyDown) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /public/assets/js/init-alpine.js: -------------------------------------------------------------------------------- 1 | function data() { 2 | function getThemeFromLocalStorage() { 3 | // if user already changed the theme, use it 4 | if (window.localStorage.getItem('dark')) { 5 | return JSON.parse(window.localStorage.getItem('dark')) 6 | } 7 | 8 | // else return their preferences 9 | return ( 10 | !!window.matchMedia && 11 | window.matchMedia('(prefers-color-scheme: dark)').matches 12 | ) 13 | } 14 | 15 | function setThemeToLocalStorage(value) { 16 | window.localStorage.setItem('dark', value) 17 | } 18 | 19 | return { 20 | dark: getThemeFromLocalStorage(), 21 | toggleTheme() { 22 | this.dark = !this.dark 23 | setThemeToLocalStorage(this.dark) 24 | }, 25 | isSideMenuOpen: false, 26 | toggleSideMenu() { 27 | this.isSideMenuOpen = !this.isSideMenuOpen 28 | }, 29 | closeSideMenu() { 30 | this.isSideMenuOpen = false 31 | }, 32 | isNotificationsMenuOpen: false, 33 | toggleNotificationsMenu() { 34 | this.isNotificationsMenuOpen = !this.isNotificationsMenuOpen 35 | }, 36 | closeNotificationsMenu() { 37 | this.isNotificationsMenuOpen = false 38 | }, 39 | isProfileMenuOpen: false, 40 | toggleProfileMenu() { 41 | this.isProfileMenuOpen = !this.isProfileMenuOpen 42 | }, 43 | closeProfileMenu() { 44 | this.isProfileMenuOpen = false 45 | }, 46 | isPagesMenuOpen: false, 47 | togglePagesMenu() { 48 | this.isPagesMenuOpen = !this.isPagesMenuOpen 49 | }, 50 | // Modal 51 | isModalOpen: false, 52 | trapCleanup: null, 53 | openModal() { 54 | this.isModalOpen = true 55 | this.trapCleanup = focusTrap(document.querySelector('#modal')) 56 | }, 57 | closeModal() { 58 | this.isModalOpen = false 59 | this.trapCleanup() 60 | }, 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /public/charts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Charts - Windmill Dashboard 7 | 11 | 12 | 16 | 17 | 21 | 25 | 26 | 27 | 28 | 29 | 30 |
34 | 35 | 295 | 296 | 297 |
307 | 576 |
577 |
578 |
581 | 582 | 600 | 601 |
602 |
605 |
606 | 618 |
619 | 625 |
626 |
627 |
    628 | 629 |
  • 630 | 662 |
  • 663 | 664 |
  • 665 | 688 | 734 |
  • 735 | 736 |
  • 737 | 751 | 830 |
  • 831 |
832 |
833 |
834 |
835 |
836 |

839 | Charts 840 |

841 | 842 | 846 |
847 | 852 | 855 | 856 | Star this project on GitHub 857 |
858 | View more → 859 |
860 | 861 |

862 | Charts are provided by 863 | 867 | Chart.js 868 | 869 | . Note that the default legends are disabled and you should 870 | provide a description for your charts in HTML. See source code for 871 | examples. 872 |

873 | 874 |
875 | 876 |
879 |

880 | Doughnut/Pie 881 |

882 | 883 |
886 | 887 |
888 | 891 | Shirts 892 |
893 |
894 | 897 | Shoes 898 |
899 |
900 | 903 | Bags 904 |
905 |
906 |
907 | 908 |
911 |

912 | Lines 913 |

914 | 915 |
918 | 919 |
920 | 923 | Organic 924 |
925 |
926 | 929 | Paid 930 |
931 |
932 |
933 | 934 |
937 |

938 | Bars 939 |

940 | 941 |
944 | 945 |
946 | 949 | Shoes 950 |
951 |
952 | 955 | Bags 956 |
957 |
958 |
959 |
960 |
961 |
962 |
963 |
964 | 965 | 966 | -------------------------------------------------------------------------------- /public/pages/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 404 - Windmill Dashboard 7 | 11 | 12 | 16 | 17 | 18 | 19 |
23 | 24 | 288 | 289 | 290 |
300 | 573 |
574 |
575 |
578 | 579 | 597 | 598 |
599 |
602 |
603 | 615 |
616 | 622 |
623 |
624 |
    625 | 626 |
  • 627 | 659 |
  • 660 | 661 |
  • 662 | 685 | 731 |
  • 732 | 733 |
  • 734 | 748 | 827 |
  • 828 |
829 |
830 |
831 |
832 |
833 | 838 | 843 | 844 |

845 | 404 846 |

847 |

848 | Page not found. Check the address or 849 | 853 | go back 854 | 855 | . 856 |

857 |
858 |
859 |
860 |
861 | 862 | 863 | -------------------------------------------------------------------------------- /public/pages/blank.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Blank - Windmill Dashboard 7 | 11 | 12 | 16 | 17 | 18 | 19 |
23 | 24 | 288 | 289 | 290 |
300 | 573 |
574 |
575 |
578 | 579 | 597 | 598 |
599 |
602 |
603 | 615 |
616 | 622 |
623 |
624 |
    625 | 626 |
  • 627 | 659 |
  • 660 | 661 |
  • 662 | 685 | 731 |
  • 732 | 733 |
  • 734 | 748 | 827 |
  • 828 |
829 |
830 |
831 |
832 | 833 |
834 |

837 | Blank 838 |

839 |
840 |
841 |
842 |
843 | 844 | 845 | -------------------------------------------------------------------------------- /public/pages/create-account.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Create account - Windmill Dashboard 7 | 11 | 12 | 16 | 17 | 18 | 19 |
20 |
23 |
24 |
25 | 31 | 37 |
38 |
39 |
40 |

43 | Create account 44 |

45 | 52 | 60 | 70 | 71 |
72 | 82 |
83 | 84 | 85 | 89 | Create account 90 | 91 | 92 |
93 | 94 | 109 | 124 | 125 |

126 | 130 | Already have an account? Login 131 | 132 |

133 |
134 |
135 |
136 |
137 |
138 | 139 | 140 | -------------------------------------------------------------------------------- /public/pages/forgot-password.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Forgot password - Windmill Dashboard 7 | 11 | 12 | 16 | 17 | 18 | 19 |
20 |
23 |
24 |
25 | 31 | 37 |
38 |
39 |
40 |

43 | Forgot password 44 |

45 | 52 | 53 | 54 | 58 | Recover password 59 | 60 |
61 |
62 |
63 |
64 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /public/pages/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Login - Windmill Dashboard 7 | 11 | 12 | 16 | 17 | 18 | 19 |
20 |
23 |
24 |
25 | 31 | 37 |
38 |
39 |
40 |

43 | Login 44 |

45 | 52 | 60 | 61 | 62 | 66 | Log in 67 | 68 | 69 |
70 | 71 | 86 | 101 | 102 |

103 | 107 | Forgot your password? 108 | 109 |

110 |

111 | 115 | Create account 116 | 117 |

118 |
119 |
120 |
121 |
122 |
123 | 124 | 125 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | const defaultTheme = require('tailwindcss/defaultTheme') 2 | const plugin = require('tailwindcss/plugin') 3 | const Color = require('color') 4 | 5 | module.exports = { 6 | purge: ['public/**/*.html'], 7 | theme: { 8 | themeVariants: ['dark'], 9 | customForms: (theme) => ({ 10 | default: { 11 | 'input, textarea': { 12 | '&::placeholder': { 13 | color: theme('colors.gray.400'), 14 | }, 15 | }, 16 | }, 17 | }), 18 | colors: { 19 | transparent: 'transparent', 20 | white: '#ffffff', 21 | black: '#000000', 22 | gray: { 23 | '50': '#f9fafb', 24 | '100': '#f4f5f7', 25 | '200': '#e5e7eb', 26 | '300': '#d5d6d7', 27 | '400': '#9e9e9e', 28 | '500': '#707275', 29 | '600': '#4c4f52', 30 | '700': '#24262d', 31 | '800': '#1a1c23', 32 | '900': '#121317', 33 | // default values from Tailwind UI palette 34 | // '300': '#d2d6dc', 35 | // '400': '#9fa6b2', 36 | // '500': '#6b7280', 37 | // '600': '#4b5563', 38 | // '700': '#374151', 39 | // '800': '#252f3f', 40 | // '900': '#161e2e', 41 | }, 42 | 'cool-gray': { 43 | '50': '#fbfdfe', 44 | '100': '#f1f5f9', 45 | '200': '#e2e8f0', 46 | '300': '#cfd8e3', 47 | '400': '#97a6ba', 48 | '500': '#64748b', 49 | '600': '#475569', 50 | '700': '#364152', 51 | '800': '#27303f', 52 | '900': '#1a202e', 53 | }, 54 | red: { 55 | '50': '#fdf2f2', 56 | '100': '#fde8e8', 57 | '200': '#fbd5d5', 58 | '300': '#f8b4b4', 59 | '400': '#f98080', 60 | '500': '#f05252', 61 | '600': '#e02424', 62 | '700': '#c81e1e', 63 | '800': '#9b1c1c', 64 | '900': '#771d1d', 65 | }, 66 | orange: { 67 | '50': '#fff8f1', 68 | '100': '#feecdc', 69 | '200': '#fcd9bd', 70 | '300': '#fdba8c', 71 | '400': '#ff8a4c', 72 | '500': '#ff5a1f', 73 | '600': '#d03801', 74 | '700': '#b43403', 75 | '800': '#8a2c0d', 76 | '900': '#771d1d', 77 | }, 78 | yellow: { 79 | '50': '#fdfdea', 80 | '100': '#fdf6b2', 81 | '200': '#fce96a', 82 | '300': '#faca15', 83 | '400': '#e3a008', 84 | '500': '#c27803', 85 | '600': '#9f580a', 86 | '700': '#8e4b10', 87 | '800': '#723b13', 88 | '900': '#633112', 89 | }, 90 | green: { 91 | '50': '#f3faf7', 92 | '100': '#def7ec', 93 | '200': '#bcf0da', 94 | '300': '#84e1bc', 95 | '400': '#31c48d', 96 | '500': '#0e9f6e', 97 | '600': '#057a55', 98 | '700': '#046c4e', 99 | '800': '#03543f', 100 | '900': '#014737', 101 | }, 102 | teal: { 103 | '50': '#edfafa', 104 | '100': '#d5f5f6', 105 | '200': '#afecef', 106 | '300': '#7edce2', 107 | '400': '#16bdca', 108 | '500': '#0694a2', 109 | '600': '#047481', 110 | '700': '#036672', 111 | '800': '#05505c', 112 | '900': '#014451', 113 | }, 114 | blue: { 115 | '50': '#ebf5ff', 116 | '100': '#e1effe', 117 | '200': '#c3ddfd', 118 | '300': '#a4cafe', 119 | '400': '#76a9fa', 120 | '500': '#3f83f8', 121 | '600': '#1c64f2', 122 | '700': '#1a56db', 123 | '800': '#1e429f', 124 | '900': '#233876', 125 | }, 126 | indigo: { 127 | '50': '#f0f5ff', 128 | '100': '#e5edff', 129 | '200': '#cddbfe', 130 | '300': '#b4c6fc', 131 | '400': '#8da2fb', 132 | '500': '#6875f5', 133 | '600': '#5850ec', 134 | '700': '#5145cd', 135 | '800': '#42389d', 136 | '900': '#362f78', 137 | }, 138 | purple: { 139 | '50': '#f6f5ff', 140 | '100': '#edebfe', 141 | '200': '#dcd7fe', 142 | '300': '#cabffd', 143 | '400': '#ac94fa', 144 | '500': '#9061f9', 145 | '600': '#7e3af2', 146 | '700': '#6c2bd9', 147 | '800': '#5521b5', 148 | '900': '#4a1d96', 149 | }, 150 | pink: { 151 | '50': '#fdf2f8', 152 | '100': '#fce8f3', 153 | '200': '#fad1e8', 154 | '300': '#f8b4d9', 155 | '400': '#f17eb8', 156 | '500': '#e74694', 157 | '600': '#d61f69', 158 | '700': '#bf125d', 159 | '800': '#99154b', 160 | '900': '#751a3d', 161 | }, 162 | }, 163 | extend: { 164 | maxHeight: { 165 | '0': '0', 166 | xl: '36rem', 167 | }, 168 | fontFamily: { 169 | sans: ['Inter', ...defaultTheme.fontFamily.sans], 170 | }, 171 | }, 172 | }, 173 | variants: { 174 | backgroundColor: [ 175 | 'hover', 176 | 'focus', 177 | 'active', 178 | 'odd', 179 | 'dark', 180 | 'dark:hover', 181 | 'dark:focus', 182 | 'dark:active', 183 | 'dark:odd', 184 | ], 185 | display: ['responsive', 'dark'], 186 | textColor: [ 187 | 'focus-within', 188 | 'hover', 189 | 'active', 190 | 'dark', 191 | 'dark:focus-within', 192 | 'dark:hover', 193 | 'dark:active', 194 | ], 195 | placeholderColor: ['focus', 'dark', 'dark:focus'], 196 | borderColor: ['focus', 'hover', 'dark', 'dark:focus', 'dark:hover'], 197 | divideColor: ['dark'], 198 | boxShadow: ['focus', 'dark:focus'], 199 | }, 200 | plugins: [ 201 | require('tailwindcss-multi-theme'), 202 | require('@tailwindcss/custom-forms'), 203 | plugin(({ addUtilities, e, theme, variants }) => { 204 | const newUtilities = {} 205 | Object.entries(theme('colors')).map(([name, value]) => { 206 | if (name === 'transparent' || name === 'current') return 207 | const color = value[300] ? value[300] : value 208 | const hsla = Color(color).alpha(0.45).hsl().string() 209 | 210 | newUtilities[`.shadow-outline-${name}`] = { 211 | 'box-shadow': `0 0 0 3px ${hsla}`, 212 | } 213 | }) 214 | 215 | addUtilities(newUtilities, variants('boxShadow')) 216 | }), 217 | ], 218 | } 219 | --------------------------------------------------------------------------------