From 64b4437acd77fda03c6ced53e0d7142c696a2640 Mon Sep 17 00:00:00 2001 From: realaravinth Date: Fri, 17 Jun 2022 16:03:13 +0530 Subject: [PATCH] feat: bootstrap dashboard templates and dashboard homepage view --- dash/__init__.py | 0 dash/admin.py | 3 + dash/apps.py | 6 ++ dash/migrations/__init__.py | 0 dash/models.py | 3 + dash/templates/dash/common/base.html | 22 ++++++ .../dash/common/components/primary-nav.html | 36 ++++++++++ .../dash/common/components/secondary-nav.html | 15 ++++ dash/templates/dash/home/index.html | 6 ++ dash/tests.py | 71 +++++++++++++++++++ dash/urls.py | 24 +++++++ dash/views.py | 36 ++++++++++ static/css/main.css | 56 +++++++++++++++ 13 files changed, 278 insertions(+) create mode 100644 dash/__init__.py create mode 100644 dash/admin.py create mode 100644 dash/apps.py create mode 100644 dash/migrations/__init__.py create mode 100644 dash/models.py create mode 100644 dash/templates/dash/common/base.html create mode 100644 dash/templates/dash/common/components/primary-nav.html create mode 100644 dash/templates/dash/common/components/secondary-nav.html create mode 100644 dash/templates/dash/home/index.html create mode 100644 dash/tests.py create mode 100644 dash/urls.py create mode 100644 dash/views.py diff --git a/dash/__init__.py b/dash/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dash/admin.py b/dash/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/dash/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/dash/apps.py b/dash/apps.py new file mode 100644 index 0000000..51fd062 --- /dev/null +++ b/dash/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class DashConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'dash' diff --git a/dash/migrations/__init__.py b/dash/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dash/models.py b/dash/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/dash/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/dash/templates/dash/common/base.html b/dash/templates/dash/common/base.html new file mode 100644 index 0000000..4e13853 --- /dev/null +++ b/dash/templates/dash/common/base.html @@ -0,0 +1,22 @@ + +{% load static %} + + + + + {{ title }}| Hostea Dashbaord + {% include "common/components/meta.html" %} + + +
+ {% include "dash/common/components/primary-nav.html" %} +
+
+ {% include "dash/common/components/secondary-nav.html" %} +
+ {% block dash %} {% endblock %} + {% include "common/components/footer.html" %} +
+
+ + diff --git a/dash/templates/dash/common/components/primary-nav.html b/dash/templates/dash/common/components/primary-nav.html new file mode 100644 index 0000000..c43a801 --- /dev/null +++ b/dash/templates/dash/common/components/primary-nav.html @@ -0,0 +1,36 @@ +{% load static %} + diff --git a/dash/templates/dash/common/components/secondary-nav.html b/dash/templates/dash/common/components/secondary-nav.html new file mode 100644 index 0000000..274868a --- /dev/null +++ b/dash/templates/dash/common/components/secondary-nav.html @@ -0,0 +1,15 @@ + diff --git a/dash/templates/dash/home/index.html b/dash/templates/dash/home/index.html new file mode 100644 index 0000000..ce6446f --- /dev/null +++ b/dash/templates/dash/home/index.html @@ -0,0 +1,6 @@ +{% extends 'dash/common/base.html' %} +{% block dash %} +{% include "common/components/error.html" %} +

{{ title }}

+ {% include "common/components/error.html" %} +{% endblock %} diff --git a/dash/tests.py b/dash/tests.py new file mode 100644 index 0000000..ab7e5ef --- /dev/null +++ b/dash/tests.py @@ -0,0 +1,71 @@ +# Copyright © 2022 Aravinth Manivannan +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +from django.contrib.auth import get_user_model +from django.utils.http import urlencode +from django.urls import reverse +from django.test import TestCase, Client, override_settings +from django.contrib.auth import authenticate +from django.conf import settings + +class DashHome(TestCase): + """ + Tests create new app view + """ + + def setUp(self): + self.password = "password121231" + self.username = "dashboard_home_user" + self.email = f"{self.username}@example.org" + self.user = get_user_model().objects.create( + username=self.username, + email=self.email, + ) + self.user.set_password(self.password) + self.user.save() + + def test_dash_is_protected(self): + """ + Tests if dashboard template renders + """ + resp = self.client.get(reverse("dash.home")) + self.assertEqual(resp.status_code, 302) + + # default LOGIN redirect URI that is used by @login_required decorator is + # /accounts/login. There's a redirection endpoint at /accounts/login/ that + # will redirect user to /login. Hence the /accounts prefix + redirect_login_uri = f"/accounts{reverse('accounts.login')}?next={reverse('dash.home')}" + self.assertEqual(resp.headers["location"], redirect_login_uri) + + def test_dash_home_renders(self): + """ + Tests if login template renders + """ + c = Client() + + # username login works + payload = { + "login": self.username, + "password": self.password, + } + resp = c.post(reverse("accounts.login"), payload) + self.assertEqual(resp.status_code, 302) + self.assertEqual(resp.headers["location"], reverse("accounts.home")) + + # email login works + resp = c.get(reverse('dash.home')) + self.assertEqual(resp.status_code, 200) + self.assertEqual(b"Billing" in resp.content, True) + self.assertEqual(b"Support" in resp.content, True) + self.assertEqual(b"Logout" in resp.content, True) diff --git a/dash/urls.py b/dash/urls.py new file mode 100644 index 0000000..80bcfa8 --- /dev/null +++ b/dash/urls.py @@ -0,0 +1,24 @@ +# Copyright © 2022 Aravinth Manivannan +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +from django.contrib import admin +from django.urls import path, include + +from .views import ( + home +) + +urlpatterns = [ + path("", home, name="dash.home"), +] diff --git a/dash/views.py b/dash/views.py new file mode 100644 index 0000000..9f7c17c --- /dev/null +++ b/dash/views.py @@ -0,0 +1,36 @@ +# Copyright © 2022 Aravinth Manivannan +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +from django.shortcuts import render, redirect, get_object_or_404 +from django.utils.http import urlencode +from django.contrib.auth import authenticate, login, logout +from django.contrib.auth import get_user_model +from django.contrib.auth.decorators import login_required +from django.http import HttpResponse +from django.views.decorators.csrf import csrf_protect +from django.urls import reverse + +def default_ctx(title: str): + return { + "title": title, + } + + + +@login_required +def home(request): + PAGE_TITLE = "Home" + ctx = default_ctx(title=PAGE_TITLE) + + return render(request, "dash/home/index.html", context=ctx) diff --git a/static/css/main.css b/static/css/main.css index d5914c4..755d654 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -34,9 +34,11 @@ h2 { body { width: 100%; min-height: 100vh; + /* display: flex; flex-direction: column; justify-content: space-between; + */ } a:hover { @@ -99,6 +101,7 @@ header { width: 100%; padding-top: 5px; border-bottom: 1px solid rgb(211, 211, 211); + height: 63px; } .nav__home-btn { @@ -469,3 +472,56 @@ footer { } /* footer ends */ + +/* dashbaord starts */ + +.panel__container { +/* background-color: green; */ +} + +/* secondary nav starts */ +.secondary-nav__container { + box-sizing: border-box; + overflow-x: auto; + flex: 1; + position: fixed; + top: 63px; + bottom: 0; + z-index: 1000; + width: 260px; + border-right: 1px solid rgb(217, 217, 217); +} + +.secondary-nav { + width: 100%; + height: 100%; + position: relative; + box-sizing: border-box; +} + + +.secondary-nav__options { + display: flex; + flex-direction: column; + border-bottom: 1px solid rgb(217, 217, 217); +} + +.secondary-nav__option-link { + padding: 20px 0 20px 20px; +} + +.secondary-nav__option-link:hover { + background-color: lightslategray; +} + +/* secondary nav ends */ + +.dash__main { + flex: 2; + display: flex; + flex-direction: column; + justify-content: space-between; + min-height: calc(-63px + 100vh); +} + +/* dashbaord ends */