├── backend ├── __init__.py ├── api │ ├── __init__.py │ ├── migrations │ │ ├── __init__.py │ │ └── 0001_initial.py │ ├── tests.py │ ├── admin.py │ ├── apps.py │ ├── models.py │ ├── urls.py │ └── views.py ├── settings │ ├── __init__.py │ └── prod.py ├── users │ ├── __init__.py │ ├── migrations │ │ ├── __init__.py │ │ ├── 0001_initial.py │ │ └── 0002_auto_20190314_2351.py │ ├── tests.py │ ├── views.py │ ├── apps.py │ ├── admin.py │ ├── serializers.py │ └── models.py ├── requirements.txt ├── wsgi.py └── urls.py ├── public ├── robots.txt ├── favicon.png ├── img │ ├── bg5.jpg │ ├── mike.jpg │ ├── anime3.png │ ├── anime6.png │ ├── emilyz.jpg │ ├── james.jpg │ ├── favicon.png │ ├── img_3115.jpg │ ├── apple-icon.png │ ├── default-avatar.png │ └── icons │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── mstile-150x150.png │ │ ├── apple-touch-icon.png │ │ ├── android-chrome-192x192.png │ │ ├── android-chrome-512x512.png │ │ ├── apple-touch-icon-60x60.png │ │ ├── apple-touch-icon-76x76.png │ │ ├── apple-touch-icon-120x120.png │ │ ├── apple-touch-icon-152x152.png │ │ ├── apple-touch-icon-180x180.png │ │ └── msapplication-icon-144x144.png ├── apple-icon.png ├── manifest.json └── index.html ├── .babelrc ├── Procfile ├── src ├── assets │ ├── sass │ │ └── black-dashboard │ │ │ ├── custom │ │ │ ├── cards │ │ │ │ ├── _card-map.scss │ │ │ │ ├── _card-plain.scss │ │ │ │ ├── _card-task.scss │ │ │ │ ├── _card-chart.scss │ │ │ │ └── _card-user.scss │ │ │ ├── utilities │ │ │ │ ├── _sizing.scss │ │ │ │ ├── _transform.scss │ │ │ │ ├── _position.scss │ │ │ │ ├── _shadows.scss │ │ │ │ ├── _backgrounds.scss │ │ │ │ ├── _floating.scss │ │ │ │ ├── _helper.scss │ │ │ │ ├── _text.scss │ │ │ │ └── _spacing.scss │ │ │ ├── _images.scss │ │ │ ├── mixins │ │ │ │ ├── _icon.scss │ │ │ │ ├── opacity.scss │ │ │ │ ├── _badges.scss │ │ │ │ ├── _modals.scss │ │ │ │ ├── _alert.scss │ │ │ │ ├── _page-header.scss │ │ │ │ ├── _background-variant.scss │ │ │ │ ├── _dropdown.scss │ │ │ │ ├── _wizard.scss │ │ │ │ ├── _popovers.scss │ │ │ │ └── _forms.scss │ │ │ ├── _utilities.scss │ │ │ ├── _mixins.scss │ │ │ ├── _functions.scss │ │ │ ├── _footer.scss │ │ │ ├── _alerts.scss │ │ │ ├── vendor │ │ │ │ └── _plugin-perfect-scrollbar.scss │ │ │ ├── _forms.scss │ │ │ └── _modal.scss │ │ │ ├── bootstrap │ │ │ ├── utilities │ │ │ │ ├── _clearfix.scss │ │ │ │ ├── _screenreaders.scss │ │ │ │ ├── _visibility.scss │ │ │ │ ├── _shadows.scss │ │ │ │ ├── _sizing.scss │ │ │ │ ├── _float.scss │ │ │ │ ├── _align.scss │ │ │ │ ├── _background.scss │ │ │ │ ├── _position.scss │ │ │ │ ├── _embed.scss │ │ │ │ ├── _display.scss │ │ │ │ ├── _spacing.scss │ │ │ │ ├── _borders.scss │ │ │ │ ├── _text.scss │ │ │ │ └── _flex.scss │ │ │ ├── _media.scss │ │ │ ├── mixins │ │ │ │ ├── _box-shadow.scss │ │ │ │ ├── _size.scss │ │ │ │ ├── _clearfix.scss │ │ │ │ ├── _visibility.scss │ │ │ │ ├── _lists.scss │ │ │ │ ├── _text-truncate.scss │ │ │ │ ├── _resize.scss │ │ │ │ ├── _float.scss │ │ │ │ ├── _badge.scss │ │ │ │ ├── _alert.scss │ │ │ │ ├── _nav-divider.scss │ │ │ │ ├── _text-emphasis.scss │ │ │ │ ├── _transition.scss │ │ │ │ ├── _text-hide.scss │ │ │ │ ├── _list-group.scss │ │ │ │ ├── _pagination.scss │ │ │ │ ├── _background-variant.scss │ │ │ │ ├── _reset-text.scss │ │ │ │ ├── _table-row.scss │ │ │ │ ├── _border-radius.scss │ │ │ │ ├── _screen-reader.scss │ │ │ │ ├── _hover.scss │ │ │ │ ├── _image.scss │ │ │ │ ├── _caret.scss │ │ │ │ ├── _grid.scss │ │ │ │ ├── _grid-framework.scss │ │ │ │ └── _gradients.scss │ │ │ ├── _transitions.scss │ │ │ ├── _jumbotron.scss │ │ │ ├── _utilities.scss │ │ │ ├── _root.scss │ │ │ ├── _progress.scss │ │ │ ├── _close.scss │ │ │ ├── _mixins.scss │ │ │ ├── _code.scss │ │ │ ├── _badge.scss │ │ │ ├── _grid.scss │ │ │ ├── _images.scss │ │ │ ├── _alert.scss │ │ │ ├── _breadcrumb.scss │ │ │ ├── _pagination.scss │ │ │ ├── _nav.scss │ │ │ ├── _type.scss │ │ │ ├── _functions.scss │ │ │ ├── _tooltip.scss │ │ │ ├── _buttons.scss │ │ │ └── _list-group.scss │ │ │ └── plugins │ │ │ └── _plugin-perfect-scrollbar.scss │ ├── fonts │ │ ├── nucleo.eot │ │ ├── nucleo.ttf │ │ ├── nucleo.woff │ │ └── nucleo.woff2 │ └── demo │ │ └── demo.css ├── layout │ ├── dashboard │ │ ├── MobileMenu.vue │ │ ├── Content.vue │ │ ├── ContentFooter.vue │ │ └── DashboardLayout.vue │ └── starter │ │ ├── MobileMenu.vue │ │ ├── SamplePage.vue │ │ ├── Content.vue │ │ ├── SampleLayout.vue │ │ └── SampleFooter.vue ├── pages │ ├── Notifications │ │ └── NotificationTemplate.vue │ ├── Dashboard │ │ ├── UserTable.vue │ │ └── TaskList.vue │ ├── Profile │ │ ├── UserCard.vue │ │ └── EditProfileForm.vue │ ├── Profile.vue │ ├── NotFoundPage.vue │ └── TableList.vue ├── config.js ├── store │ ├── index.js │ └── user.js ├── components │ ├── Charts │ │ ├── utils.js │ │ ├── BarChart.js │ │ └── LineChart.js │ ├── SidebarPlugin │ │ ├── index.js │ │ └── SidebarLink.vue │ ├── Cards │ │ ├── StatsCard.vue │ │ └── Card.vue │ ├── NavbarToggleButton.vue │ ├── index.js │ ├── CloseButton.vue │ ├── BaseRadio.vue │ ├── BaseAlert.vue │ ├── BaseCheckbox.vue │ ├── BaseButton.vue │ ├── BaseTable.vue │ ├── NotificationPlugin │ │ ├── Notifications.vue │ │ └── index.js │ ├── BaseDropdown.vue │ ├── Inputs │ │ └── BaseInput.vue │ └── BaseNav.vue ├── service │ └── local-storage-service.js ├── plugins │ ├── globalDirectives.js │ ├── globalComponents.js │ ├── blackDashboard.js │ └── RTLPlugin.js ├── router │ └── index.js ├── helpers │ ├── utils.js │ └── interceptors.js ├── directives │ └── click-ouside.js ├── i18n.js ├── App.vue ├── main.js ├── registerServiceWorker.js └── constants │ └── index.js ├── docker ├── frontend_setup.sh ├── BackendDockerfile ├── backend_setup.sh └── FrontendDockerfile ├── .gitignore ├── TODO ├── manage.py ├── app.json ├── docker-compose.yml ├── LICENSE ├── package.json └── vue.config.js /backend/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/api/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/settings/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/users/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/api/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/users/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["@babel/plugin-syntax-dynamic-import"] 3 | } 4 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | release: python manage.py migrate 2 | web: gunicorn backend.wsgi --log-file - 3 | -------------------------------------------------------------------------------- /backend/api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /backend/api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /backend/users/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /backend/users/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | # Create your views here. 4 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/custom/cards/_card-map.scss: -------------------------------------------------------------------------------- 1 | .map { 2 | height: 500px; 3 | } 4 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/utilities/_clearfix.scss: -------------------------------------------------------------------------------- 1 | .clearfix { 2 | @include clearfix(); 3 | } 4 | -------------------------------------------------------------------------------- /backend/api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class AppConfig(AppConfig): 5 | name = 'api' 6 | -------------------------------------------------------------------------------- /public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/public/favicon.png -------------------------------------------------------------------------------- /public/img/bg5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/public/img/bg5.jpg -------------------------------------------------------------------------------- /public/img/mike.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/public/img/mike.jpg -------------------------------------------------------------------------------- /backend/users/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class UsersConfig(AppConfig): 5 | name = 'users' 6 | -------------------------------------------------------------------------------- /public/apple-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/public/apple-icon.png -------------------------------------------------------------------------------- /public/img/anime3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/public/img/anime3.png -------------------------------------------------------------------------------- /public/img/anime6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/public/img/anime6.png -------------------------------------------------------------------------------- /public/img/emilyz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/public/img/emilyz.jpg -------------------------------------------------------------------------------- /public/img/james.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/public/img/james.jpg -------------------------------------------------------------------------------- /public/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/public/img/favicon.png -------------------------------------------------------------------------------- /public/img/img_3115.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/public/img/img_3115.jpg -------------------------------------------------------------------------------- /public/img/apple-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/public/img/apple-icon.png -------------------------------------------------------------------------------- /public/img/default-avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/public/img/default-avatar.png -------------------------------------------------------------------------------- /src/assets/fonts/nucleo.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/src/assets/fonts/nucleo.eot -------------------------------------------------------------------------------- /src/assets/fonts/nucleo.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/src/assets/fonts/nucleo.ttf -------------------------------------------------------------------------------- /src/assets/fonts/nucleo.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/src/assets/fonts/nucleo.woff -------------------------------------------------------------------------------- /src/assets/fonts/nucleo.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/src/assets/fonts/nucleo.woff2 -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/custom/utilities/_sizing.scss: -------------------------------------------------------------------------------- 1 | // Height values in vh 2 | 3 | .h-100vh { 4 | height: 100vh !important; 5 | } 6 | -------------------------------------------------------------------------------- /docker/frontend_setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd src/ 3 | npm install 4 | # yarn install 5 | # yarn serve --host 0.0.0.0 6 | yarn build --watch --mode=production -------------------------------------------------------------------------------- /public/img/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/public/img/icons/favicon-16x16.png -------------------------------------------------------------------------------- /public/img/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/public/img/icons/favicon-32x32.png -------------------------------------------------------------------------------- /backend/users/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from . import models 4 | # Register your models here. 5 | admin.site.register(models.User) -------------------------------------------------------------------------------- /public/img/icons/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/public/img/icons/mstile-150x150.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/public/img/icons/apple-touch-icon.png -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/_media.scss: -------------------------------------------------------------------------------- 1 | .media { 2 | display: flex; 3 | align-items: flex-start; 4 | } 5 | 6 | .media-body { 7 | flex: 1; 8 | } 9 | -------------------------------------------------------------------------------- /public/img/icons/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/public/img/icons/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/img/icons/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/public/img/icons/android-chrome-512x512.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/public/img/icons/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/public/img/icons/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/mixins/_box-shadow.scss: -------------------------------------------------------------------------------- 1 | @mixin box-shadow($shadow...) { 2 | @if $enable-shadows { 3 | box-shadow: $shadow; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/public/img/icons/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/public/img/icons/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/public/img/icons/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /public/img/icons/msapplication-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iProgramStuff/docker-django-vue-postgres-template/HEAD/public/img/icons/msapplication-icon-144x144.png -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/mixins/_size.scss: -------------------------------------------------------------------------------- 1 | // Sizing shortcuts 2 | 3 | @mixin size($width, $height: $width) { 4 | width: $width; 5 | height: $height; 6 | } 7 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/mixins/_clearfix.scss: -------------------------------------------------------------------------------- 1 | @mixin clearfix() { 2 | &::after { 3 | display: block; 4 | clear: both; 5 | content: ""; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/custom/_images.scss: -------------------------------------------------------------------------------- 1 | img{ 2 | max-width: 100%; 3 | border-radius: $border-radius-sm; 4 | } 5 | .img-raised{ 6 | box-shadow: $box-shadow-raised; 7 | } 8 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/custom/mixins/_icon.scss: -------------------------------------------------------------------------------- 1 | @mixin icon-shape-variant($color) { 2 | color: saturate(darken($color, 10%), 10); 3 | background-color: transparentize(lighten($color, 10%), .5); 4 | } -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/mixins/_visibility.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | // Visibility 4 | 5 | @mixin invisible($visibility) { 6 | visibility: $visibility !important; 7 | } 8 | -------------------------------------------------------------------------------- /src/layout/dashboard/MobileMenu.vue: -------------------------------------------------------------------------------- 1 | 6 | 9 | 11 | -------------------------------------------------------------------------------- /src/layout/starter/MobileMenu.vue: -------------------------------------------------------------------------------- 1 | 6 | 9 | 11 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/utilities/_screenreaders.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Screenreaders 3 | // 4 | 5 | .sr-only { 6 | @include sr-only(); 7 | } 8 | 9 | .sr-only-focusable { 10 | @include sr-only-focusable(); 11 | } 12 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/custom/mixins/opacity.scss: -------------------------------------------------------------------------------- 1 | // Opacity 2 | 3 | @mixin opacity($opacity) { 4 | opacity: $opacity; 5 | // IE8 filter 6 | $opacity-ie: ($opacity * 100); 7 | filter: #{alpha(opacity=$opacity-ie)}; 8 | } 9 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/utilities/_visibility.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Visibility utilities 3 | // 4 | 5 | .visible { 6 | @include invisible(visible); 7 | } 8 | 9 | .invisible { 10 | @include invisible(hidden); 11 | } 12 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/mixins/_lists.scss: -------------------------------------------------------------------------------- 1 | // Lists 2 | 3 | // Unstyled keeps list items block level, just removes default browser padding and list-style 4 | @mixin list-unstyled { 5 | padding-left: 0; 6 | list-style: none; 7 | } 8 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/mixins/_text-truncate.scss: -------------------------------------------------------------------------------- 1 | // Text truncate 2 | // Requires inline-block or block for proper styling 3 | 4 | @mixin text-truncate() { 5 | overflow: hidden; 6 | text-overflow: ellipsis; 7 | white-space: nowrap; 8 | } 9 | -------------------------------------------------------------------------------- /src/layout/starter/SamplePage.vue: -------------------------------------------------------------------------------- 1 | 4 | 12 | 13 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/mixins/_resize.scss: -------------------------------------------------------------------------------- 1 | // Resize anything 2 | 3 | @mixin resizable($direction) { 4 | overflow: auto; // Per CSS3 UI, `resize` only applies when `overflow` isn't `visible` 5 | resize: $direction; // Options: horizontal, vertical, both 6 | } 7 | -------------------------------------------------------------------------------- /src/pages/Notifications/NotificationTemplate.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /backend/requirements.txt: -------------------------------------------------------------------------------- 1 | dj-database-url==0.5.0 2 | Django==2.1.7 3 | django-cors-headers==2.5.1 4 | django-environ==0.4.5 5 | djangorestframework==3.9.2 6 | djangorestframework-jwt==1.11.0 7 | gunicorn==19.9.0 8 | psycopg2-binary==2.7.7 9 | PyJWT==1.7.1 10 | pytz==2018.9 11 | whitenoise==4.0 -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/mixins/_float.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | @mixin float-left { 4 | float: left !important; 5 | } 6 | @mixin float-right { 7 | float: right !important; 8 | } 9 | @mixin float-none { 10 | float: none !important; 11 | } 12 | -------------------------------------------------------------------------------- /src/config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | colors: { 3 | default: "#344675", 4 | primary: "#42b883", 5 | info: "#1d8cf8", 6 | danger: "#fd5d93", 7 | teal: "#00d6b4", 8 | primaryGradient: ['rgba(76, 211, 150, 0.1)', 'rgba(53, 183, 125, 0)', 'rgba(119,52,169,0)'], 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /docker/BackendDockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3 2 | ENV PYTHONUNBUFFERED 1 3 | RUN mkdir /app 4 | COPY backend/requirements.txt /app/ 5 | RUN pip install -r app/requirements.txt 6 | COPY . /app 7 | WORKDIR /app 8 | EXPOSE 8000 9 | # RUN python manage.py migrate 10 | # CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | import userModule from './user' 4 | 5 | Vue.use(Vuex); 6 | 7 | const store = new Vuex.Store({ 8 | modules: { 9 | userModule, 10 | } 11 | }); 12 | 13 | store.commit("userModule/initialiseStore"); 14 | 15 | export default store; -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/utilities/_shadows.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | .shadow-sm { box-shadow: $box-shadow-sm !important; } 4 | .shadow { box-shadow: $box-shadow !important; } 5 | .shadow-lg { box-shadow: $box-shadow-lg !important; } 6 | .shadow-none { box-shadow: none !important; } 7 | -------------------------------------------------------------------------------- /docker/backend_setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | yes | python manage.py makemigrations # This is a development thing so I don't have to run it manually, but will be removed in production 4 | yes | python manage.py migrate 5 | yes | python manage.py loaddata categories 6 | 7 | python manage.py runserver 0.0.0.0:8000 --settings=backend.settings.dev -------------------------------------------------------------------------------- /docker/FrontendDockerfile: -------------------------------------------------------------------------------- 1 | FROM node:11.11.0-stretch 2 | COPY . /app 3 | WORKDIR /app 4 | EXPOSE 8000 5 | 6 | RUN npm install -g npm 7 | RUN npm install -g @vue/cli @vue/cli-service @vue/cli-plugin-babel @vue/cli-plugin-eslint @vue/cli-plugin-pwa vue-template-compiler@^2.0.0 vue-cli-plugin-i18n ajv@^5.0.0 chart.js@2.7.x webpack 8 | 9 | RUN npm install -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/mixins/_badge.scss: -------------------------------------------------------------------------------- 1 | @mixin badge-variant($bg) { 2 | color: color-yiq($bg); 3 | background-color: $bg; 4 | 5 | &[href] { 6 | @include hover-focus { 7 | color: color-yiq($bg); 8 | text-decoration: none; 9 | background-color: darken($bg, 10%); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/components/Charts/utils.js: -------------------------------------------------------------------------------- 1 | export function hexToRGB(hex, alpha) { 2 | const r = parseInt(hex.slice(1, 3), 16), 3 | g = parseInt(hex.slice(3, 5), 16), 4 | b = parseInt(hex.slice(5, 7), 16); 5 | 6 | if (alpha) { 7 | return `rgba(${r},${g},${b}, ${alpha})`; 8 | } else { 9 | return `rgb(${r},${g},${b})`; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/mixins/_alert.scss: -------------------------------------------------------------------------------- 1 | @mixin alert-variant($background, $border, $color) { 2 | color: $color; 3 | @include gradient-bg($background); 4 | border-color: $border; 5 | 6 | hr { 7 | border-top-color: darken($border, 5%); 8 | } 9 | 10 | .alert-link { 11 | color: darken($color, 10%); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/custom/utilities/_transform.scss: -------------------------------------------------------------------------------- 1 | @include media-breakpoint-up(lg) { 2 | .transform-perspective-right { 3 | transform: scale(1) perspective(1040px) rotateY(-11deg) rotateX(2deg) rotate(2deg); 4 | } 5 | .transform-perspective-left{ 6 | transform: scale(1) perspective(2000px) rotateY(11deg) rotateX(2deg) rotate(-2deg) 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | db.sqlite3 4 | /dist 5 | /venv 6 | __pycache__ 7 | 8 | # local env files 9 | .env.local 10 | .env.*.local 11 | 12 | # Log files 13 | npm-debug.log* 14 | yarn-debug.log* 15 | yarn-error.log* 16 | 17 | # Editor directories and files 18 | .idea 19 | .vscode 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw* 25 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | Idea: Start new users with demo data and little popups. When they enter their first entry, popup about deleting their demo data. And have message "When you're ready to start tracking your own data, CLICK HERE to delete data" 2 | 3 | 4 | Users should be able to edit their (add / delete) categories at their whim. More complicated with entries in a category though. 5 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/mixins/_nav-divider.scss: -------------------------------------------------------------------------------- 1 | // Horizontal dividers 2 | // 3 | // Dividers (basically an hr) within dropdowns and nav lists 4 | 5 | @mixin nav-divider($color: $nav-divider-color, $margin-y: $nav-divider-margin-y) { 6 | height: 0; 7 | margin: $margin-y 0; 8 | overflow: hidden; 9 | border-top: 1px solid $color; 10 | } 11 | -------------------------------------------------------------------------------- /src/service/local-storage-service.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueLocalStorage from 'vue-localstorage' 3 | 4 | Vue.use(VueLocalStorage, { 5 | name: 'localStorage', 6 | bind: true, //created computed members from variable declarations 7 | localStorage: { 8 | userAuthData: null 9 | } 10 | }); 11 | 12 | export default Vue.localStorage; -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/mixins/_text-emphasis.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | // Typography 4 | 5 | @mixin text-emphasis-variant($parent, $color) { 6 | #{$parent} { 7 | color: $color !important; 8 | } 9 | a#{$parent} { 10 | @include hover-focus { 11 | color: darken($color, 10%) !important; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/custom/utilities/_position.scss: -------------------------------------------------------------------------------- 1 | @each $size, $value in $spacers { 2 | .top-#{$size} { 3 | top: $value; 4 | } 5 | .right-#{$size} { 6 | right: $value; 7 | } 8 | .bottom-#{$size} { 9 | bottom: $value; 10 | } 11 | .left-#{$size} { 12 | left: $value; 13 | } 14 | } 15 | 16 | .center { 17 | left: 50%; 18 | transform: translateX(-50%); 19 | } -------------------------------------------------------------------------------- /src/plugins/globalDirectives.js: -------------------------------------------------------------------------------- 1 | import clickOutside from '../directives/click-ouside.js'; 2 | 3 | 4 | /** 5 | * You can register global directives here and use them as a plugin in your main Vue instance 6 | */ 7 | 8 | const GlobalDirectives = { 9 | install (Vue) { 10 | Vue.directive('click-outside', clickOutside); 11 | } 12 | } 13 | 14 | export default GlobalDirectives 15 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/mixins/_transition.scss: -------------------------------------------------------------------------------- 1 | @mixin transition($transition...) { 2 | @if $enable-transitions { 3 | @if length($transition) == 0 { 4 | transition: $transition-base; 5 | } @else { 6 | transition: $transition; 7 | } 8 | } 9 | 10 | @media screen and (prefers-reduced-motion: reduce) { 11 | transition: none; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/custom/_utilities.scss: -------------------------------------------------------------------------------- 1 | @import "utilities/backgrounds.scss"; 2 | @import "utilities/floating.scss"; 3 | @import "utilities/helper.scss"; 4 | @import "utilities/position.scss"; 5 | @import "utilities/sizing.scss"; 6 | @import "utilities/spacing.scss"; 7 | @import "utilities/shadows.scss"; 8 | @import "utilities/text.scss"; 9 | @import "utilities/transform.scss"; 10 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/custom/cards/_card-plain.scss: -------------------------------------------------------------------------------- 1 | .card-plain { 2 | background: transparent; 3 | box-shadow: none; 4 | 5 | .card-header, 6 | .card-footer { 7 | margin-left: 0; 8 | margin-right: 0; 9 | background-color: transparent; 10 | } 11 | 12 | &:not(.card-subcategories).card-body { 13 | padding-left: 0; 14 | padding-right: 0; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/custom/mixins/_badges.scss: -------------------------------------------------------------------------------- 1 | @mixin badge-variant($bg) { 2 | color: color-yiq($bg); 3 | background-color: $bg; 4 | 5 | &[href] { 6 | @include hover-focus { 7 | color: color-yiq($bg); 8 | text-decoration: none; 9 | background-color: darken($bg, 3%); 10 | } 11 | } 12 | .tagsinput-remove-link{ 13 | color: $white; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /backend/api/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from rest_framework import serializers 3 | 4 | 5 | class Message(models.Model): 6 | subject = models.CharField(max_length=200) 7 | body = models.TextField() 8 | 9 | 10 | class MessageSerializer(serializers.HyperlinkedModelSerializer): 11 | class Meta: 12 | model = Message 13 | fields = ('url', 'subject', 'body', 'pk') 14 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/utilities/_sizing.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | // Width and height 4 | 5 | @each $prop, $abbrev in (width: w, height: h) { 6 | @each $size, $length in $sizes { 7 | .#{$abbrev}-#{$size} { #{$prop}: $length !important; } 8 | } 9 | } 10 | 11 | .mw-100 { max-width: 100% !important; } 12 | .mh-100 { max-height: 100% !important; } 13 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/utilities/_float.scss: -------------------------------------------------------------------------------- 1 | @each $breakpoint in map-keys($grid-breakpoints) { 2 | @include media-breakpoint-up($breakpoint) { 3 | $infix: breakpoint-infix($breakpoint, $grid-breakpoints); 4 | 5 | .float#{$infix}-left { @include float-left; } 6 | .float#{$infix}-right { @include float-right; } 7 | .float#{$infix}-none { @include float-none; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/custom/mixins/_modals.scss: -------------------------------------------------------------------------------- 1 | @mixin modal-colors($bg-color, $color) { 2 | .modal-content{ 3 | background-color: $bg-color; 4 | color: $color; 5 | } 6 | 7 | .modal-body p{ 8 | color: rgba($white, 0.8); 9 | } 10 | 11 | //inputs 12 | @include input-coloured-bg($opacity-5, $white, $white, $transparent-bg, $opacity-1, $opacity-2); 13 | 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/layout/starter/Content.vue: -------------------------------------------------------------------------------- 1 | 9 | 17 | -------------------------------------------------------------------------------- /src/layout/dashboard/Content.vue: -------------------------------------------------------------------------------- 1 | 9 | 17 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import VueRouter from "vue-router"; 2 | import routes from "./routes"; 3 | 4 | // configure router 5 | const router = new VueRouter({ 6 | routes, // short for routes: routes 7 | linkExactActiveClass: "active", 8 | scrollBehavior: (to) => { 9 | if (to.hash) { 10 | return {selector: to.hash} 11 | } else { 12 | return { x: 0, y: 0 } 13 | } 14 | } 15 | }); 16 | 17 | export default router; 18 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/custom/mixins/_alert.scss: -------------------------------------------------------------------------------- 1 | @mixin alert-variant($background, $border, $color) { 2 | color: color-yiq($background); 3 | // @include gradient-bg($background); 4 | background-color: lighten($background, 5%); 5 | border-color: $border; 6 | 7 | hr { 8 | border-top-color: darken($border, 5%); 9 | } 10 | 11 | .alert-link { 12 | color: darken($color, 10%); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/custom/utilities/_shadows.scss: -------------------------------------------------------------------------------- 1 | [class*="shadow"] { 2 | @if $enable-transitions { 3 | transition: $transition-base; 4 | } 5 | } 6 | 7 | .shadow-sm--hover:hover { box-shadow: $box-shadow-sm !important; } 8 | .shadow--hover:hover { box-shadow: $box-shadow !important; } 9 | .shadow-lg--hover:hover { box-shadow: $box-shadow-lg !important; } 10 | .shadow-none--hover:hover { box-shadow: none !important; } 11 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/_transitions.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable selector-no-qualifying-type 2 | 3 | .fade { 4 | @include transition($transition-fade); 5 | 6 | &:not(.show) { 7 | opacity: 0; 8 | } 9 | } 10 | 11 | .collapse { 12 | &:not(.show) { 13 | display: none; 14 | } 15 | } 16 | 17 | .collapsing { 18 | position: relative; 19 | height: 0; 20 | overflow: hidden; 21 | @include transition($transition-collapse); 22 | } 23 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/_jumbotron.scss: -------------------------------------------------------------------------------- 1 | .jumbotron { 2 | padding: $jumbotron-padding ($jumbotron-padding / 2); 3 | margin-bottom: $jumbotron-padding; 4 | background-color: $jumbotron-bg; 5 | @include border-radius($border-radius-lg); 6 | 7 | @include media-breakpoint-up(sm) { 8 | padding: ($jumbotron-padding * 2) $jumbotron-padding; 9 | } 10 | } 11 | 12 | .jumbotron-fluid { 13 | padding-right: 0; 14 | padding-left: 0; 15 | @include border-radius(0); 16 | } 17 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/utilities/_align.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | .align-baseline { vertical-align: baseline !important; } // Browser default 4 | .align-top { vertical-align: top !important; } 5 | .align-middle { vertical-align: middle !important; } 6 | .align-bottom { vertical-align: bottom !important; } 7 | .align-text-bottom { vertical-align: text-bottom !important; } 8 | .align-text-top { vertical-align: text-top !important; } 9 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/mixins/_text-hide.scss: -------------------------------------------------------------------------------- 1 | // CSS image replacement 2 | @mixin text-hide($ignore-warning: false) { 3 | // stylelint-disable-next-line font-family-no-missing-generic-family-keyword 4 | font: 0/0 a; 5 | color: transparent; 6 | text-shadow: none; 7 | background-color: transparent; 8 | border: 0; 9 | 10 | @if ($ignore-warning != true) { 11 | @warn "The `text-hide()` mixin has been deprecated as of v4.1.0. It will be removed entirely in v5."; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/pages/Dashboard/UserTable.vue: -------------------------------------------------------------------------------- 1 | 7 | 20 | 22 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "besquared", 3 | "short_name": "besquared", 4 | "icons": [ 5 | { 6 | "src": "./img/icons/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "./img/icons/android-chrome-512x512.png", 12 | "sizes": "512x512", 13 | "type": "image/png" 14 | } 15 | ], 16 | "start_url": "./index.html", 17 | "display": "standalone", 18 | "background_color": "#000000", 19 | "theme_color": "#4DBA87" 20 | } 21 | -------------------------------------------------------------------------------- /backend/settings/prod.py: -------------------------------------------------------------------------------- 1 | """ Production Settings """ 2 | 3 | import os 4 | # import dj_database_url 5 | from .dev import * 6 | 7 | 8 | ############ 9 | # DATABASE # 10 | ############ 11 | # DATABASES = { 12 | # 'default': dj_database_url.config( 13 | # default=os.getenv('DATABASE_URL') 14 | # ) 15 | # } 16 | 17 | 18 | ############ 19 | # SECURITY # 20 | ############ 21 | 22 | DEBUG = False # bool(os.getenv('DJANGO_DEBUG', '')) 23 | 24 | # Set to your Domain here (eg. 'yourwebsite.com') 25 | ALLOWED_HOSTS = ['*'] 26 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/utilities/_background.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | @each $color, $value in $theme-colors { 4 | @include bg-variant(".bg-#{$color}", $value); 5 | } 6 | 7 | @if $enable-gradients { 8 | @each $color, $value in $theme-colors { 9 | @include bg-gradient-variant(".bg-gradient-#{$color}", $value); 10 | } 11 | } 12 | 13 | .bg-white { 14 | background-color: $white !important; 15 | } 16 | 17 | .bg-transparent { 18 | background-color: transparent !important; 19 | } 20 | -------------------------------------------------------------------------------- /src/helpers/utils.js: -------------------------------------------------------------------------------- 1 | export const validateEmail = function (email) { 2 | var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; 3 | return re.test(email); 4 | } 5 | 6 | export const escapeSpecialUrlCharacters = function (string) { 7 | return string 8 | .replace(/'/g, "%27") 9 | .replace(/&/g, "%26") 10 | .replace(/%/g, "%25") 11 | .replace(/#/g, "%23") 12 | .replace(/\s/g, "%20"); 13 | } -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/custom/mixins/_page-header.scss: -------------------------------------------------------------------------------- 1 | @mixin linear-gradient($color1, $color2){ 2 | background: $color1; /* For browsers that do not support gradients */ 3 | background: -webkit-linear-gradient(90deg, $color1 , $color2); /* For Safari 5.1 to 6.0 */ 4 | background: -o-linear-gradient(90deg, $color1, $color2); /* For Opera 11.1 to 12.0 */ 5 | background: -moz-linear-gradient(90deg, $color1, $color2); /* For Firefox 3.6 to 15 */ 6 | background: linear-gradient(0deg, $color1 , $color2); /* Standard syntax */ 7 | } 8 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/_utilities.scss: -------------------------------------------------------------------------------- 1 | @import "utilities/align"; 2 | @import "utilities/background"; 3 | @import "utilities/borders"; 4 | @import "utilities/clearfix"; 5 | @import "utilities/display"; 6 | @import "utilities/embed"; 7 | @import "utilities/flex"; 8 | @import "utilities/float"; 9 | @import "utilities/position"; 10 | @import "utilities/screenreaders"; 11 | @import "utilities/shadows"; 12 | @import "utilities/sizing"; 13 | @import "utilities/spacing"; 14 | @import "utilities/text"; 15 | @import "utilities/visibility"; 16 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/mixins/_list-group.scss: -------------------------------------------------------------------------------- 1 | // List Groups 2 | 3 | @mixin list-group-item-variant($state, $background, $color) { 4 | .list-group-item-#{$state} { 5 | color: $color; 6 | background-color: $background; 7 | 8 | &.list-group-item-action { 9 | @include hover-focus { 10 | color: $color; 11 | background-color: darken($background, 5%); 12 | } 13 | 14 | &.active { 15 | color: $white; 16 | background-color: $color; 17 | border-color: $color; 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/custom/_mixins.scss: -------------------------------------------------------------------------------- 1 | @import "mixins/alert.scss"; 2 | @import "mixins/badges.scss"; 3 | @import "mixins/background-variant.scss"; 4 | @import "mixins/buttons.scss"; 5 | @import "mixins/forms.scss"; 6 | @import "mixins/icon.scss"; 7 | @import "mixins/modals.scss"; 8 | @import "mixins/popovers.scss"; 9 | @import "mixins/page-header.scss"; 10 | @import "mixins/vendor-prefixes.scss"; 11 | @import "mixins/opacity.scss"; 12 | @import "mixins/modals.scss"; 13 | @import "mixins/inputs.scss"; 14 | @import "mixins/dropdown.scss"; 15 | @import "mixins/wizard.scss"; 16 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/custom/mixins/_background-variant.scss: -------------------------------------------------------------------------------- 1 | // Contextual backgrounds 2 | @mixin bg-variant($parent, $color) { 3 | #{$parent} { 4 | background-color: $color !important; 5 | } 6 | a#{$parent}, 7 | button#{$parent} { 8 | @include hover-focus { 9 | background-color: darken($color, 10%) !important; 10 | } 11 | } 12 | } 13 | 14 | @mixin bg-gradient-variant($parent, $color) { 15 | #{$parent} { 16 | background: linear-gradient(87deg, $color 0, adjust-hue($color, 25%) 100%) !important; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == '__main__': 6 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'backend.settings.dev') 7 | try: 8 | from django.core.management import execute_from_command_line 9 | except ImportError as exc: 10 | raise ImportError( 11 | "Couldn't import Django. Are you sure it's installed and " 12 | "available on your PYTHONPATH environment variable? Did you " 13 | "forget to activate a virtual environment?" 14 | ) from exc 15 | execute_from_command_line(sys.argv) 16 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/mixins/_pagination.scss: -------------------------------------------------------------------------------- 1 | // Pagination 2 | 3 | @mixin pagination-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) { 4 | .page-link { 5 | padding: $padding-y $padding-x; 6 | font-size: $font-size; 7 | line-height: $line-height; 8 | } 9 | 10 | .page-item { 11 | &:first-child { 12 | .page-link { 13 | @include border-left-radius($border-radius); 14 | } 15 | } 16 | &:last-child { 17 | .page-link { 18 | @include border-right-radius($border-radius); 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/custom/cards/_card-task.scss: -------------------------------------------------------------------------------- 1 | .card-tasks { 2 | height: 473px; 3 | 4 | .table-full-width { 5 | max-height: 410px; 6 | position: relative; 7 | } 8 | 9 | .card-header { 10 | .title { 11 | margin-right: 20px; 12 | font-weight: $font-weight-normal; 13 | } 14 | 15 | .dropdown { 16 | float: right; 17 | color: darken($white, 20%); 18 | } 19 | } 20 | 21 | .card-body { 22 | i { 23 | color: $dark-gray; 24 | font-size: 1.4em; 25 | &:hover { 26 | color: $white; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/plugins/globalComponents.js: -------------------------------------------------------------------------------- 1 | import { BaseInput, Card, BaseDropdown, BaseButton, BaseCheckbox } from "../components/index"; 2 | /** 3 | * You can register global components here and use them as a plugin in your main Vue instance 4 | */ 5 | 6 | const GlobalComponents = { 7 | install(Vue) { 8 | Vue.component(BaseInput.name, BaseInput); 9 | Vue.component(Card.name, Card); 10 | Vue.component(BaseDropdown.name, BaseDropdown); 11 | Vue.component(BaseButton.name, BaseButton); 12 | Vue.component(BaseCheckbox.name, BaseCheckbox); 13 | } 14 | }; 15 | 16 | export default GlobalComponents; 17 | -------------------------------------------------------------------------------- /src/directives/click-ouside.js: -------------------------------------------------------------------------------- 1 | export default { 2 | bind: function (el, binding, vnode) { 3 | el.clickOutsideEvent = function (event) { 4 | // here I check that click was outside the el and his childrens 5 | if (!(el == event.target || el.contains(event.target))) { 6 | // and if it did, call method provided in attribute value 7 | vnode.context[binding.expression](event); 8 | } 9 | }; 10 | document.body.addEventListener('click', el.clickOutsideEvent) 11 | }, 12 | unbind: function (el) { 13 | document.body.removeEventListener('click', el.clickOutsideEvent) 14 | }, 15 | } 16 | -------------------------------------------------------------------------------- /backend/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for project project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | # This will set production as default, but we must still set it with an 15 | # ENV on heroku to ensure that the migrate command runs agains the correct DB 16 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'backend.settings.prod') 17 | 18 | application = get_wsgi_application() 19 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/mixins/_background-variant.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | // Contextual backgrounds 4 | 5 | @mixin bg-variant($parent, $color) { 6 | #{$parent} { 7 | background-color: $color !important; 8 | } 9 | a#{$parent}, 10 | button#{$parent} { 11 | @include hover-focus { 12 | background-color: darken($color, 10%) !important; 13 | } 14 | } 15 | } 16 | 17 | @mixin bg-gradient-variant($parent, $color) { 18 | #{$parent} { 19 | background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x !important; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /backend/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path, include 2 | from rest_framework_jwt.views import obtain_jwt_token, refresh_jwt_token, verify_jwt_token 3 | from rest_framework import routers 4 | from . import views 5 | 6 | router = routers.DefaultRouter() 7 | router.register('messages', views.MessageViewSet) 8 | 9 | urlpatterns = [ 10 | path('', include(router.urls)), 11 | path('auth/login/', obtain_jwt_token, name="auth-login"), 12 | path('auth/register/', views.CreateUserView.as_view(), name="auth-register"), 13 | path('auth/token-refresh/', refresh_jwt_token), 14 | path('auth/token-verify/', verify_jwt_token), 15 | ] 16 | -------------------------------------------------------------------------------- /src/plugins/blackDashboard.js: -------------------------------------------------------------------------------- 1 | import SideBar from "@/components/SidebarPlugin"; 2 | import Notify from "@/components/NotificationPlugin"; 3 | import GlobalComponents from "./globalComponents"; 4 | import GlobalDirectives from "./globalDirectives"; 5 | import RTLPlugin from "./RTLPlugin"; 6 | 7 | //css assets 8 | import "@/assets/sass/black-dashboard.scss"; 9 | import "@/assets/css/nucleo-icons.css"; 10 | import "@/assets/demo/demo.css"; 11 | 12 | export default { 13 | install(Vue) { 14 | Vue.use(GlobalComponents); 15 | Vue.use(GlobalDirectives); 16 | Vue.use(SideBar); 17 | Vue.use(Notify); 18 | Vue.use(RTLPlugin); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /backend/api/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.1 on 2018-08-10 00:59 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | initial = True 9 | 10 | dependencies = [ 11 | ] 12 | 13 | operations = [ 14 | migrations.CreateModel( 15 | name='Message', 16 | fields=[ 17 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 18 | ('subject', models.CharField(max_length=200)), 19 | ('body', models.TextField()), 20 | ], 21 | ), 22 | ] 23 | -------------------------------------------------------------------------------- /src/components/SidebarPlugin/index.js: -------------------------------------------------------------------------------- 1 | import Sidebar from "./SideBar.vue"; 2 | import SidebarLink from "./SidebarLink"; 3 | 4 | const SidebarStore = { 5 | showSidebar: false, 6 | sidebarLinks: [], 7 | displaySidebar(value) { 8 | this.showSidebar = value; 9 | } 10 | }; 11 | 12 | const SidebarPlugin = { 13 | install(Vue) { 14 | let app = new Vue({ 15 | data: { 16 | sidebarStore: SidebarStore 17 | } 18 | }); 19 | 20 | Vue.prototype.$sidebar = app.sidebarStore; 21 | Vue.component("side-bar", Sidebar); 22 | Vue.component("sidebar-link", SidebarLink); 23 | } 24 | }; 25 | 26 | export default SidebarPlugin; 27 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/mixins/_reset-text.scss: -------------------------------------------------------------------------------- 1 | @mixin reset-text { 2 | font-family: $font-family-base; 3 | // We deliberately do NOT reset font-size or word-wrap. 4 | font-style: normal; 5 | font-weight: $font-weight-normal; 6 | line-height: $line-height-base; 7 | text-align: left; // Fallback for where `start` is not supported 8 | text-align: start; // stylelint-disable-line declaration-block-no-duplicate-properties 9 | text-decoration: none; 10 | text-shadow: none; 11 | text-transform: none; 12 | letter-spacing: normal; 13 | word-break: normal; 14 | word-spacing: normal; 15 | white-space: normal; 16 | line-break: auto; 17 | } 18 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/custom/mixins/_dropdown.scss: -------------------------------------------------------------------------------- 1 | @mixin dropdown-colors($brand-color, $dropdown-header-color, $dropdown-color, $background-color ) { 2 | background-color: $brand-color; 3 | 4 | &:before{ 5 | color: $brand-color; 6 | } 7 | 8 | .dropdown-header:not([href]):not([tabindex]){ 9 | color: $dropdown-header-color; 10 | } 11 | 12 | .dropdown-item{ 13 | color: $dropdown-color; 14 | 15 | &:hover, 16 | &:focus{ 17 | background-color: $background-color; 18 | } 19 | } 20 | 21 | .dropdown-divider{ 22 | background-color: $background-color; 23 | } 24 | 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/_root.scss: -------------------------------------------------------------------------------- 1 | :root { 2 | // Custom variable values only support SassScript inside `#{}`. 3 | @each $color, $value in $colors { 4 | --#{$color}: #{$value}; 5 | } 6 | 7 | @each $color, $value in $theme-colors { 8 | --#{$color}: #{$value}; 9 | } 10 | 11 | @each $bp, $value in $grid-breakpoints { 12 | --breakpoint-#{$bp}: #{$value}; 13 | } 14 | 15 | // Use `inspect` for lists so that quoted items keep the quotes. 16 | // See https://github.com/sass/sass/issues/2383#issuecomment-336349172 17 | --font-family-sans-serif: #{inspect($font-family-sans-serif)}; 18 | --font-family-monospace: #{inspect($font-family-monospace)}; 19 | } 20 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/custom/_functions.scss: -------------------------------------------------------------------------------- 1 | // Retrieve color Sass maps 2 | 3 | @function section-color($key: "primary") { 4 | @return map-get($section-colors, $key); 5 | } 6 | 7 | // Lines colors 8 | 9 | @function shapes-primary-color($key: "step-1-gradient-bg") { 10 | @return map-get($shapes-primary-colors, $key); 11 | } 12 | 13 | @function shapes-default-color($key: "step-1-gradient-bg") { 14 | @return map-get($shapes-default-colors, $key); 15 | } 16 | 17 | @function lines-light-color($key: "step-1-gradient-bg") { 18 | @return map-get($shapes-light-colors, $key); 19 | } 20 | 21 | @function shapes-dark-color($key: "step-1-gradient-bg") { 22 | @return map-get($shapes-dark-colors, $key); 23 | } -------------------------------------------------------------------------------- /src/components/Cards/StatsCard.vue: -------------------------------------------------------------------------------- 1 | 20 | 30 | 32 | -------------------------------------------------------------------------------- /src/i18n.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueI18n from 'vue-i18n' 3 | 4 | Vue.use(VueI18n) 5 | 6 | function loadLocaleMessages () { 7 | const locales = require.context('./locales', true, /[A-Za-z0-9-_,\s]+\.json$/i) 8 | const messages = {} 9 | locales.keys().forEach(key => { 10 | const matched = key.match(/([a-z0-9]+)\./i) 11 | if (matched && matched.length > 1) { 12 | const locale = matched[1] 13 | messages[locale] = locales(key) 14 | } 15 | }) 16 | return messages 17 | } 18 | 19 | export default new VueI18n({ 20 | locale: process.env.VUE_APP_I18N_LOCALE || 'en', 21 | fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en', 22 | messages: loadLocaleMessages() 23 | }) 24 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/components/NavbarToggleButton.vue: -------------------------------------------------------------------------------- 1 | 11 | 26 | 28 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Docker Django VueJs Postgres Template", 3 | "description": "", 4 | "repository": "https://github.com/iprogramstuff/docker-django-vue-postgres-template", 5 | "keywords": ["django", "vue", "vuejs", "template", "django rest framework"], 6 | "env": { 7 | "DJANGO_SETTINGS_MODULE": { 8 | "description": "Set Django Settings to Production", 9 | "value": "backend.settings.prod" 10 | } 11 | }, 12 | "engines": { 13 | "yarn": "1.4.0", 14 | "npm": "6.2.0" 15 | }, 16 | "addons": [ 17 | 18 | ], 19 | "buildpacks": [ 20 | { 21 | "url": "heroku/nodejs" 22 | }, 23 | { 24 | "url": "heroku/python" 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/custom/mixins/_wizard.scss: -------------------------------------------------------------------------------- 1 | @mixin set-wizard-color($color) { 2 | .progress-with-circle .progress-bar{ 3 | background: $color; 4 | } 5 | 6 | .nav-pills .nav-item .nav-link{ 7 | color: $color; 8 | 9 | &.checked, &.active{ 10 | background: $color; 11 | color: white; 12 | } 13 | &:hover{ 14 | background: $white; 15 | } 16 | } 17 | 18 | .nav-pills .nav-item .nav-link.active, 19 | .nav-pills .nav-item .nav-link.checked:focus, 20 | .nav-pills .nav-item .nav-link.checked:hover, 21 | .nav-pills .nav-item .nav-link.active:focus, 22 | .nav-pills .nav-item .nav-link.active:hover{ 23 | background: $color; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/layout/dashboard/ContentFooter.vue: -------------------------------------------------------------------------------- 1 | 18 | 27 | 29 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | // import localStorage from './service/local-storage-service' 3 | import VueRouter from "vue-router"; 4 | import RouterPrefetch from 'vue-router-prefetch' 5 | import App from "./App"; 6 | import store from './store/index' 7 | 8 | // TIP: change to import router from "./router/starterRouter"; to start with a clean layout 9 | import router from "./router/index"; 10 | 11 | import BlackDashboard from "./plugins/blackDashboard"; 12 | import i18n from "./i18n" 13 | // import './registerServiceWorker' 14 | 15 | Vue.use(BlackDashboard); 16 | Vue.use(VueRouter); 17 | Vue.use(RouterPrefetch); 18 | 19 | /* eslint-disable no-new */ 20 | new Vue({ 21 | // localStorage, 22 | router, 23 | store, 24 | i18n, 25 | render: h => h(App) 26 | }).$mount("#app"); 27 | 28 | export {app, store} -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/mixins/_table-row.scss: -------------------------------------------------------------------------------- 1 | // Tables 2 | 3 | @mixin table-row-variant($state, $background) { 4 | // Exact selectors below required to override `.table-striped` and prevent 5 | // inheritance to nested tables. 6 | .table-#{$state} { 7 | &, 8 | > th, 9 | > td { 10 | background-color: $background; 11 | } 12 | } 13 | 14 | // Hover states for `.table-hover` 15 | // Note: this is not available for cells or rows within `thead` or `tfoot`. 16 | .table-hover { 17 | $hover-background: darken($background, 5%); 18 | 19 | .table-#{$state} { 20 | @include hover { 21 | background-color: $hover-background; 22 | 23 | > td, 24 | > th { 25 | background-color: $hover-background; 26 | } 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /backend/users/serializers.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth import get_user_model 2 | from rest_framework import serializers 3 | # from .models import User 4 | 5 | class UserSerializer(serializers.HyperlinkedModelSerializer): 6 | def create(self, validated_data): 7 | print("in create userserializer") 8 | try: 9 | user = get_user_model().objects.create( 10 | username=validated_data['username'], 11 | email=validated_data['email'] 12 | ) 13 | user.set_password(validated_data['password']) 14 | user.save() 15 | return user 16 | except Exception: 17 | return None 18 | 19 | class Meta: 20 | model = get_user_model() 21 | fields = ('username','email', 'password','created_at', 'updated_at', 'first_name', 'last_name', 'pk') 22 | -------------------------------------------------------------------------------- /src/components/index.js: -------------------------------------------------------------------------------- 1 | import BaseInput from "./Inputs/BaseInput.vue"; 2 | 3 | import BaseCheckbox from "./BaseCheckbox.vue"; 4 | import BaseRadio from "./BaseRadio.vue"; 5 | import BaseDropdown from "./BaseDropdown.vue"; 6 | import BaseTable from "./BaseTable.vue"; 7 | import BaseButton from "./BaseButton"; 8 | import BaseAlert from "./BaseAlert"; 9 | import BaseNav from "./BaseNav"; 10 | import Modal from "./Modal"; 11 | import CloseButton from "./CloseButton"; 12 | 13 | import Card from "./Cards/Card.vue"; 14 | import StatsCard from "./Cards/StatsCard.vue"; 15 | 16 | import SidebarPlugin from "./SidebarPlugin/index"; 17 | 18 | export { 19 | BaseInput, 20 | Card, 21 | Modal, 22 | CloseButton, 23 | StatsCard, 24 | BaseTable, 25 | BaseCheckbox, 26 | BaseRadio, 27 | BaseDropdown, 28 | BaseButton, 29 | BaseAlert, 30 | SidebarPlugin, 31 | BaseNav 32 | }; 33 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/utilities/_position.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | // Common values 4 | 5 | // Sass list not in variables since it's not intended for customization. 6 | // stylelint-disable-next-line scss/dollar-variable-default 7 | $positions: static, relative, absolute, fixed, sticky; 8 | 9 | @each $position in $positions { 10 | .position-#{$position} { position: $position !important; } 11 | } 12 | 13 | // Shorthand 14 | 15 | .fixed-top { 16 | position: fixed; 17 | top: 0; 18 | right: 0; 19 | left: 0; 20 | z-index: $zindex-fixed; 21 | } 22 | 23 | .fixed-bottom { 24 | position: fixed; 25 | right: 0; 26 | bottom: 0; 27 | left: 0; 28 | z-index: $zindex-fixed; 29 | } 30 | 31 | .sticky-top { 32 | @supports (position: sticky) { 33 | position: sticky; 34 | top: 0; 35 | z-index: $zindex-sticky; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/components/CloseButton.vue: -------------------------------------------------------------------------------- 1 | 13 | 33 | 35 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/custom/mixins/_popovers.scss: -------------------------------------------------------------------------------- 1 | @mixin popover-variant($background) { 2 | background-color: $background; 3 | 4 | .popover-header { 5 | background-color: $background; 6 | color: color-yiq($background); 7 | opacity: .6; 8 | } 9 | 10 | .popover-body { 11 | color: color-yiq($background); 12 | } 13 | 14 | .popover-header{ 15 | border-color: rgba(color-yiq($background), .2); 16 | } 17 | 18 | &.bs-popover-top { 19 | .arrow::after { 20 | border-top-color: $background; 21 | } 22 | } 23 | 24 | &.bs-popover-right { 25 | .arrow::after { 26 | border-right-color: $background; 27 | } 28 | } 29 | 30 | &.bs-popover-bottom { 31 | .arrow::after { 32 | border-bottom-color: $background; 33 | } 34 | } 35 | 36 | &.bs-popover-left { 37 | .arrow::after { 38 | border-left-color: $background; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/layout/starter/SampleLayout.vue: -------------------------------------------------------------------------------- 1 | 9 | 14 | 35 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/mixins/_border-radius.scss: -------------------------------------------------------------------------------- 1 | // Single side border-radius 2 | 3 | @mixin border-radius($radius: $border-radius) { 4 | @if $enable-rounded { 5 | border-radius: $radius; 6 | } 7 | } 8 | 9 | @mixin border-top-radius($radius) { 10 | @if $enable-rounded { 11 | border-top-left-radius: $radius; 12 | border-top-right-radius: $radius; 13 | } 14 | } 15 | 16 | @mixin border-right-radius($radius) { 17 | @if $enable-rounded { 18 | border-top-right-radius: $radius; 19 | border-bottom-right-radius: $radius; 20 | } 21 | } 22 | 23 | @mixin border-bottom-radius($radius) { 24 | @if $enable-rounded { 25 | border-bottom-right-radius: $radius; 26 | border-bottom-left-radius: $radius; 27 | } 28 | } 29 | 30 | @mixin border-left-radius($radius) { 31 | @if $enable-rounded { 32 | border-top-left-radius: $radius; 33 | border-bottom-left-radius: $radius; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/mixins/_screen-reader.scss: -------------------------------------------------------------------------------- 1 | // Only display content to screen readers 2 | // 3 | // See: https://a11yproject.com/posts/how-to-hide-content/ 4 | // See: https://hugogiraudel.com/2016/10/13/css-hide-and-seek/ 5 | 6 | @mixin sr-only { 7 | position: absolute; 8 | width: 1px; 9 | height: 1px; 10 | padding: 0; 11 | overflow: hidden; 12 | clip: rect(0, 0, 0, 0); 13 | white-space: nowrap; 14 | border: 0; 15 | } 16 | 17 | // Use in conjunction with .sr-only to only display content when it's focused. 18 | // 19 | // Useful for "Skip to main content" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 20 | // 21 | // Credit: HTML5 Boilerplate 22 | 23 | @mixin sr-only-focusable { 24 | &:active, 25 | &:focus { 26 | position: static; 27 | width: auto; 28 | height: auto; 29 | overflow: visible; 30 | clip: auto; 31 | white-space: normal; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/layout/starter/SampleFooter.vue: -------------------------------------------------------------------------------- 1 | 21 | 30 | -------------------------------------------------------------------------------- /src/helpers/interceptors.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import userStore from '../store/user' 3 | import store from '../store' 4 | import router from '../routes' 5 | 6 | export default function setup() { 7 | axios.interceptors.request.use(function (config) { 8 | // SET TOKEN 9 | const token = userStore.state.token; 10 | if (token) { 11 | config.headers.Authorization = `JWT ${token}`; 12 | } 13 | return config; 14 | }, function (err) { 15 | return Promise.reject(err); 16 | }); 17 | 18 | axios.interceptors.response.use(function (response) { 19 | return response; 20 | }, function (err) { 21 | if (err.message.includes("401")) { 22 | store.commit("userModule/logout"); 23 | router.go("/"); 24 | return; 25 | } 26 | // Do something with response error 27 | return Promise.reject(err); 28 | }); 29 | } -------------------------------------------------------------------------------- /backend/api/views.py: -------------------------------------------------------------------------------- 1 | from django.views.generic import TemplateView 2 | from django.views.decorators.cache import never_cache 3 | from django.contrib.auth import get_user_model 4 | 5 | from rest_framework import viewsets, status, permissions 6 | from rest_framework.response import Response 7 | from rest_framework.generics import CreateAPIView 8 | 9 | from .models import Message, MessageSerializer 10 | 11 | from backend.users.models import User 12 | from backend.users.serializers import UserSerializer 13 | 14 | class MessageViewSet(viewsets.ModelViewSet): 15 | """ 16 | API endpoint that allows messages to be viewed or edited. 17 | """ 18 | queryset = Message.objects.all() 19 | serializer_class = MessageSerializer 20 | 21 | class CreateUserView(CreateAPIView): 22 | model = get_user_model() 23 | permission_classes = [ 24 | permissions.AllowAny # Or anon users can't register 25 | ] 26 | serializer_class = UserSerializer -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/mixins/_hover.scss: -------------------------------------------------------------------------------- 1 | // Hover mixin and `$enable-hover-media-query` are deprecated. 2 | // 3 | // Originally added during our alphas and maintained during betas, this mixin was 4 | // designed to prevent `:hover` stickiness on iOS-an issue where hover styles 5 | // would persist after initial touch. 6 | // 7 | // For backward compatibility, we've kept these mixins and updated them to 8 | // always return their regular pseudo-classes instead of a shimmed media query. 9 | // 10 | // Issue: https://github.com/twbs/bootstrap/issues/25195 11 | 12 | @mixin hover { 13 | &:hover { @content; } 14 | } 15 | 16 | @mixin hover-focus { 17 | &:hover, 18 | &:focus { 19 | @content; 20 | } 21 | } 22 | 23 | @mixin plain-hover-focus { 24 | &, 25 | &:hover, 26 | &:focus { 27 | @content; 28 | } 29 | } 30 | 31 | @mixin hover-focus-active { 32 | &:hover, 33 | &:focus, 34 | &:active { 35 | @content; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/pages/Dashboard/TaskList.vue: -------------------------------------------------------------------------------- 1 | 21 | 34 | 36 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/utilities/_embed.scss: -------------------------------------------------------------------------------- 1 | // Credit: Nicolas Gallagher and SUIT CSS. 2 | 3 | .embed-responsive { 4 | position: relative; 5 | display: block; 6 | width: 100%; 7 | padding: 0; 8 | overflow: hidden; 9 | 10 | &::before { 11 | display: block; 12 | content: ""; 13 | } 14 | 15 | .embed-responsive-item, 16 | iframe, 17 | embed, 18 | object, 19 | video { 20 | position: absolute; 21 | top: 0; 22 | bottom: 0; 23 | left: 0; 24 | width: 100%; 25 | height: 100%; 26 | border: 0; 27 | } 28 | } 29 | 30 | .embed-responsive-21by9 { 31 | &::before { 32 | padding-top: percentage(9 / 21); 33 | } 34 | } 35 | 36 | .embed-responsive-16by9 { 37 | &::before { 38 | padding-top: percentage(9 / 16); 39 | } 40 | } 41 | 42 | .embed-responsive-4by3 { 43 | &::before { 44 | padding-top: percentage(3 / 4); 45 | } 46 | } 47 | 48 | .embed-responsive-1by1 { 49 | &::before { 50 | padding-top: percentage(1 / 1); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/custom/utilities/_backgrounds.scss: -------------------------------------------------------------------------------- 1 | @each $color, $value in $colors { 2 | @include bg-variant(".bg-#{$color}", $value); 3 | } 4 | 5 | @each $color, $value in $theme-colors { 6 | @include bg-gradient-variant(".bg-gradient-#{$color}", $value); 7 | } 8 | 9 | @each $color, $value in $colors { 10 | @include bg-gradient-variant(".bg-gradient-#{$color}", $value); 11 | } 12 | 13 | 14 | // Sections 15 | 16 | section { 17 | //background-color: section-color("primary"); 18 | } 19 | 20 | @each $color, $value in $section-colors { 21 | @include bg-variant(".section-#{$color}", $value); 22 | } 23 | 24 | @each $color, $value in $theme-colors { 25 | @include bg-gradient-variant(".bg-gradient-#{$color}", $value); 26 | } 27 | 28 | 29 | // Shape (svg) fill colors 30 | @each $color, $value in $theme-colors { 31 | .fill-#{$color} { 32 | fill: $value; 33 | } 34 | 35 | .stroke-#{$color} { 36 | stroke: $value; 37 | } 38 | } 39 | 40 | .fill-opacity-8 { 41 | fill-opacity: .8; 42 | } -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/_progress.scss: -------------------------------------------------------------------------------- 1 | @keyframes progress-bar-stripes { 2 | from { background-position: $progress-height 0; } 3 | to { background-position: 0 0; } 4 | } 5 | 6 | .progress { 7 | display: flex; 8 | height: $progress-height; 9 | overflow: hidden; // force rounded corners by cropping it 10 | font-size: $progress-font-size; 11 | background-color: $progress-bg; 12 | @include border-radius($progress-border-radius); 13 | @include box-shadow($progress-box-shadow); 14 | } 15 | 16 | .progress-bar { 17 | display: flex; 18 | flex-direction: column; 19 | justify-content: center; 20 | color: $progress-bar-color; 21 | text-align: center; 22 | white-space: nowrap; 23 | background-color: $progress-bar-bg; 24 | @include transition($progress-bar-transition); 25 | } 26 | 27 | .progress-bar-striped { 28 | @include gradient-striped(); 29 | background-size: $progress-height $progress-height; 30 | } 31 | 32 | .progress-bar-animated { 33 | animation: progress-bar-stripes $progress-bar-animation-timing; 34 | } 35 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/_close.scss: -------------------------------------------------------------------------------- 1 | .close { 2 | float: right; 3 | font-size: $close-font-size; 4 | font-weight: $close-font-weight; 5 | line-height: 1; 6 | color: $close-color; 7 | text-shadow: $close-text-shadow; 8 | opacity: .5; 9 | 10 | &:not(:disabled):not(.disabled) { 11 | 12 | @include hover-focus { 13 | color: $close-color; 14 | text-decoration: none; 15 | opacity: .75; 16 | } 17 | 18 | // Opinionated: add "hand" cursor to non-disabled .close elements 19 | cursor: pointer; 20 | } 21 | } 22 | 23 | // Additional properties for button version 24 | // iOS requires the button element instead of an anchor tag. 25 | // If you want the anchor version, it requires `href="#"`. 26 | // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile 27 | 28 | // stylelint-disable property-no-vendor-prefix, selector-no-qualifying-type 29 | button.close { 30 | padding: 0; 31 | background-color: transparent; 32 | border: 0; 33 | -webkit-appearance: none; 34 | } 35 | // stylelint-enable 36 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Demo Site 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 |
23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.3' 2 | 3 | services: 4 | db: 5 | image: postgres 6 | container_name: docker-django-vue-db 7 | environment: 8 | POSTGRES_USER: user 9 | POSTGRES_PASSWORD: pass 10 | POSTGRES_DB: db 11 | restart: unless-stopped 12 | ports: 13 | - "5432:5432" 14 | django: 15 | build: 16 | context: . 17 | dockerfile: docker/BackendDockerfile 18 | container_name: docker-django-vue-backend 19 | command: ./docker/backend_setup.sh 20 | environment: 21 | POSTGRES_NAME: postgres 22 | POSTGRES_USER: user 23 | POSTGRES_PASSWORD: pass 24 | POSTGRES_HOST: db 25 | volumes: 26 | - .:/app 27 | ports: 28 | - "8002:8000" 29 | depends_on: 30 | - db 31 | vue: 32 | build: 33 | context: . 34 | dockerfile: docker/FrontendDockerfile 35 | container_name: docker-django-vue-frontend 36 | command: ./docker/frontend_setup.sh 37 | volumes: 38 | - .:/app 39 | ports: 40 | - "8082:8080" 41 | depends_on: 42 | - django -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/custom/utilities/_floating.scss: -------------------------------------------------------------------------------- 1 | .floating { 2 | animation: floating 3s ease infinite; 3 | will-change: transform; 4 | 5 | &:hover { 6 | animation-play-state: paused; 7 | } 8 | } 9 | 10 | .floating-lg { 11 | animation: floating-lg 3s ease infinite; 12 | } 13 | 14 | .floating-sm { 15 | animation: floating-sm 3s ease infinite; 16 | } 17 | 18 | // Keyframes 19 | 20 | @keyframes floating-lg { 21 | 0% { 22 | transform: translateY(0px) 23 | } 24 | 50% { 25 | transform: translateY(15px) 26 | } 27 | 100% { 28 | transform: translateY(0px) 29 | } 30 | } 31 | 32 | @keyframes floating { 33 | 0% { 34 | transform: translateY(0px) 35 | } 36 | 50% { 37 | transform: translateY(10px) 38 | } 39 | 100% { 40 | transform: translateY(0px) 41 | } 42 | } 43 | 44 | @keyframes floating-sm { 45 | 0% { 46 | transform: translateY(0px) 47 | } 48 | 50% { 49 | transform: translateY(5px) 50 | } 51 | 100% { 52 | transform: translateY(0px) 53 | } 54 | } -------------------------------------------------------------------------------- /src/registerServiceWorker.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | 3 | import { register } from 'register-service-worker' 4 | 5 | if (process.env.NODE_ENV === 'production') { 6 | register(`${process.env.BASE_URL}service-worker.js`, { 7 | registrationOptions: { 8 | scope: process.env.BASE_URL, 9 | }, 10 | ready () { 11 | console.log( 12 | 'App is being served from cache by a service worker.\n' + 13 | 'For more details, visit https://goo.gl/AFskqB' 14 | ) 15 | }, 16 | registered () { 17 | console.log('Service worker has been registered.') 18 | }, 19 | cached () { 20 | console.log('Content has been cached for offline use.') 21 | }, 22 | updatefound () { 23 | console.log('New content is downloading.') 24 | }, 25 | updated () { 26 | console.log('New content is available; please refresh.') 27 | }, 28 | offline () { 29 | console.log('No internet connection found. App is running in offline mode.') 30 | }, 31 | error (error) { 32 | console.error('Error during service worker registration:', error) 33 | } 34 | }) 35 | } 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Gui Talarico 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 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/custom/utilities/_helper.scss: -------------------------------------------------------------------------------- 1 | // Image 2 | 3 | .img-center { 4 | display: block; 5 | margin-left: auto; 6 | margin-right: auto; 7 | } 8 | 9 | // Clearfix 10 | 11 | .floatfix { 12 | &:before, 13 | &:after { 14 | content: ''; 15 | display: table; 16 | } 17 | &:after { 18 | clear: both; 19 | } 20 | } 21 | 22 | // Overflows 23 | 24 | .overflow-visible { 25 | overflow: visible !important; 26 | } 27 | .overflow-hidden { 28 | overflow: hidden !important; 29 | } 30 | 31 | // Opacity classes 32 | 33 | .opacity-1 { 34 | opacity: .1 !important; 35 | } 36 | .opacity-2 { 37 | opacity: .2 !important; 38 | } 39 | .opacity-3 { 40 | opacity: .3 !important; 41 | } 42 | .opacity-4 { 43 | opacity: .4 !important; 44 | } 45 | .opacity-5 { 46 | opacity: .5 !important; 47 | } 48 | .opacity-6 { 49 | opacity: .6 !important; 50 | } 51 | .opacity-7 { 52 | opacity: .7 !important; 53 | } 54 | .opacity-8 { 55 | opacity: .8 !important; 56 | } 57 | .opacity-8 { 58 | opacity: .9 !important; 59 | } 60 | .opacity-10 { 61 | opacity: 1 !important; 62 | } -------------------------------------------------------------------------------- /src/assets/demo/demo.css: -------------------------------------------------------------------------------- 1 | .tim-row { 2 | margin-bottom: 20px; 3 | } 4 | 5 | .tim-white-buttons { 6 | background-color: #777777; 7 | } 8 | 9 | .typography-line { 10 | padding-left: 25%; 11 | margin-bottom: 35px; 12 | position: relative; 13 | display: block; 14 | width: 100%; 15 | } 16 | 17 | .typography-line span { 18 | bottom: 10px; 19 | color: #c0c1c2; 20 | display: block; 21 | font-weight: 400; 22 | font-size: 13px; 23 | line-height: 13px; 24 | left: 0; 25 | position: absolute; 26 | width: 260px; 27 | text-transform: none; 28 | } 29 | 30 | .tim-row { 31 | padding-top: 60px; 32 | } 33 | 34 | .tim-row h3 { 35 | margin-top: 0; 36 | } 37 | 38 | .offline-doc .page-header { 39 | display: flex; 40 | align-items: center; 41 | } 42 | 43 | .offline-doc .footer { 44 | position: absolute; 45 | width: 100%; 46 | background: transparent; 47 | bottom: 0; 48 | color: #fff; 49 | z-index: 1; 50 | } 51 | 52 | @media all and (min-width: 992px) { 53 | .sidebar .nav>li.active-pro { 54 | position: absolute; 55 | width: 100%; 56 | bottom: 10px; 57 | } 58 | } 59 | 60 | .card.card-upgrade .card-category { 61 | max-width: 530px; 62 | margin: 0 auto; 63 | } -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/custom/utilities/_text.scss: -------------------------------------------------------------------------------- 1 | // Weight and italics 2 | 3 | .font-weight-300 { font-weight: 300 !important; } 4 | .font-weight-400 { font-weight: 400 !important; } 5 | .font-weight-500 { font-weight: 500 !important; } 6 | .font-weight-600 { font-weight: 600 !important; } 7 | .font-weight-700 { font-weight: 700 !important; } 8 | .font-weight-800 { font-weight: 800 !important; } 9 | .font-weight-900 { font-weight: 900 !important; } 10 | 11 | 12 | // Text decorations 13 | 14 | .text-underline { text-decoration: underline; } 15 | .text-through { text-decoration: line-through; } 16 | 17 | 18 | // Line heights 19 | 20 | .lh-100 { line-height: 1; } 21 | .lh-110 { line-height: 1.1; } 22 | .lh-120 { line-height: 1.2; } 23 | .lh-130 { line-height: 1.3; } 24 | .lh-140 { line-height: 1.4; } 25 | .lh-150 { line-height: 1.5; } 26 | .lh-160 { line-height: 1.6; } 27 | .lh-170 { line-height: 1.7; } 28 | .lh-180 { line-height: 1.8; } 29 | 30 | //Contextual colors 31 | 32 | .text-muted { color: $text-muted !important; } 33 | 34 | 35 | 36 | // Letter spacings 37 | 38 | .ls-1 { letter-spacing: .0625rem; } 39 | .ls-15 { letter-spacing: .09375rem; } 40 | .ls-2 { letter-spacing: 0.125rem; } 41 | -------------------------------------------------------------------------------- /src/plugins/RTLPlugin.js: -------------------------------------------------------------------------------- 1 | export default { 2 | install(Vue) { 3 | let app = new Vue({ 4 | data() { 5 | return { 6 | isRTL: false 7 | } 8 | }, 9 | methods: { 10 | getDocClasses() { 11 | return document.body.classList 12 | }, 13 | enableRTL() { 14 | this.isRTL = true; 15 | this.getDocClasses().add('rtl'); 16 | this.getDocClasses().add('menu-on-right'); 17 | this.toggleBootstrapRTL(true); 18 | }, 19 | disableRTL() { 20 | this.isRTL = false; 21 | this.getDocClasses().remove('rtl'); 22 | this.getDocClasses().remove('menu-on-right'); 23 | this.toggleBootstrapRTL(false); 24 | }, 25 | toggleBootstrapRTL(value) { 26 | for (let i=0; i < document.styleSheets.length; i++){ 27 | let styleSheet = document.styleSheets[i]; 28 | let { href } = styleSheet; 29 | if(href && href.endsWith('bootstrap-rtl.css')){ 30 | styleSheet.disabled = !value; 31 | } 32 | } 33 | } 34 | } 35 | }); 36 | 37 | Vue.prototype.$rtl = app; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Toggles 2 | // 3 | // Used in conjunction with global variables to enable certain theme features. 4 | 5 | // Utilities 6 | @import "mixins/breakpoints"; 7 | @import "mixins/hover"; 8 | @import "mixins/image"; 9 | @import "mixins/badge"; 10 | @import "mixins/resize"; 11 | @import "mixins/screen-reader"; 12 | @import "mixins/size"; 13 | @import "mixins/reset-text"; 14 | @import "mixins/text-emphasis"; 15 | @import "mixins/text-hide"; 16 | @import "mixins/text-truncate"; 17 | @import "mixins/visibility"; 18 | 19 | // // Components 20 | @import "mixins/alert"; 21 | @import "mixins/buttons"; 22 | @import "mixins/caret"; 23 | @import "mixins/pagination"; 24 | @import "mixins/lists"; 25 | @import "mixins/list-group"; 26 | @import "mixins/nav-divider"; 27 | @import "mixins/forms"; 28 | @import "mixins/table-row"; 29 | 30 | // // Skins 31 | @import "mixins/background-variant"; 32 | @import "mixins/border-radius"; 33 | @import "mixins/box-shadow"; 34 | @import "mixins/gradients"; 35 | @import "mixins/transition"; 36 | 37 | // // Layout 38 | @import "mixins/clearfix"; 39 | @import "mixins/grid-framework"; 40 | @import "mixins/grid"; 41 | @import "mixins/float"; 42 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/_code.scss: -------------------------------------------------------------------------------- 1 | // Inline code 2 | code { 3 | font-size: $code-font-size; 4 | color: $code-color; 5 | word-break: break-word; 6 | 7 | // Streamline the style when inside anchors to avoid broken underline and more 8 | a > & { 9 | color: inherit; 10 | } 11 | } 12 | 13 | // User input typically entered via keyboard 14 | kbd { 15 | padding: $kbd-padding-y $kbd-padding-x; 16 | font-size: $kbd-font-size; 17 | color: $kbd-color; 18 | background-color: $kbd-bg; 19 | @include border-radius($border-radius-sm); 20 | @include box-shadow($kbd-box-shadow); 21 | 22 | kbd { 23 | padding: 0; 24 | font-size: 100%; 25 | font-weight: $nested-kbd-font-weight; 26 | @include box-shadow(none); 27 | } 28 | } 29 | 30 | // Blocks of code 31 | pre { 32 | display: block; 33 | font-size: $code-font-size; 34 | color: $pre-color; 35 | 36 | // Account for some code outputs that place code tags in pre tags 37 | code { 38 | font-size: inherit; 39 | color: inherit; 40 | word-break: normal; 41 | } 42 | } 43 | 44 | // Enable scrollable blocks of code 45 | .pre-scrollable { 46 | max-height: $pre-scrollable-max-height; 47 | overflow-y: scroll; 48 | } 49 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/_badge.scss: -------------------------------------------------------------------------------- 1 | // Base class 2 | // 3 | // Requires one of the contextual, color modifier classes for `color` and 4 | // `background-color`. 5 | 6 | .badge { 7 | display: inline-block; 8 | padding: $badge-padding-y $badge-padding-x; 9 | font-size: $badge-font-size; 10 | font-weight: $badge-font-weight; 11 | line-height: 1; 12 | text-align: center; 13 | white-space: nowrap; 14 | vertical-align: baseline; 15 | @include border-radius($badge-border-radius); 16 | 17 | // Empty badges collapse automatically 18 | &:empty { 19 | display: none; 20 | } 21 | } 22 | 23 | // Quick fix for badges in buttons 24 | .btn .badge { 25 | position: relative; 26 | top: -1px; 27 | } 28 | 29 | // Pill badges 30 | // 31 | // Make them extra rounded with a modifier to replace v3's badges. 32 | 33 | .badge-pill { 34 | padding-right: $badge-pill-padding-x; 35 | padding-left: $badge-pill-padding-x; 36 | @include border-radius($badge-pill-border-radius); 37 | } 38 | 39 | // Colors 40 | // 41 | // Contextual variations (linked badges get darker on :hover). 42 | 43 | @each $color, $value in $theme-colors { 44 | .badge-#{$color} { 45 | @include badge-variant($value); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /backend/urls.py: -------------------------------------------------------------------------------- 1 | """project URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/2.1/topics/http/urls/ 5 | """ 6 | from django.contrib import admin 7 | from django.urls import path, include 8 | from django.views.generic import TemplateView 9 | from django.views.decorators.cache import never_cache 10 | 11 | # These paths are for the Vue app - remove if you are not using the vue frontend, and create your custom views. 12 | urlpatterns = [ 13 | # http://localhost:8000/ 14 | path('', never_cache(TemplateView.as_view( 15 | template_name='index.html')), name='index'), 16 | path('app.js', never_cache(TemplateView.as_view( 17 | template_name='app.js')), name='appjs'), 18 | ] 19 | ### 20 | 21 | # These paths are for the api endpoints and admin interface. 22 | urlpatterns += [ 23 | # http://localhost:8000/api/ 24 | path('api/v1.0/', include('backend.api.urls')), 25 | 26 | # http://localhost:8000/admin/ 27 | path('admin/', admin.site.urls), 28 | ] 29 | ### 30 | 31 | 32 | # Matches everything else, probably a Vue route? 33 | # urlpatterns += [ 34 | # re_path(r'(?P)$', index_view, name='index-for-SPA'), 35 | # ] 36 | -------------------------------------------------------------------------------- /src/constants/index.js: -------------------------------------------------------------------------------- 1 | /* This variable is controlled by gulp. You can run gulp with flag -e to set this variable. 2 | Example: gulp dev-cis -e qa 3 | Possible values for flag -e are: 'docker', 'local', 'prod', 'qa', 'dev' (default). */ 4 | var env = 'docker'; 5 | 6 | /************************************ 7 | * ENV URLS 8 | ************************************/ 9 | let ENV_URLS = {} 10 | 11 | if (env == "local") { 12 | ENV_URLS = { 13 | "api": "http://localhost:8000/api/v1.0/", 14 | // "apiv2": "http://localhost:8000/api/v2.0/" 15 | } 16 | } else if (env == "docker") { 17 | ENV_URLS = { 18 | "api": "http://localhost:8002/api/v1.0/", 19 | } 20 | } 21 | else if (env == "production" || env == "staging") { 22 | alert("No URLs set for for production or staging") 23 | } 24 | else { 25 | alert("NO ENV SET!") 26 | console.error("No env set! Using localhost for dev server."); 27 | ENV_URLS = { 28 | "api": "https://localhost:8000/api/v1.0/", 29 | } 30 | } 31 | 32 | export const URLS = ENV_URLS 33 | 34 | /************************************ 35 | * TODO: UPDATE ALL LOCAL DATA STRINGS 36 | ************************************/ 37 | export const LOCAL = { 38 | userAuthData: "userAuthData" 39 | }; 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/_grid.scss: -------------------------------------------------------------------------------- 1 | // Container widths 2 | // 3 | // Set the container width, and override it for fixed navbars in media queries. 4 | 5 | @if $enable-grid-classes { 6 | .container { 7 | @include make-container(); 8 | @include make-container-max-widths(); 9 | } 10 | } 11 | 12 | // Fluid container 13 | // 14 | // Utilizes the mixin meant for fixed width containers, but with 100% width for 15 | // fluid, full width layouts. 16 | 17 | @if $enable-grid-classes { 18 | .container-fluid { 19 | @include make-container(); 20 | } 21 | } 22 | 23 | // Row 24 | // 25 | // Rows contain and clear the floats of your columns. 26 | 27 | @if $enable-grid-classes { 28 | .row { 29 | @include make-row(); 30 | } 31 | 32 | // Remove the negative margin from default .row, then the horizontal padding 33 | // from all immediate children columns (to prevent runaway style inheritance). 34 | .no-gutters { 35 | margin-right: 0; 36 | margin-left: 0; 37 | 38 | > .col, 39 | > [class*="col-"] { 40 | padding-right: 0; 41 | padding-left: 0; 42 | } 43 | } 44 | } 45 | 46 | // Columns 47 | // 48 | // Common styles for small and large grid columns 49 | 50 | @if $enable-grid-classes { 51 | @include make-grid-columns(); 52 | } 53 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/custom/cards/_card-chart.scss: -------------------------------------------------------------------------------- 1 | .card-chart { 2 | overflow: hidden; 3 | .card-header{ 4 | .card-title{ 5 | i{ 6 | font-size: 16px; 7 | margin-right: 5px; 8 | margin-bottom: 3px; 9 | } 10 | } 11 | .card-category{ 12 | margin-bottom: 5px; 13 | } 14 | } 15 | .card-body{ 16 | padding-left: 5px; 17 | padding-right: 5px; 18 | .tab-space{ 19 | padding: 0; 20 | } 21 | } 22 | .table{ 23 | margin-bottom: 0; 24 | 25 | td{ 26 | border-top: none; 27 | border-bottom: 1px solid rgba($white,0.1); 28 | } 29 | } 30 | 31 | .card-progress { 32 | margin-top: 30px; 33 | padding: 0 10px; 34 | } 35 | 36 | .chart-area { 37 | height: 220px; 38 | width: 100%; 39 | } 40 | .card-footer { 41 | margin-top: 15px; 42 | 43 | .stats{ 44 | color: $dark-gray; 45 | } 46 | } 47 | 48 | .dropdown{ 49 | position: absolute; 50 | right: 20px; 51 | top: 20px; 52 | 53 | .btn{ 54 | margin: 0; 55 | } 56 | } 57 | 58 | &.card-chart-pie{ 59 | .chart-area{ 60 | padding: 10px 0 25px; 61 | height: auto; 62 | } 63 | 64 | .card-title{ 65 | margin-bottom: 10px; 66 | i{ 67 | font-size: 1rem; 68 | } 69 | } 70 | 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/_images.scss: -------------------------------------------------------------------------------- 1 | // Responsive images (ensure images don't scale beyond their parents) 2 | // 3 | // This is purposefully opt-in via an explicit class rather than being the default for all ``s. 4 | // We previously tried the "images are responsive by default" approach in Bootstrap v2, 5 | // and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps) 6 | // which weren't expecting the images within themselves to be involuntarily resized. 7 | // See also https://github.com/twbs/bootstrap/issues/18178 8 | .img-fluid { 9 | @include img-fluid; 10 | } 11 | 12 | 13 | // Image thumbnails 14 | .img-thumbnail { 15 | padding: $thumbnail-padding; 16 | background-color: $thumbnail-bg; 17 | border: $thumbnail-border-width solid $thumbnail-border-color; 18 | @include border-radius($thumbnail-border-radius); 19 | @include box-shadow($thumbnail-box-shadow); 20 | 21 | // Keep them at most 100% wide 22 | @include img-fluid; 23 | } 24 | 25 | // 26 | // Figures 27 | // 28 | 29 | .figure { 30 | // Ensures the caption's text aligns with the image. 31 | display: inline-block; 32 | } 33 | 34 | .figure-img { 35 | margin-bottom: ($spacer / 2); 36 | line-height: 1; 37 | } 38 | 39 | .figure-caption { 40 | font-size: $figure-caption-font-size; 41 | color: $figure-caption-color; 42 | } 43 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/mixins/_image.scss: -------------------------------------------------------------------------------- 1 | // Image Mixins 2 | // - Responsive image 3 | // - Retina image 4 | 5 | 6 | // Responsive image 7 | // 8 | // Keep images from scaling beyond the width of their parents. 9 | 10 | @mixin img-fluid { 11 | // Part 1: Set a maximum relative to the parent 12 | max-width: 100%; 13 | // Part 2: Override the height to auto, otherwise images will be stretched 14 | // when setting a width and height attribute on the img element. 15 | height: auto; 16 | } 17 | 18 | 19 | // Retina image 20 | // 21 | // Short retina mixin for setting background-image and -size. 22 | 23 | // stylelint-disable indentation, media-query-list-comma-newline-after 24 | @mixin img-retina($file-1x, $file-2x, $width-1x, $height-1x) { 25 | background-image: url($file-1x); 26 | 27 | // Autoprefixer takes care of adding -webkit-min-device-pixel-ratio and -o-min-device-pixel-ratio, 28 | // but doesn't convert dppx=>dpi. 29 | // There's no such thing as unprefixed min-device-pixel-ratio since it's nonstandard. 30 | // Compatibility info: https://caniuse.com/#feat=css-media-resolution 31 | @media only screen and (min-resolution: 192dpi), // IE9-11 don't support dppx 32 | only screen and (min-resolution: 2dppx) { // Standardized 33 | background-image: url($file-2x); 34 | background-size: $width-1x $height-1x; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/pages/Profile/UserCard.vue: -------------------------------------------------------------------------------- 1 | 35 | 47 | 49 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/_alert.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Base styles 3 | // 4 | 5 | .alert { 6 | position: relative; 7 | padding: $alert-padding-y $alert-padding-x; 8 | margin-bottom: $alert-margin-bottom; 9 | border: $alert-border-width solid transparent; 10 | @include border-radius($alert-border-radius); 11 | } 12 | 13 | // Headings for larger alerts 14 | .alert-heading { 15 | // Specified to prevent conflicts of changing $headings-color 16 | color: inherit; 17 | } 18 | 19 | // Provide class for links that match alerts 20 | .alert-link { 21 | font-weight: $alert-link-font-weight; 22 | } 23 | 24 | 25 | // Dismissible alerts 26 | // 27 | // Expand the right padding and account for the close button's positioning. 28 | 29 | .alert-dismissible { 30 | padding-right: ($close-font-size + $alert-padding-x * 2); 31 | 32 | // Adjust close link position 33 | .close { 34 | position: absolute; 35 | top: 0; 36 | right: 0; 37 | padding: $alert-padding-y $alert-padding-x; 38 | color: inherit; 39 | } 40 | } 41 | 42 | 43 | // Alternate styles 44 | // 45 | // Generate contextual modifier classes for colorizing the alert. 46 | 47 | @each $color, $value in $theme-colors { 48 | .alert-#{$color} { 49 | @include alert-variant(theme-color-level($color, $alert-bg-level), theme-color-level($color, $alert-border-level), theme-color-level($color, $alert-color-level)); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/pages/Profile.vue: -------------------------------------------------------------------------------- 1 | 12 | 42 | 44 | -------------------------------------------------------------------------------- /backend/users/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.contrib.auth.models import AbstractUser 3 | 4 | class User(AbstractUser): 5 | SEX_CHOICE = ( 6 | ('m', 'Male'), 7 | ('f', 'Female'), 8 | ('o', 'Other'), 9 | ) 10 | 11 | STATUS_CHOICE = ( 12 | ('a', 'Active'), 13 | ('i', 'Inactive'), 14 | ('t', 'Terminated') 15 | ) 16 | 17 | email = models.EmailField(unique=True) 18 | first_name = models.CharField(max_length=40, blank=True) 19 | last_name = models.CharField(max_length=40, blank=True) 20 | address = models.CharField(max_length=255, blank=True) 21 | sex = models.CharField(max_length=1, choices=SEX_CHOICE, blank=True, null=True) 22 | age = models.DateField(null=True, blank=True) 23 | terms_agreement = models.BooleanField(default=True, blank=True) 24 | verified = models.BooleanField(default=False) 25 | status = models.CharField(max_length=1, choices=STATUS_CHOICE, 26 | default=STATUS_CHOICE[0][0], blank=True) 27 | created_at = models.DateTimeField(auto_now_add=True) 28 | updated_at = models.DateTimeField(auto_now=True) 29 | 30 | def __unicode__(self): 31 | return self.email 32 | 33 | def get_all_expenses(self): 34 | return None 35 | 36 | def get_all_entries(self): 37 | return None 38 | 39 | class Meta: 40 | db_table = 'users' 41 | -------------------------------------------------------------------------------- /src/components/SidebarPlugin/SidebarLink.vue: -------------------------------------------------------------------------------- 1 | 15 | 63 | 65 | -------------------------------------------------------------------------------- /src/assets/sass/black-dashboard/bootstrap/_breadcrumb.scss: -------------------------------------------------------------------------------- 1 | .breadcrumb { 2 | display: flex; 3 | flex-wrap: wrap; 4 | padding: $breadcrumb-padding-y $breadcrumb-padding-x; 5 | margin-bottom: $breadcrumb-margin-bottom; 6 | list-style: none; 7 | background-color: $breadcrumb-bg; 8 | @include border-radius($breadcrumb-border-radius); 9 | } 10 | 11 | .breadcrumb-item { 12 | // The separator between breadcrumbs (by default, a forward-slash: "/") 13 | + .breadcrumb-item { 14 | padding-left: $breadcrumb-item-padding; 15 | 16 | &::before { 17 | display: inline-block; // Suppress underlining of the separator in modern browsers 18 | padding-right: $breadcrumb-item-padding; 19 | color: $breadcrumb-divider-color; 20 | content: $breadcrumb-divider; 21 | } 22 | } 23 | 24 | // IE9-11 hack to properly handle hyperlink underlines for breadcrumbs built 25 | // without `