.onrender.com/api/`
9 |
10 | ## [1.0.3] 2022-10-03
11 | ### Improvements
12 |
13 | - Fix Docker Scripts
14 |
15 | ## [1.0.2] 2022-06-07
16 | ### Improvements
17 |
18 | - Update Docker Scripts
19 | - App served now by Gunicorn
20 | - Update Dependencies
21 |
22 | ## [1.0.1] 2022-01-28
23 | ### Improvements
24 |
25 | - Dependencies update (all packages)
26 | - `Django==4.0.1`
27 |
28 | ## [1.0.0] 2021-07-20
29 | ### First stable version
30 |
31 | > Features:
32 |
33 | - API:
34 | - Sign UP: `/api/users/register`
35 | - Sign IN: `/api/users/login`
36 | - Logout: `/api/users/logout`
37 | - Check Session: `/api/users/checkSession`
38 | - Edit User: `/api/users/edit`
39 | - Docker
40 |
--------------------------------------------------------------------------------
/react-ui/src/components/Charts/BarChart.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import Card from "components/Card/Card";
3 | import Chart from "react-apexcharts";
4 | import { barChartData, barChartOptions } from "variables/charts";
5 |
6 | class BarChart extends Component {
7 | constructor(props) {
8 | super(props);
9 | this.state = {
10 | chartData: [],
11 | chartOptions: {},
12 | };
13 | }
14 |
15 | componentDidMount() {
16 | this.setState({
17 | chartData: barChartData,
18 | chartOptions: barChartOptions,
19 | });
20 | }
21 |
22 | render() {
23 | return (
24 |
31 |
38 |
39 | );
40 | }
41 | }
42 |
43 | export default BarChart;
44 |
--------------------------------------------------------------------------------
/react-ui/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | ## [v1.0.7] 2022-12-03
4 | ### Changes
5 |
6 | - UI/UX Changes
7 | - Minor Fixes
8 |
9 | ## [v1.0.6] 2022-12-03
10 | ### Changes
11 |
12 | - Bump UI: `v2.0.3`
13 | - Updates for [LIVE Deployer](https://appseed.us/go-live/)
14 |
15 | ## [v1.0.5] 2022-11-08
16 | ### Improvements
17 |
18 | - Save Compat matrix in `package.json`
19 | - `build` node
20 | - Yarn, NPM
21 | - NodeJS versions
22 |
23 | ## [1.0.4] 2022-11-05
24 | ### Improvements
25 |
26 | - Added `env.sample`
27 | - `API_URL` can be specified in `env` (optional)
28 | - data used in `src/config.js`
29 | - Added `compatibility matrix` for Node, yarn & NPM
30 | - Testing tool: [Render API Wrapper](https://github.com/app-generator/deploy-automation-render)
31 |
32 | ## [1.0.3] 2021-11-16
33 | ### Improvements
34 |
35 | - Added Docker Support
36 | - Fixes:
37 | - Logout over Flask API Server
38 |
39 | ## [1.0.2] 2021-10-13
40 | ### Improvements
41 |
42 | - Added Usable JWT Authentication Flow
43 | - Login/Logout/Register
44 |
45 | ## [1.0.1] 2021-10-09
46 | ### Initial Import
47 |
48 | - Added RTL Page
49 | - Bug Fixing
50 | - Added Chakra UI - Base Framework
51 |
--------------------------------------------------------------------------------
/api-server-django/api/user/tests.py:
--------------------------------------------------------------------------------
1 | from django.urls import reverse
2 | from rest_framework.test import APITestCase
3 | from rest_framework import status
4 |
5 |
6 | class UserViewSetTest(APITestCase):
7 | base_edit_url = reverse("api:user-edit-list")
8 | base_url_login = reverse("api:login-list")
9 |
10 | data_login = {"password": "12345678", "email": "teast@admin.com"}
11 |
12 | def test_edit(self):
13 |
14 | # Login to retrieve token
15 |
16 | response = self.client.post(f"{self.base_url_login}", data=self.data_login)
17 | response_data = response.json()
18 |
19 | token = response_data["token"]
20 | user_id = response_data["user"]["_id"]
21 |
22 | self.client.credentials(HTTP_AUTHORIZATION=token)
23 |
24 | # Edit user
25 |
26 | data = {
27 | "email": "new@admin.com",
28 | "userID": user_id,
29 | }
30 |
31 | response = self.client.post(f"{self.base_edit_url}", data=data)
32 | self.assertEqual(response.status_code, status.HTTP_200_OK)
33 |
34 | response_data = response.json()
35 |
36 | self.assertEqual(response_data["success"], True)
37 |
--------------------------------------------------------------------------------
/react-ui/src/views/Dashboard/Dashboard/components/ChartStatistics.js:
--------------------------------------------------------------------------------
1 | import { Flex, Progress, Text, useColorModeValue } from "@chakra-ui/react";
2 | import IconBox from "components/Icons/IconBox";
3 | import React from "react";
4 |
5 | const ChartStatistics = ({ title, amount, icon, percentage }) => {
6 | const iconTeal = useColorModeValue("teal.300", "teal.300");
7 | const iconBoxInside = useColorModeValue("white", "white");
8 | const textColor = useColorModeValue("gray.700", "white");
9 | const overlayRef = React.useRef();
10 | return (
11 |
12 |
13 |
14 | {icon}
15 |
16 |
17 | {title}
18 |
19 |
20 |
21 | {amount}
22 |
23 |
29 |
30 | );
31 | };
32 |
33 | export default ChartStatistics;
34 |
--------------------------------------------------------------------------------
/react-ui/src/assets/svg/jira-logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/react-ui/src/components/Menu/ItemContent.js:
--------------------------------------------------------------------------------
1 | // chakra imports
2 | import { Avatar, Flex, Text, useColorModeValue } from "@chakra-ui/react";
3 | import { ClockIcon } from "components/Icons/Icons";
4 | import PropTypes from "prop-types";
5 | import React from "react";
6 |
7 | export function ItemContent(props) {
8 | const navbarIcon = useColorModeValue("gray.500", "gray.200");
9 | const notificationColor = useColorModeValue("gray.700", "white");
10 | const spacing = " ";
11 | return (
12 | <>
13 |
19 |
20 |
21 |
22 | {props.boldInfo}
23 | {spacing}
24 |
25 | {props.info}
26 |
27 |
28 |
29 |
30 | {props.time}
31 |
32 |
33 |
34 | >
35 | );
36 | }
37 |
--------------------------------------------------------------------------------
/react-ui/src/assets/svg/invision-logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/react-ui/src/assets/svg/visa.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/api-server-django/api/authentication/serializers/register.py:
--------------------------------------------------------------------------------
1 | from rest_framework import serializers
2 | from rest_framework.exceptions import ValidationError
3 | from django.core.exceptions import ObjectDoesNotExist
4 | from api.user.models import User
5 |
6 |
7 | class RegisterSerializer(serializers.ModelSerializer):
8 | password = serializers.CharField(min_length=4, max_length=128, write_only=True)
9 | username = serializers.CharField(max_length=255, required=True)
10 | email = serializers.EmailField(required=True)
11 |
12 | class Meta:
13 | model = User
14 | fields = ["id", "username", "password", "email", "is_active", "date"]
15 |
16 | def validate_username(self, value):
17 | try:
18 | User.objects.get(username=value)
19 | except ObjectDoesNotExist:
20 | return value
21 | raise ValidationError({"success": False, "msg": "Username already taken."})
22 |
23 | def validate_email(self, value):
24 | try:
25 | User.objects.get(email=value)
26 | except ObjectDoesNotExist:
27 | return value
28 | raise ValidationError({"success": False, "msg": "Email already taken."})
29 |
30 | def create(self, validated_data):
31 |
32 | return User.objects.create_user(**validated_data)
33 |
--------------------------------------------------------------------------------
/react-ui/src/views/Dashboard/Dashboard/components/SalesOverview.js:
--------------------------------------------------------------------------------
1 | // Chakra imports
2 | import { Box, Flex, Text, useColorModeValue } from "@chakra-ui/react";
3 | // Custom components
4 | import Card from "components/Card/Card.js";
5 | import CardHeader from "components/Card/CardHeader.js";
6 | import React from "react";
7 |
8 | const SalesOverview = ({ title, percentage, chart }) => {
9 | const textColor = useColorModeValue("gray.700", "white");
10 | return (
11 |
12 |
13 |
14 |
15 | {title}
16 |
17 |
18 | 0 ? "green.400" : "red.400"}
21 | fontWeight='bold'>
22 | {`${percentage}%`} more
23 | {" "}
24 | in 2021
25 |
26 |
27 |
28 |
29 | {chart}
30 |
31 |
32 | );
33 | };
34 |
35 | export default SalesOverview;
36 |
--------------------------------------------------------------------------------
/api-server-django/LICENSE.md:
--------------------------------------------------------------------------------
1 | # MIT License
2 |
3 | Copyright (c) 2019 - present [AppSeed](http://appseed.us/)
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 |
23 |
24 |
25 | ---
26 | For more information regarding licensing, contact the AppSeed Service < *support@appseed.us* >
--------------------------------------------------------------------------------
/react-ui/src/components/Tables/InvoicesRow.js:
--------------------------------------------------------------------------------
1 | import {
2 | Box,
3 | Button,
4 | Flex,
5 | Icon,
6 | Spacer,
7 | Text,
8 | useColorModeValue,
9 | } from "@chakra-ui/react";
10 | import React from "react";
11 |
12 | function InvoicesRow(props) {
13 | const textColor = useColorModeValue("gray.700", "white");
14 | const { date, code, price, format, logo } = props;
15 |
16 | return (
17 |
18 |
19 |
20 | {date}
21 |
22 |
23 | {code}
24 |
25 |
26 |
27 |
28 |
29 | {price}
30 |
31 |
32 |
40 |
41 | );
42 | }
43 |
44 | export default InvoicesRow;
45 |
--------------------------------------------------------------------------------
/api-server-django/api/authentication/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.5 on 2021-07-15 11:29
2 |
3 | from django.conf import settings
4 | from django.db import migrations, models
5 | import django.db.models.deletion
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | initial = True
11 |
12 | dependencies = [
13 | migrations.swappable_dependency(settings.AUTH_USER_MODEL),
14 | ]
15 |
16 | operations = [
17 | migrations.CreateModel(
18 | name="ActiveSession",
19 | fields=[
20 | (
21 | "id",
22 | models.BigAutoField(
23 | auto_created=True,
24 | primary_key=True,
25 | serialize=False,
26 | verbose_name="ID",
27 | ),
28 | ),
29 | ("token", models.CharField(max_length=255)),
30 | ("date", models.DateTimeField(auto_now_add=True)),
31 | (
32 | "user",
33 | models.ForeignKey(
34 | on_delete=django.db.models.deletion.CASCADE,
35 | to=settings.AUTH_USER_MODEL,
36 | ),
37 | ),
38 | ],
39 | ),
40 | ]
41 |
--------------------------------------------------------------------------------
/react-ui/src/assets/svg/slack-logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/react-ui/src/views/Dashboard/Billing/components/BillingInformation.js:
--------------------------------------------------------------------------------
1 | // Chakra imports
2 | import { Flex, Text, useColorModeValue } from "@chakra-ui/react";
3 | // Custom components
4 | import Card from "components/Card/Card.js";
5 | import CardBody from "components/Card/CardBody.js";
6 | import CardHeader from "components/Card/CardHeader.js";
7 | import BillingRow from "components/Tables/BillingRow";
8 | import React from "react";
9 |
10 | const BillingInformation = ({ title, data }) => {
11 | const textColor = useColorModeValue("gray.700", "white");
12 | return (
13 |
14 |
15 |
16 |
17 | {title}
18 |
19 |
20 |
21 |
22 | {data.map((row) => {
23 | return (
24 |
30 | );
31 | })}
32 |
33 |
34 |
35 |
36 | );
37 | };
38 |
39 | export default BillingInformation;
40 |
--------------------------------------------------------------------------------
/react-ui/src/theme/theme.js:
--------------------------------------------------------------------------------
1 | import { extendTheme } from '@chakra-ui/react';
2 | import { globalStyles } from './styles';
3 | import { breakpoints } from './foundations/breakpoints';
4 | import { buttonStyles } from './components/button';
5 | import { badgeStyles } from './components/badge';
6 | import { linkStyles } from './components/link';
7 | import { drawerStyles } from './components/drawer';
8 | import { CardComponent } from './additions/card/Card';
9 | import { CardBodyComponent } from './additions/card/CardBody';
10 | import { CardHeaderComponent } from './additions/card/CardHeader';
11 | import { MainPanelComponent } from './additions/layout/MainPanel';
12 | import { PanelContentComponent } from './additions/layout/PanelContent';
13 | import { PanelContainerComponent } from './additions/layout/PanelContainer';
14 | // import { mode } from "@chakra-ui/theme-tools";
15 | export default extendTheme(
16 | { breakpoints }, // Breakpoints
17 | globalStyles,
18 | buttonStyles, // Button styles
19 | badgeStyles, // Badge styles
20 | linkStyles, // Link styles
21 | drawerStyles, // Sidebar variant for Chakra's drawer
22 | CardComponent, // Card component
23 | CardBodyComponent, // Card Body component
24 | CardHeaderComponent, // Card Header component
25 | MainPanelComponent, // Main Panel component
26 | PanelContentComponent, // Panel Content component
27 | PanelContainerComponent // Panel Container component
28 | );
29 |
--------------------------------------------------------------------------------
/react-ui/src/components/Tables/TimelineRow.js:
--------------------------------------------------------------------------------
1 | import { Box, Flex, Icon, Text, useColorModeValue } from "@chakra-ui/react";
2 | import React from "react";
3 |
4 | function TimelineRow(props) {
5 | const { logo, title, date, color, index, arrLength } = props;
6 | const textColor = useColorModeValue("gray.700", "white.300");
7 | const bgIconColor = useColorModeValue("white.300", "gray.700");
8 |
9 | return (
10 |
11 |
12 |
24 |
29 |
30 |
31 |
32 | {title}
33 |
34 |
35 | {date}
36 |
37 |
38 |
39 | );
40 | }
41 |
42 | export default TimelineRow;
43 |
--------------------------------------------------------------------------------
/react-ui/src/components/FixedPlugin/FixedPlugin.js:
--------------------------------------------------------------------------------
1 | // Chakra Imports
2 | import { Button, useColorModeValue } from "@chakra-ui/react";
3 | // Custom Icons
4 | import { SettingsIcon } from "components/Icons/Icons";
5 | import PropTypes from "prop-types";
6 | import React from "react";
7 |
8 | export default function FixedPlugin(props) {
9 | const { secondary, onChange, onSwitch, fixed, ...rest } = props;
10 | // Chakra Color Mode
11 | let navbarIcon = useColorModeValue("gray.500", "gray.200");
12 | let bgButton = useColorModeValue("white", "gray.600");
13 | let fixedDisplay = "flex";
14 | if (props.secondary) {
15 | fixedDisplay = "none";
16 | }
17 |
18 | const settingsRef = React.useRef();
19 | return (
20 | <>
21 |
42 | >
43 | );
44 | }
45 |
46 | FixedPlugin.propTypes = {
47 | fixed: PropTypes.bool,
48 | onChange: PropTypes.func,
49 | onSwitch: PropTypes.func,
50 | };
51 |
--------------------------------------------------------------------------------
/react-ui/src/index.js:
--------------------------------------------------------------------------------
1 | /*!
2 |
3 | =========================================================
4 | * Purity UI Dashboard - v1.0.1
5 | =========================================================
6 |
7 | * Product Page: https://www.creative-tim.com/product/purity-ui-dashboard
8 | * Copyright 2021 Creative Tim (https://www.creative-tim.com)
9 | * Licensed under MIT (https://github.com/creativetimofficial/purity-ui-dashboard/blob/master/LICENSE.md)
10 |
11 | * Design by Creative Tim & Coded by Simmmple
12 |
13 | =========================================================
14 |
15 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
16 |
17 | */
18 | import React from "react";
19 | import ReactDOM from "react-dom";
20 | import { HashRouter, Route, Switch, Redirect } from "react-router-dom";
21 |
22 | import { AuthProvider } from "./auth-context/auth.context";
23 |
24 | import AuthLayout from "layouts/Auth.js";
25 | import AdminLayout from "layouts/Admin.js";
26 | import RTLLayout from "layouts/RTL.js";
27 |
28 | let user = localStorage.getItem("user");
29 | user = JSON.parse(user);
30 |
31 | ReactDOM.render(
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | ,
42 | document.getElementById("root")
43 | );
44 |
--------------------------------------------------------------------------------
/react-ui/src/components/Navbars/SearchBar/SearchBar.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import {
3 | IconButton,
4 | Input,
5 | InputGroup,
6 | InputLeftElement,
7 | useColorModeValue,
8 | } from "@chakra-ui/react";
9 | import { SearchIcon } from "@chakra-ui/icons";
10 | export function SearchBar(props) {
11 | // Pass the computed styles into the `__css` prop
12 | const { variant, children, ...rest } = props;
13 | // Chakra Color Mode
14 | const mainTeal = useColorModeValue("teal.300", "teal.300");
15 | const searchIconColor = useColorModeValue("gray.700", "gray.200");
16 | const inputBg = useColorModeValue("white", "gray.800");
17 | return (
18 |
29 | }
44 | >
45 | }
46 | />
47 |
53 |
54 | );
55 | }
56 |
--------------------------------------------------------------------------------
/api-server-django/api/user/viewsets.py:
--------------------------------------------------------------------------------
1 | from api.user.serializers import UserSerializer
2 | from api.user.models import User
3 | from rest_framework import viewsets, status
4 | from rest_framework.permissions import IsAuthenticated
5 | from rest_framework.response import Response
6 | from rest_framework.exceptions import ValidationError
7 | from rest_framework import mixins
8 |
9 |
10 | class UserViewSet(
11 | viewsets.GenericViewSet, mixins.CreateModelMixin, mixins.UpdateModelMixin
12 | ):
13 | serializer_class = UserSerializer
14 | permission_classes = (IsAuthenticated,)
15 |
16 | error_message = {"success": False, "msg": "Error updating user"}
17 |
18 | def update(self, request, *args, **kwargs):
19 | partial = kwargs.pop("partial", True)
20 | instance = User.objects.get(id=request.data.get("userID"))
21 | serializer = self.get_serializer(instance, data=request.data, partial=partial)
22 | serializer.is_valid(raise_exception=True)
23 | self.perform_update(serializer)
24 |
25 | if getattr(instance, "_prefetched_objects_cache", None):
26 | instance._prefetched_objects_cache = {}
27 |
28 | return Response(serializer.data)
29 |
30 | def create(self, request, *args, **kwargs):
31 | user_id = request.data.get("userID")
32 |
33 | if not user_id:
34 | raise ValidationError(self.error_message)
35 |
36 | if self.request.user.pk != int(user_id) and not self.request.user.is_superuser:
37 | raise ValidationError(self.error_message)
38 |
39 | self.update(request)
40 |
41 | return Response({"success": True}, status.HTTP_200_OK)
42 |
--------------------------------------------------------------------------------
/api-server-django/api/authentication/backends.py:
--------------------------------------------------------------------------------
1 | import jwt
2 |
3 | from rest_framework import authentication, exceptions
4 | from django.conf import settings
5 |
6 | from api.user.models import User
7 | from api.authentication.models import ActiveSession
8 |
9 |
10 | class ActiveSessionAuthentication(authentication.BaseAuthentication):
11 |
12 | auth_error_message = {"success": False, "msg": "User is not logged on."}
13 |
14 | def authenticate(self, request):
15 |
16 | request.user = None
17 |
18 | auth_header = authentication.get_authorization_header(request)
19 |
20 | if not auth_header:
21 | return None
22 |
23 | token = auth_header.decode("utf-8")
24 |
25 | return self._authenticate_credentials(token)
26 |
27 | def _authenticate_credentials(self, token):
28 |
29 | try:
30 | jwt.decode(token, settings.SECRET_KEY, algorithms=["HS256"])
31 | except:
32 | raise exceptions.AuthenticationFailed(self.auth_error_message)
33 |
34 | try:
35 | active_session = ActiveSession.objects.get(token=token)
36 | except:
37 | raise exceptions.AuthenticationFailed(self.auth_error_message)
38 |
39 | try:
40 | user = active_session.user
41 | except User.DoesNotExist:
42 | msg = {"success": False, "msg": "No user matching this token was found."}
43 | raise exceptions.AuthenticationFailed(msg)
44 |
45 | if not user.is_active:
46 | msg = {"success": False, "msg": "This user has been deactivated."}
47 | raise exceptions.AuthenticationFailed(msg)
48 |
49 | return (user, token)
50 |
--------------------------------------------------------------------------------
/react-ui/src/components/Sidebar/index.js:
--------------------------------------------------------------------------------
1 | /*eslint-disable*/
2 | // chakra imports
3 | import {
4 | Box, useColorModeValue
5 | } from "@chakra-ui/react";
6 | import React from "react";
7 | import SidebarContent from "./SidebarContent";
8 |
9 | // FUNCTIONS
10 |
11 | function Sidebar(props) {
12 | // to check for active links and opened collapses
13 | const mainPanel = React.useRef();
14 | let variantChange = "0.2s linear";
15 |
16 | const { logoText, routes, sidebarVariant } = props;
17 |
18 | // BRAND
19 | // Chakra Color Mode
20 | let sidebarBg = "none";
21 | let sidebarRadius = "0px";
22 | let sidebarMargins = "0px";
23 | if (sidebarVariant === "opaque") {
24 | sidebarBg = useColorModeValue("white", "gray.700");
25 | sidebarRadius = "16px";
26 | sidebarMargins = "16px 0px 16px 16px";
27 | }
28 |
29 | // SIDEBAR
30 | return (
31 |
32 |
33 |
50 |
55 |
56 |
57 |
58 | );
59 | }
60 |
61 |
62 |
63 |
64 | export default Sidebar;
65 |
--------------------------------------------------------------------------------
/react-ui/src/views/Dashboard/Billing/components/Invoices.js:
--------------------------------------------------------------------------------
1 | // Chakra imports
2 | import { Button, Flex, Text, useColorModeValue } from "@chakra-ui/react";
3 | // Custom components
4 | import Card from "components/Card/Card.js";
5 | import CardBody from "components/Card/CardBody.js";
6 | import CardHeader from "components/Card/CardHeader.js";
7 | import InvoicesRow from "components/Tables/InvoicesRow";
8 | import React from "react";
9 |
10 | const Invoices = ({ title, data }) => {
11 | const textColor = useColorModeValue("gray.700", "white");
12 |
13 | return (
14 |
18 |
19 |
20 |
21 | {title}
22 |
23 |
32 |
33 |
34 |
35 |
36 | {data.map((row) => {
37 | return (
38 |
45 | );
46 | })}
47 |
48 |
49 |
50 | );
51 | };
52 |
53 | export default Invoices;
54 |
--------------------------------------------------------------------------------
/react-ui/src/views/Dashboard/Dashboard/components/OrdersOverview.js:
--------------------------------------------------------------------------------
1 | // Chakra imports
2 | import { Flex, Text, useColorModeValue } from "@chakra-ui/react";
3 | // Custom components
4 | import Card from "components/Card/Card.js";
5 | import CardBody from "components/Card/CardBody.js";
6 | import CardHeader from "components/Card/CardHeader.js";
7 | import TimelineRow from "components/Tables/TimelineRow";
8 | import React from "react";
9 |
10 | const OrdersOverview = ({ title, amount, data }) => {
11 | const textColor = useColorModeValue("gray.700", "white");
12 |
13 | return (
14 |
15 |
16 |
17 |
18 | {title}
19 |
20 |
21 |
22 | {`${amount}%`}
23 | {" "}
24 | this month.
25 |
26 |
27 |
28 |
29 |
30 | {data.map((row, index, arr) => {
31 | return (
32 |
41 | );
42 | })}
43 |
44 |
45 |
46 | );
47 | };
48 |
49 | export default OrdersOverview;
50 |
--------------------------------------------------------------------------------
/react-ui/src/components/Sidebar/SidebarHelp.js:
--------------------------------------------------------------------------------
1 | import { QuestionIcon } from "@chakra-ui/icons";
2 | import { Button, Flex, Link, Text } from "@chakra-ui/react";
3 | import SidebarHelpImage from "assets/img/SidebarHelpImage.png";
4 | import IconBox from "components/Icons/IconBox";
5 | import React from "react";
6 |
7 | export function SidebarHelp(props) {
8 | // Pass the computed styles into the `__css` prop
9 | const { children, ...rest } = props;
10 | return (
11 |
22 |
23 |
24 |
25 |
26 | Need help?
27 |
28 |
29 | Please check our docs
30 |
31 |
35 |
53 |
54 |
55 | );
56 | }
57 |
--------------------------------------------------------------------------------
/react-ui/src/views/Dashboard/Billing/components/PaymentStatistics.js:
--------------------------------------------------------------------------------
1 | // Chakra imports
2 | import { Flex, Text, useColorModeValue } from "@chakra-ui/react";
3 | // Custom components
4 | import Card from "components/Card/Card.js";
5 | import CardBody from "components/Card/CardBody.js";
6 | import IconBox from "components/Icons/IconBox";
7 | import { Separator } from "components/Separator/Separator";
8 | import React from "react";
9 |
10 | const PaymentStatistics = ({ icon, title, description, amount }) => {
11 | const iconTeal = useColorModeValue("teal.300", "teal.300");
12 | const textColor = useColorModeValue("gray.700", "white");
13 |
14 | return (
15 |
16 |
17 |
18 |
19 | {icon}
20 |
21 |
28 |
29 | {title}
30 |
31 |
36 | {description}
37 |
38 |
39 |
40 |
41 | {`%${amount}`}
42 |
43 |
44 |
45 |
46 | );
47 | };
48 |
49 | export default PaymentStatistics;
50 |
--------------------------------------------------------------------------------
/react-ui/src/components/Tables/TransactionRow.js:
--------------------------------------------------------------------------------
1 | import { Box, Flex, Icon, Text, useColorModeValue } from "@chakra-ui/react";
2 | import React from "react";
3 |
4 | function TransactionRow(props) {
5 | const textColor = useColorModeValue("gray.700", "white");
6 | const { name, date, logo, price } = props;
7 |
8 | return (
9 |
10 |
11 |
28 |
29 |
30 |
31 |
36 | {name}
37 |
38 |
43 | {date}
44 |
45 |
46 |
47 |
56 |
57 | {price}
58 |
59 |
60 |
61 | );
62 | }
63 |
64 | export default TransactionRow;
65 |
--------------------------------------------------------------------------------
/react-ui/src/views/Dashboard/Dashboard/components/MiniStatistics.js:
--------------------------------------------------------------------------------
1 | // Chakra imports
2 | import {
3 | Flex,
4 | Stat,
5 | StatHelpText,
6 | StatLabel,
7 | StatNumber,
8 | useColorModeValue,
9 | } from "@chakra-ui/react";
10 | // Custom components
11 | import Card from "components/Card/Card.js";
12 | import CardBody from "components/Card/CardBody.js";
13 | import IconBox from "components/Icons/IconBox";
14 | import React from "react";
15 |
16 | const MiniStatistics = ({ title, amount, percentage, icon }) => {
17 | const iconTeal = useColorModeValue("teal.300", "teal.300");
18 | const textColor = useColorModeValue("gray.700", "white");
19 |
20 | return (
21 |
22 |
23 |
24 |
25 |
30 | {title}
31 |
32 |
33 |
34 | {amount}
35 |
36 | 0 ? "green.400" : "red.400"}
41 | fontWeight='bold'
42 | ps='3px'
43 | fontSize='md'>
44 | {percentage > 0 ? `+${percentage}%` : `${percentage}%`}
45 |
46 |
47 |
48 |
49 | {icon}
50 |
51 |
52 |
53 |
54 | );
55 | };
56 |
57 | export default MiniStatistics;
58 |
--------------------------------------------------------------------------------
/react-ui/src/assets/svg/adobexd-logo.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/react-ui/src/views/Dashboard/Profile/components/ProjectCard.js:
--------------------------------------------------------------------------------
1 | // Chakra imports
2 | import {
3 | Avatar,
4 | AvatarGroup,
5 | Box,
6 | Button,
7 | Flex,
8 | Image,
9 | Text,
10 | useColorModeValue,
11 | } from "@chakra-ui/react";
12 | import React from "react";
13 |
14 | const ProjectCard = ({ image, name, category, avatars, description }) => {
15 | // Chakra color mode
16 | const textColor = useColorModeValue("gray.700", "white");
17 |
18 | return (
19 |
20 |
21 |
22 |
29 |
30 |
31 |
32 | {name}
33 |
34 |
35 | {category}
36 |
37 |
38 | {description}
39 |
40 |
41 |
50 |
51 | {avatars.map((el, idx) => {
52 | return ;
53 | })}
54 |
55 |
56 |
57 |
58 | );
59 | };
60 |
61 | export default ProjectCard;
62 |
--------------------------------------------------------------------------------
/react-ui/src/components/Tables/TablesProjectRow.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import {
3 | Tr,
4 | Td,
5 | Flex,
6 | Text,
7 | Progress,
8 | Icon,
9 | Button,
10 | useColorModeValue,
11 | } from "@chakra-ui/react";
12 | import { FaEllipsisV } from "react-icons/fa";
13 |
14 | function DashboardTableRow(props) {
15 | const { logo, name, status, budget, progression } = props;
16 | const textColor = useColorModeValue("gray.700", "white");
17 | return (
18 |
19 | |
20 |
21 |
22 |
28 | {name}
29 |
30 |
31 | |
32 |
33 |
34 | {budget}
35 |
36 | |
37 |
38 |
39 | {status}
40 |
41 | |
42 |
43 |
44 | {`${progression}%`}
50 |
56 |
57 | |
58 |
59 |
62 | |
63 |
64 | );
65 | }
66 |
67 | export default DashboardTableRow;
68 |
--------------------------------------------------------------------------------
/react-ui/src/views/Dashboard/Tables/components/Projects.js:
--------------------------------------------------------------------------------
1 | // Chakra imports
2 | import {
3 | Flex,
4 | Table,
5 | Tbody,
6 | Text,
7 | Th,
8 | Thead,
9 | Tr,
10 | useColorModeValue,
11 | } from "@chakra-ui/react";
12 | // Custom components
13 | import Card from "components/Card/Card.js";
14 | import CardBody from "components/Card/CardBody.js";
15 | import CardHeader from "components/Card/CardHeader.js";
16 | import TablesProjectRow from "components/Tables/TablesProjectRow";
17 | import React from "react";
18 |
19 | const Projects = ({ title, captions, data }) => {
20 | const textColor = useColorModeValue("gray.700", "white");
21 | return (
22 |
23 |
24 |
25 |
26 | {title}
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | {captions.map((caption, idx) => {
35 | return (
36 | |
37 | {caption}
38 | |
39 | );
40 | })}
41 |
42 |
43 |
44 | {data.map((row) => {
45 | return (
46 |
54 | );
55 | })}
56 |
57 |
58 |
59 |
60 | );
61 | };
62 |
63 | export default Projects;
64 |
--------------------------------------------------------------------------------
/api-server-django/api/user/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 |
3 | from django.contrib.auth.models import (
4 | AbstractBaseUser,
5 | BaseUserManager,
6 | PermissionsMixin,
7 | )
8 |
9 |
10 | class UserManager(BaseUserManager):
11 | def create_user(self, username, email, password=None, **kwargs):
12 | """Create and return a `User` with an email, username and password."""
13 | if username is None:
14 | raise TypeError("Users must have a username.")
15 | if email is None:
16 | raise TypeError("Users must have an email.")
17 |
18 | user = self.model(username=username, email=self.normalize_email(email))
19 | user.set_password(password)
20 | user.save(using=self._db)
21 |
22 | return user
23 |
24 | def create_superuser(self, username, email, password):
25 | """
26 | Create and return a `User` with superuser (admin) permissions.
27 | """
28 | if password is None:
29 | raise TypeError("Superusers must have a password.")
30 | if email is None:
31 | raise TypeError("Superusers must have an email.")
32 | if username is None:
33 | raise TypeError("Superusers must have an username.")
34 |
35 | user = self.create_user(username, email, password)
36 | user.is_superuser = True
37 | user.is_staff = True
38 | user.save(using=self._db)
39 |
40 | return user
41 |
42 |
43 | class User(AbstractBaseUser, PermissionsMixin):
44 | username = models.CharField(db_index=True, max_length=255, unique=True)
45 | email = models.EmailField(db_index=True, unique=True)
46 | is_active = models.BooleanField(default=True)
47 | is_staff = models.BooleanField(default=False)
48 | date = models.DateTimeField(auto_now_add=True)
49 |
50 | USERNAME_FIELD = "email"
51 | REQUIRED_FIELDS = ["username"]
52 |
53 | objects = UserManager()
54 |
55 | def __str__(self):
56 | return f"{self.email}"
57 |
--------------------------------------------------------------------------------
/react-ui/src/views/Dashboard/Tables/components/Authors.js:
--------------------------------------------------------------------------------
1 | // Chakra imports
2 | import {
3 | Table,
4 | Tbody,
5 | Text,
6 | Th,
7 | Thead,
8 | Tr,
9 | useColorModeValue,
10 | } from "@chakra-ui/react";
11 | // Custom components
12 | import Card from "components/Card/Card.js";
13 | import CardBody from "components/Card/CardBody.js";
14 | import CardHeader from "components/Card/CardHeader.js";
15 | import TablesTableRow from "components/Tables/TablesTableRow";
16 | import React from "react";
17 |
18 | const Authors = ({ title, captions, data }) => {
19 | const textColor = useColorModeValue("gray.700", "white");
20 | return (
21 |
22 |
23 |
24 | {title}
25 |
26 |
27 |
28 |
29 |
30 |
31 | {captions.map((caption, idx) => {
32 | return (
33 | |
34 | {caption}
35 | |
36 | );
37 | })}
38 |
39 |
40 |
41 | {data.map((row) => {
42 | return (
43 |
53 | );
54 | })}
55 |
56 |
57 |
58 |
59 | );
60 | };
61 |
62 | export default Authors;
63 |
--------------------------------------------------------------------------------
/react-ui/src/components/Tables/DashboardTableRow.js:
--------------------------------------------------------------------------------
1 | import {
2 | Avatar,
3 | AvatarGroup,
4 | Flex,
5 | Icon,
6 | Progress,
7 | Td,
8 | Text,
9 | Tr,
10 | useColorModeValue,
11 | } from "@chakra-ui/react";
12 | import React from "react";
13 |
14 | function DashboardTableRow(props) {
15 | const { logo, name, members, budget, progression } = props;
16 | const textColor = useColorModeValue("gray.700", "white");
17 | return (
18 |
19 | |
20 |
21 |
22 |
28 | {name}
29 |
30 |
31 | |
32 |
33 |
34 |
35 | {members.map((member) => {
36 | return (
37 |
43 | );
44 | })}
45 |
46 | |
47 |
48 |
49 | {budget}
50 |
51 | |
52 |
53 |
54 | {`${progression}%`}
60 |
66 |
67 | |
68 |
69 | );
70 | }
71 |
72 | export default DashboardTableRow;
73 |
--------------------------------------------------------------------------------
/react-ui/src/views/Dashboard/Billing/components/CreditCard.js:
--------------------------------------------------------------------------------
1 | // Chakra imports
2 | import { Box, Flex, Spacer, Text } from "@chakra-ui/react";
3 | // Custom components
4 | import Card from "components/Card/Card.js";
5 | import CardBody from "components/Card/CardBody.js";
6 | import React from "react";
7 |
8 | const CreditCard = ({
9 | backgroundImage,
10 | title,
11 | icon,
12 | number,
13 | validity,
14 | cvv,
15 | }) => {
16 | return (
17 |
25 |
26 |
32 |
33 |
34 | {title}
35 |
36 | {icon}
37 |
38 |
39 |
40 |
41 |
42 | {number}
43 |
44 |
45 |
46 |
47 | {validity.name}
48 |
49 | {validity.date}
50 |
51 |
52 |
53 | {cvv.name}
54 |
55 | {cvv.code}
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | );
64 | };
65 |
66 | export default CreditCard;
67 |
--------------------------------------------------------------------------------
/react-ui/src/assets/svg/logo-white.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/api-server-django/api/authentication/serializers/login.py:
--------------------------------------------------------------------------------
1 | import jwt
2 | from rest_framework import serializers, exceptions
3 | from django.contrib.auth import authenticate
4 | from datetime import datetime, timedelta
5 | from django.conf import settings
6 | from django.core.exceptions import ObjectDoesNotExist
7 |
8 | from api.authentication.models import ActiveSession
9 |
10 |
11 | def _generate_jwt_token(user):
12 | token = jwt.encode(
13 | {"id": user.pk, "exp": datetime.utcnow() + timedelta(days=7)},
14 | settings.SECRET_KEY,
15 | )
16 |
17 | return token
18 |
19 |
20 | class LoginSerializer(serializers.Serializer):
21 | email = serializers.CharField(max_length=255)
22 | username = serializers.CharField(max_length=255, read_only=True)
23 | password = serializers.CharField(max_length=128, write_only=True)
24 |
25 | def validate(self, data):
26 | email = data.get("email", None)
27 | password = data.get("password", None)
28 |
29 | if email is None:
30 | raise exceptions.ValidationError(
31 | {"success": False, "msg": "Email is required to login"}
32 | )
33 | if password is None:
34 | raise exceptions.ValidationError(
35 | {"success": False, "msg": "Password is required to log in."}
36 | )
37 | user = authenticate(username=email, password=password)
38 |
39 | if user is None:
40 | raise exceptions.AuthenticationFailed({"success": False, "msg": "Wrong credentials"})
41 |
42 | if not user.is_active:
43 | raise exceptions.ValidationError(
44 | {"success": False, "msg": "User is not active"}
45 | )
46 |
47 | try:
48 | session = ActiveSession.objects.get(user=user)
49 | if not session.token:
50 | raise ValueError
51 |
52 | jwt.decode(session.token, settings.SECRET_KEY, algorithms=["HS256"])
53 |
54 | except (ObjectDoesNotExist, ValueError, jwt.ExpiredSignatureError):
55 | session = ActiveSession.objects.create(
56 | user=user, token=_generate_jwt_token(user)
57 | )
58 |
59 | return {
60 | "success": True,
61 | "token": session.token,
62 | "user": {"_id": user.pk, "username": user.username, "email": user.email},
63 | }
64 |
--------------------------------------------------------------------------------
/react-ui/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "purity-dashboard-react",
3 | "version": "2.0.2",
4 | "private": true,
5 | "dependencies": {
6 | "@chakra-ui/icons": "^1.1.5",
7 | "@chakra-ui/react": "1.8.8",
8 | "@chakra-ui/system": "^1.12.1",
9 | "@chakra-ui/theme-tools": "^1.3.6",
10 | "@emotion/cache": "^11.7.1",
11 | "@emotion/react": "^11.8.1",
12 | "@emotion/styled": "^11.8.1",
13 | "@fontsource/open-sans": "^4.5.0",
14 | "@fontsource/raleway": "^4.5.0",
15 | "@fontsource/roboto": "^4.5.8",
16 | "apexcharts": "^3.27.3",
17 | "axios": "^1.2.0",
18 | "classnames": "2.3.1",
19 | "framer-motion": "^4.1.17",
20 | "match-sorter": "6.3.0",
21 | "moment": "2.29.1",
22 | "node-sass": "7.0.1",
23 | "nouislider": "15.0.0",
24 | "react": "16.14.0",
25 | "react-apexcharts": "^1.3.9",
26 | "react-big-calendar": "0.33.2",
27 | "react-bootstrap-sweetalert": "^5.2.0",
28 | "react-datetime": "3.1.1",
29 | "react-dom": "16.14.0",
30 | "react-github-btn": "^1.2.1",
31 | "react-icons": "^4.2.0",
32 | "react-jvectormap": "0.0.16",
33 | "react-router-dom": "5.2.1",
34 | "react-scripts": "5.0.0",
35 | "react-swipeable-views": "0.14.0",
36 | "react-table": "7.7.0",
37 | "react-tagsinput": "3.19.0",
38 | "stylis": "^4.0.13",
39 | "stylis-plugin-rtl": "^2.1.1"
40 | },
41 | "resolutions": {
42 | "react-error-overlay": "6.0.11"
43 | },
44 | "scripts": {
45 | "start": "react-scripts start",
46 | "build": "react-scripts build && gulp licenses",
47 | "test": "react-scripts test --env=jsdom",
48 | "eject": "react-scripts eject",
49 | "deploy": "npm run build",
50 | "lint:check": "eslint . --ext=js,jsx; exit 0",
51 | "lint:fix": "eslint . --ext=js,jsx --fix; exit 0",
52 | "install:clean": "rm -rf node_modules/ && rm -rf package-lock.json && npm install && npm start"
53 | },
54 | "optionalDependencies": {
55 | "@babel/core": "7.14.0",
56 | "typescript": "4.2.4"
57 | },
58 | "devDependencies": {
59 | "@babel/plugin-transform-react-jsx-source": "^7.14.5",
60 | "eslint-config-prettier": "8.3.0",
61 | "eslint-plugin-prettier": "3.4.0",
62 | "gulp": "4.0.2",
63 | "gulp-append-prepend": "1.0.9",
64 | "prettier": "2.2.1"
65 | },
66 | "browserslist": {
67 | "production": [
68 | "cover 99.8%",
69 | "not dead",
70 | "not OperaMini all"
71 | ],
72 | "development": [
73 | "cover 99.8%",
74 | "not dead",
75 | "not OperaMini all"
76 | ]
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/react-ui/src/components/Tables/TablesTableRow.js:
--------------------------------------------------------------------------------
1 | import {
2 | Avatar,
3 | Badge,
4 | Button,
5 | Flex,
6 | Td,
7 | Text,
8 | Tr,
9 | useColorModeValue,
10 | } from "@chakra-ui/react";
11 | import React from "react";
12 |
13 | function TablesTableRow(props) {
14 | const { logo, name, email, subdomain, domain, status, date } = props;
15 | const textColor = useColorModeValue("gray.700", "white");
16 | const bgStatus = useColorModeValue("gray.400", "#1a202c");
17 | const colorStatus = useColorModeValue("white", "gray.400");
18 |
19 | return (
20 |
21 | |
22 |
23 |
24 |
25 |
31 | {name}
32 |
33 |
34 | {email}
35 |
36 |
37 |
38 | |
39 |
40 |
41 |
42 |
43 | {domain}
44 |
45 |
46 | {subdomain}
47 |
48 |
49 | |
50 |
51 |
58 | {status}
59 |
60 | |
61 |
62 |
63 | {date}
64 |
65 | |
66 |
67 |
77 | |
78 |
79 | );
80 | }
81 |
82 | export default TablesTableRow;
83 |
--------------------------------------------------------------------------------
/react-ui/src/views/Dashboard/Dashboard/components/Projects.js:
--------------------------------------------------------------------------------
1 | // Chakra imports
2 | import {
3 | Flex,
4 | Icon,
5 | Table,
6 | Tbody,
7 | Text,
8 | Th,
9 | Thead,
10 | Tr,
11 | useColorModeValue,
12 | } from "@chakra-ui/react";
13 | // Custom components
14 | import Card from "components/Card/Card.js";
15 | import CardHeader from "components/Card/CardHeader.js";
16 | import DashboardTableRow from "components/Tables/DashboardTableRow";
17 | import React from "react";
18 | import { IoCheckmarkDoneCircleSharp } from "react-icons/io5";
19 |
20 | const Projects = ({ title, amount, captions, data }) => {
21 | const textColor = useColorModeValue("gray.700", "white");
22 |
23 | return (
24 |
25 |
26 |
27 |
28 | {title}
29 |
30 |
31 |
38 |
39 |
40 | {amount} done
41 | {" "}
42 | this month.
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | {captions.map((caption, idx) => {
51 | return (
52 | |
53 | {caption}
54 | |
55 | );
56 | })}
57 |
58 |
59 |
60 | {data.map((row) => {
61 | return (
62 |
70 | );
71 | })}
72 |
73 |
74 |
75 | );
76 | };
77 |
78 | export default Projects;
79 |
--------------------------------------------------------------------------------
/react-ui/src/routes.js:
--------------------------------------------------------------------------------
1 | // import
2 | import Dashboard from "views/Dashboard/Dashboard";
3 | import Tables from "views/Dashboard/Tables";
4 | import Billing from "views/Dashboard/Billing";
5 | import RTLPage from "views/Dashboard/RTL";
6 | import Profile from "views/Dashboard/Profile";
7 | import SignIn from "views/Auth/SignIn.js";
8 | import SignUp from "views/Auth/SignUp.js";
9 |
10 | import {
11 | HomeIcon,
12 | StatsIcon,
13 | CreditIcon,
14 | PersonIcon,
15 | DocumentIcon,
16 | RocketIcon,
17 | SupportIcon,
18 | } from "components/Icons/Icons";
19 |
20 | var dashRoutes = [
21 | {
22 | path: "/dashboard",
23 | name: "Dashboard",
24 | rtlName: "لوحة القيادة",
25 | icon: ,
26 | component: Dashboard,
27 | layout: "/admin",
28 | protected: true,
29 | },
30 | {
31 | path: "/tables",
32 | name: "Tables",
33 | rtlName: "لوحة القيادة",
34 | icon: ,
35 | component: Tables,
36 | layout: "/admin",
37 | protected: true,
38 | },
39 | {
40 | path: "/billing",
41 | name: "Billing",
42 | rtlName: "لوحة القيادة",
43 | icon: ,
44 | component: Billing,
45 | layout: "/admin",
46 | protected: true,
47 | },
48 | {
49 | path: "/rtl-support-page",
50 | name: "RTL",
51 | rtlName: "آرتيإل",
52 | icon: ,
53 | component: RTLPage,
54 | layout: "/rtl",
55 | },
56 | {
57 | name: "ACCOUNT PAGES",
58 | category: "account",
59 | rtlName: "صفحات",
60 | state: "pageCollapse",
61 | views: [
62 | {
63 | path: "/profile",
64 | name: "Profile",
65 | rtlName: "لوحة القيادة",
66 | icon: ,
67 | secondaryNavbar: true,
68 | component: Profile,
69 | layout: "/admin",
70 | protected: true,
71 | },
72 | {
73 | path: "/signin",
74 | name: "Sign In",
75 | rtlName: "لوحة القيادة",
76 | icon: ,
77 | component: SignIn,
78 | layout: "/auth",
79 | },
80 | {
81 | path: "/signup",
82 | name: "Sign Up",
83 | rtlName: "لوحة القيادة",
84 | icon: ,
85 | secondaryNavbar: true,
86 | component: SignUp,
87 | layout: "/auth",
88 | },
89 | ],
90 | },
91 | ];
92 | export default dashRoutes;
93 |
--------------------------------------------------------------------------------
/api-server-django/api/authentication/tests.py:
--------------------------------------------------------------------------------
1 | from django.urls import reverse
2 | from rest_framework.test import APITestCase
3 | from rest_framework import status
4 |
5 |
6 | class AuthenticationTest(APITestCase):
7 | base_url_register = reverse("api:register-list")
8 | base_url_login = reverse("api:login-list")
9 | base_url_logout = reverse("api:logout-list")
10 | base_url_check_session = reverse("api:check-session-list")
11 |
12 | data_register = {"username": "test", "password": "pass", "email": "test@appseed.us"}
13 |
14 | data_login = {"password": "12345678", "email": "teast@admin.com"}
15 |
16 | def test_register(self):
17 | response = self.client.post(
18 | f"{self.base_url_register}", data=self.data_register
19 | )
20 | self.assertEqual(response.status_code, status.HTTP_201_CREATED)
21 | response_data = response.json()
22 | self.assertEqual(response_data["success"], True)
23 |
24 | def test_login(self):
25 | response = self.client.post(f"{self.base_url_login}", data=self.data_login)
26 | self.assertEqual(response.status_code, status.HTTP_200_OK)
27 | response_data = response.json()
28 | self.assertEqual(response_data["success"], True)
29 |
30 | def test_logout(self):
31 | # Login to retrieve token
32 |
33 | response = self.client.post(f"{self.base_url_login}", data=self.data_login)
34 | response_data = response.json()
35 |
36 | token = response_data["token"]
37 |
38 | self.client.credentials(HTTP_AUTHORIZATION=token)
39 |
40 | # Logout
41 |
42 | response = self.client.post(f"{self.base_url_logout}", data={"token": token})
43 | self.assertEqual(response.status_code, status.HTTP_200_OK)
44 | response_data = response.json()
45 | self.assertEqual(response_data["success"], True)
46 |
47 | def test_check_session(self):
48 | # Login to retrieve token
49 |
50 | response = self.client.post(f"{self.base_url_login}", data=self.data_login)
51 | response_data = response.json()
52 |
53 | token = response_data["token"]
54 |
55 | self.client.credentials(HTTP_AUTHORIZATION=token)
56 |
57 | # Check session
58 | response = self.client.post(f"{self.base_url_check_session}")
59 | self.assertEqual(response.status_code, status.HTTP_200_OK)
60 |
61 | response_data = response.json()
62 | self.assertEqual(response_data["success"], True)
63 |
--------------------------------------------------------------------------------
/api-server-django/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | .python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95 | __pypackages__/
96 |
97 | # Celery stuff
98 | celerybeat-schedule
99 | celerybeat.pid
100 |
101 | # SageMath parsed files
102 | *.sage.py
103 |
104 | # Environments
105 | .env
106 | .venv
107 | env/
108 | venv/
109 | ENV/
110 | env.bak/
111 | venv.bak/
112 |
113 | # Spyder project settings
114 | .spyderproject
115 | .spyproject
116 |
117 | # Rope project settings
118 | .ropeproject
119 |
120 | # mkdocs documentation
121 | /site
122 |
123 | # mypy
124 | .mypy_cache/
125 | .dmypy.json
126 | dmypy.json
127 |
128 | # Pyre type checker
129 | .pyre/
130 | .env__
131 |
--------------------------------------------------------------------------------
/react-ui/src/views/Dashboard/Dashboard/components/ActiveUsers.js:
--------------------------------------------------------------------------------
1 | // Chakra imports
2 | import { Flex, SimpleGrid, Text, useColorModeValue } from "@chakra-ui/react";
3 | // Custom components
4 | import Card from "components/Card/Card.js";
5 | import CardBody from "components/Card/CardBody.js";
6 | // Custom icons
7 | import {
8 | CartIcon,
9 | RocketIcon,
10 | StatsIcon,
11 | WalletIcon,
12 | } from "components/Icons/Icons.js";
13 | import React from "react";
14 | import ChartStatistics from "./ChartStatistics";
15 |
16 | const ActiveUsers = ({ title, percentage, chart }) => {
17 | const iconBoxInside = useColorModeValue("white", "white");
18 | const textColor = useColorModeValue("gray.700", "white");
19 | return (
20 |
21 |
22 |
23 | {chart}
24 |
25 |
26 | {title}
27 |
28 |
29 | 0 ? "green.400" : "red.400"}
32 | fontWeight='bold'>
33 | {percentage > 0 ? `+${percentage}%` : `-${percentage}%`}
34 | {" "}
35 | than last week
36 |
37 |
38 |
39 | }
44 | />
45 | }
50 | />
51 | }
56 | />
57 | }
62 | />
63 |
64 |
65 |
66 |
67 | );
68 | };
69 |
70 | export default ActiveUsers;
71 |
--------------------------------------------------------------------------------
/react-ui/src/components/Tables/BillingRow.js:
--------------------------------------------------------------------------------
1 | import {
2 | Box,
3 | Button,
4 | Flex,
5 | Icon,
6 | Text,
7 | useColorModeValue,
8 | } from "@chakra-ui/react";
9 | import React from "react";
10 | import { FaPencilAlt, FaTrashAlt } from "react-icons/fa";
11 |
12 | function BillingRow(props) {
13 | const textColor = useColorModeValue("gray.700", "white");
14 | const bgColor = useColorModeValue("#F8F9FA", "gray.800");
15 | const nameColor = useColorModeValue("gray.500", "white");
16 | const { name, company, email, number } = props;
17 |
18 | return (
19 |
20 |
21 |
22 |
23 | {name}
24 |
25 |
26 | Company Name:{" "}
27 |
28 | {company}
29 |
30 |
31 |
32 | Email Address:{" "}
33 |
34 | {email}
35 |
36 |
37 |
38 | VAT Number:{" "}
39 |
40 | {number}
41 |
42 |
43 |
44 |
49 |
62 |
70 |
71 |
72 |
73 | );
74 | }
75 |
76 | export default BillingRow;
77 |
--------------------------------------------------------------------------------
/react-ui/src/views/Dashboard/Profile/index.js:
--------------------------------------------------------------------------------
1 | // Chakra imports
2 | import { Flex, Grid, useColorModeValue } from "@chakra-ui/react";
3 | import avatar4 from "assets/img/avatars/avatar4.png";
4 | import ProfileBgImage from "assets/img/ProfileBackground.png";
5 | import React from "react";
6 | import { FaCube, FaPenFancy } from "react-icons/fa";
7 | import { IoDocumentsSharp } from "react-icons/io5";
8 | import Conversations from "./components/Conversations";
9 | import Header from "./components/Header";
10 | import PlatformSettings from "./components/PlatformSettings";
11 | import ProfileInformation from "./components/ProfileInformation";
12 | import Projects from "./components/Projects";
13 |
14 | function Profile() {
15 | // Chakra color mode
16 | const textColor = useColorModeValue("gray.700", "white");
17 | const bgProfile = useColorModeValue(
18 | "hsla(0,0%,100%,.8)",
19 | "linear-gradient(112.83deg, rgba(255, 255, 255, 0.21) 0%, rgba(255, 255, 255, 0) 110.84%)"
20 | );
21 |
22 | return (
23 |
24 | ,
34 | },
35 | {
36 | name: "TEAMS",
37 | icon: ,
38 | },
39 | {
40 | name: "PROJECTS",
41 | icon: ,
42 | },
43 | ]}
44 | />
45 |
46 |
51 |
61 |
62 |
63 |
64 |
65 | );
66 | }
67 |
68 | export default Profile;
69 |
--------------------------------------------------------------------------------
/react-ui/src/views/Dashboard/Dashboard/components/WorkWithTheRockets.js:
--------------------------------------------------------------------------------
1 | // Chakra imports
2 | import {
3 | Box,
4 | Button,
5 | Flex,
6 | Icon,
7 | Portal,
8 | Spacer,
9 | Text,
10 | } from "@chakra-ui/react";
11 | // Custom components
12 | import Card from "components/Card/Card.js";
13 | import CardBody from "components/Card/CardBody.js";
14 | import React from "react";
15 | // react icons
16 | import { BsArrowRight } from "react-icons/bs";
17 |
18 | const WorkWithTheRockets = ({ title, description, backgroundImage }) => {
19 | const overlayRef = React.useRef();
20 | return (
21 |
22 |
32 |
39 |
40 |
45 |
46 | {title}
47 |
48 |
49 | {description}
50 |
51 |
52 |
53 |
73 |
74 |
75 |
76 |
77 |
78 | );
79 | };
80 |
81 | export default WorkWithTheRockets;
82 |
--------------------------------------------------------------------------------
/react-ui/src/views/Dashboard/Dashboard/components/BuiltByDevelopers.js:
--------------------------------------------------------------------------------
1 | // Chakra imports
2 | import {
3 | Button,
4 | Flex,
5 | Icon,
6 | Spacer,
7 | Text,
8 | useColorModeValue,
9 | } from "@chakra-ui/react";
10 | // Custom components
11 | import Card from "components/Card/Card.js";
12 | import CardBody from "components/Card/CardBody.js";
13 | import React from "react";
14 | // react icons
15 | import { BsArrowRight } from "react-icons/bs";
16 |
17 | const BuiltByDevelopers = ({ title, name, description, image }) => {
18 | const textColor = useColorModeValue("gray.700", "white");
19 |
20 | return (
21 |
22 |
23 |
24 |
29 |
30 | {title}
31 |
32 |
33 | {name}
34 |
35 |
36 | {description}
37 |
38 |
39 |
40 |
67 |
68 |
69 |
70 |
77 | {image}
78 |
79 |
80 |
81 |
82 | );
83 | };
84 |
85 | export default BuiltByDevelopers;
86 |
--------------------------------------------------------------------------------
/react-ui/src/views/Dashboard/Profile/components/PlatformSettings.js:
--------------------------------------------------------------------------------
1 | // Chakra imports
2 | import { Flex, Switch, Text, useColorModeValue } from "@chakra-ui/react";
3 | // Custom components
4 | import Card from "components/Card/Card";
5 | import CardBody from "components/Card/CardBody";
6 | import CardHeader from "components/Card/CardHeader";
7 | import React from "react";
8 |
9 | const PlatformSettings = ({ title, subtitle1, subtitle2 }) => {
10 | // Chakra color mode
11 | const textColor = useColorModeValue("gray.700", "white");
12 | return (
13 |
14 |
15 |
16 | {title}
17 |
18 |
19 |
20 |
21 |
22 | {subtitle1}
23 |
24 |
25 |
26 |
27 | Email me when someone follows me
28 |
29 |
30 |
31 |
32 |
33 | Email me when someone answers on my post
34 |
35 |
36 |
37 |
38 |
39 | Email me when someone mentions me
40 |
41 |
42 |
47 | {subtitle2}
48 |
49 |
50 |
51 |
52 | New launches and projects
53 |
54 |
55 |
56 |
57 |
58 | Monthly product changes
59 |
60 |
61 |
62 |
63 |
64 | Subscribe to newsletter
65 |
66 |
67 |
68 |
69 |
70 | );
71 | };
72 |
73 | export default PlatformSettings;
74 |
--------------------------------------------------------------------------------
/react-ui/src/views/Dashboard/Billing/components/Transactions.js:
--------------------------------------------------------------------------------
1 | // Chakra imports
2 | import { Flex, Icon, Text, useColorModeValue } from "@chakra-ui/react";
3 | // Custom components
4 | import Card from "components/Card/Card.js";
5 | import CardBody from "components/Card/CardBody.js";
6 | import CardHeader from "components/Card/CardHeader.js";
7 | import TransactionRow from "components/Tables/TransactionRow";
8 | import React from "react";
9 | import { FaRegCalendarAlt } from "react-icons/fa";
10 |
11 | const Transactions = ({
12 | title,
13 | date,
14 | newestTransactions,
15 | olderTransactions,
16 | }) => {
17 | // Chakra color mode
18 | const textColor = useColorModeValue("gray.700", "white");
19 |
20 | return (
21 |
22 |
23 |
24 |
30 |
34 | {title}
35 |
36 |
37 |
42 |
43 | {date}
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
56 | NEWEST
57 |
58 | {newestTransactions.map((row) => {
59 | return (
60 |
66 | );
67 | })}
68 |
73 | OLDER
74 |
75 | {olderTransactions.map((row) => {
76 | return (
77 |
83 | );
84 | })}
85 |
86 |
87 |
88 | );
89 | };
90 |
91 | export default Transactions;
92 |
--------------------------------------------------------------------------------
/api-server-django/api/user/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.5 on 2021-07-15 11:20
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | initial = True
9 |
10 | dependencies = [
11 | ("auth", "0012_alter_user_first_name_max_length"),
12 | ]
13 |
14 | operations = [
15 | migrations.CreateModel(
16 | name="User",
17 | fields=[
18 | (
19 | "id",
20 | models.BigAutoField(
21 | auto_created=True,
22 | primary_key=True,
23 | serialize=False,
24 | verbose_name="ID",
25 | ),
26 | ),
27 | ("password", models.CharField(max_length=128, verbose_name="password")),
28 | (
29 | "last_login",
30 | models.DateTimeField(
31 | blank=True, null=True, verbose_name="last login"
32 | ),
33 | ),
34 | (
35 | "is_superuser",
36 | models.BooleanField(
37 | default=False,
38 | help_text="Designates that this user has all permissions without explicitly assigning them.",
39 | verbose_name="superuser status",
40 | ),
41 | ),
42 | ("username", models.CharField(db_index=True, max_length=255)),
43 | (
44 | "email",
45 | models.EmailField(db_index=True, max_length=254, unique=True),
46 | ),
47 | ("is_active", models.BooleanField(default=True)),
48 | ("date", models.DateTimeField(auto_now_add=True)),
49 | (
50 | "groups",
51 | models.ManyToManyField(
52 | blank=True,
53 | help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.",
54 | related_name="user_set",
55 | related_query_name="user",
56 | to="auth.Group",
57 | verbose_name="groups",
58 | ),
59 | ),
60 | (
61 | "user_permissions",
62 | models.ManyToManyField(
63 | blank=True,
64 | help_text="Specific permissions for this user.",
65 | related_name="user_set",
66 | related_query_name="user",
67 | to="auth.Permission",
68 | verbose_name="user permissions",
69 | ),
70 | ),
71 | ],
72 | options={
73 | "abstract": False,
74 | },
75 | ),
76 | ]
77 |
--------------------------------------------------------------------------------
/react-ui/src/components/Footer/Footer.js:
--------------------------------------------------------------------------------
1 | /*eslint-disable*/
2 | import React from "react";
3 | import { Flex, Link, List, ListItem, Text } from "@chakra-ui/react";
4 | import PropTypes from "prop-types";
5 |
6 | export default function Footer(props) {
7 | // const linkTeal = useColorModeValue("teal.400", "red.200");=
8 | return (
9 |
22 |
30 | ©
31 |
37 | {document.documentElement.dir === "rtl"
38 | ? " توقيت الإبداعية"
39 | : "Creative Tim "}
40 |
41 | &
42 |
48 | {document.documentElement.dir === "rtl" ? "سيممبل " : " Simmmple"}
49 |
50 | {document.documentElement.dir === "rtl"
51 | ? "للحصول على ويب أفضل"
52 | : " for a better web"}
53 |
54 |
55 |
61 |
62 | {document.documentElement.dir === "rtl"
63 | ? "توقيت الإبداعية"
64 | : "Creative Tim"}
65 |
66 |
67 |
73 |
74 | {document.documentElement.dir === "rtl" ? "سيممبل" : "Simmmple"}
75 |
76 |
77 |
83 |
88 | {document.documentElement.dir === "rtl" ? "مدونة" : "Blog"}
89 |
90 |
91 |
92 |
97 | {document.documentElement.dir === "rtl" ? "رخصة" : "License"}
98 |
99 |
100 |
101 |
102 | );
103 | }
104 |
--------------------------------------------------------------------------------
/react-ui/gulpfile.js:
--------------------------------------------------------------------------------
1 | const gulp = require("gulp");
2 | const gap = require("gulp-append-prepend");
3 |
4 | gulp.task("licenses", async function () {
5 | // this is to add Creative Tim licenses in the production mode for the minified js
6 | gulp
7 | .src("build/static/js/*chunk.js", { base: "./" })
8 | .pipe(
9 | gap.prependText(`/*!
10 |
11 | =========================================================
12 | * Purity UI Dashboard - v1.0.1
13 | =========================================================
14 |
15 | * Product Page: https://www.creative-tim.com/product/purity-ui-dashboard
16 | * Copyright 2021 Creative Tim (https://www.creative-tim.com)
17 | * Licensed under MIT (https://github.com/creativetimofficial/purity-ui-dashboard/blob/master/LICENSE.md)
18 |
19 | * Design by Creative Tim & Coded by Simmmple
20 |
21 | =========================================================
22 |
23 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
24 |
25 | */`)
26 | )
27 | .pipe(gulp.dest("./", { overwrite: true }));
28 |
29 | // this is to add Creative Tim licenses in the production mode for the minified html
30 | gulp
31 | .src("build/index.html", { base: "./" })
32 | .pipe(
33 | gap.prependText(``)
52 | )
53 | .pipe(gulp.dest("./", { overwrite: true }));
54 |
55 | // this is to add Creative Tim licenses in the production mode for the minified css
56 | gulp
57 | .src("build/static/css/*chunk.css", { base: "./" })
58 | .pipe(
59 | gap.prependText(`/*!
60 |
61 | =========================================================
62 | * Purity UI Dashboard - v1.0.1
63 | =========================================================
64 |
65 | * Product Page: https://www.creative-tim.com/product/purity-ui-dashboard
66 | * Copyright 2021 Creative Tim (https://www.creative-tim.com)
67 | * Licensed under MIT (https://github.com/creativetimofficial/purity-ui-dashboard/blob/master/LICENSE.md)
68 |
69 | * Design by Creative Tim & Coded by Simmmple
70 |
71 | =========================================================
72 |
73 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
74 |
75 | */`)
76 | )
77 | .pipe(gulp.dest("./", { overwrite: true }));
78 | return;
79 | });
80 |
--------------------------------------------------------------------------------
/react-ui/src/layouts/Auth.js:
--------------------------------------------------------------------------------
1 | // chakra imports
2 | import { Box, ChakraProvider, Portal } from '@chakra-ui/react';
3 | import Footer from 'components/Footer/Footer.js';
4 | // core components
5 | import AuthNavbar from 'components/Navbars/AuthNavbar.js';
6 | import React from 'react';
7 | import { Redirect, Route, Switch } from 'react-router-dom';
8 | import routes from 'routes.js';
9 | import '@fontsource/roboto/400.css';
10 | import '@fontsource/roboto/500.css';
11 | import '@fontsource/roboto/700.css';
12 | import theme from 'theme/theme.js';
13 |
14 | export default function Pages(props) {
15 | const { ...rest } = props;
16 | // ref for the wrapper div
17 | const wrapper = React.createRef();
18 | React.useEffect(() => {
19 | document.body.style.overflow = 'unset';
20 | // Specify how to clean up after this effect:
21 | return function cleanup() {};
22 | });
23 | const getActiveRoute = (routes) => {
24 | let activeRoute = 'Default Brand Text';
25 | for (let i = 0; i < routes.length; i++) {
26 | if (routes[i].collapse) {
27 | let collapseActiveRoute = getActiveRoute(routes[i].views);
28 | if (collapseActiveRoute !== activeRoute) {
29 | return collapseActiveRoute;
30 | }
31 | } else if (routes[i].category) {
32 | let categoryActiveRoute = getActiveRoute(routes[i].views);
33 | if (categoryActiveRoute !== activeRoute) {
34 | return categoryActiveRoute;
35 | }
36 | } else {
37 | if (window.location.href.indexOf(routes[i].layout + routes[i].path) !== -1) {
38 | return routes[i].name;
39 | }
40 | }
41 | }
42 | return activeRoute;
43 | };
44 | const getActiveNavbar = (routes) => {
45 | let activeNavbar = false;
46 | for (let i = 0; i < routes.length; i++) {
47 | if (routes[i].category) {
48 | let categoryActiveNavbar = getActiveNavbar(routes[i].views);
49 | if (categoryActiveNavbar !== activeNavbar) {
50 | return categoryActiveNavbar;
51 | }
52 | } else {
53 | if (window.location.href.indexOf(routes[i].layout + routes[i].path) !== -1) {
54 | if (routes[i].secondaryNavbar) {
55 | return routes[i].secondaryNavbar;
56 | }
57 | }
58 | }
59 | }
60 | return activeNavbar;
61 | };
62 | const getRoutes = (routes) => {
63 | return routes.map((prop, key) => {
64 | if (prop.collapse) {
65 | return getRoutes(prop.views);
66 | }
67 | if (prop.category === 'account') {
68 | return getRoutes(prop.views);
69 | }
70 | if (prop.layout === '/auth') {
71 | return ;
72 | } else {
73 | return null;
74 | }
75 | });
76 | };
77 | const navRef = React.useRef();
78 | document.documentElement.dir = 'ltr';
79 | return (
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 | {getRoutes(routes)}
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 | );
99 | }
100 |
--------------------------------------------------------------------------------
/react-ui/src/views/Dashboard/Profile/components/Projects.js:
--------------------------------------------------------------------------------
1 | // Chakra imports
2 | import {
3 | Button,
4 | Flex,
5 | Grid,
6 | Icon,
7 | Text,
8 | useColorModeValue,
9 | } from "@chakra-ui/react";
10 | // Assets
11 | import avatar2 from "assets/img/avatars/avatar2.png";
12 | import avatar4 from "assets/img/avatars/avatar4.png";
13 | import avatar6 from "assets/img/avatars/avatar6.png";
14 | import imageArchitect1 from "assets/img/ImageArchitect1.png";
15 | import imageArchitect2 from "assets/img/ImageArchitect2.png";
16 | import imageArchitect3 from "assets/img/ImageArchitect3.png";
17 | // Custom components
18 | import Card from "components/Card/Card";
19 | import CardBody from "components/Card/CardBody";
20 | import CardHeader from "components/Card/CardHeader";
21 | import React from "react";
22 | import { FaPlus } from "react-icons/fa";
23 | import ProjectCard from "./ProjectCard";
24 |
25 | const Projects = ({ title, description }) => {
26 | // Chakra color mode
27 | const textColor = useColorModeValue("gray.700", "white");
28 |
29 | return (
30 |
31 |
32 |
33 |
34 | {title}
35 |
36 |
37 | {description}
38 |
39 |
40 |
41 |
42 |
46 |
55 |
64 |
73 |
87 |
88 |
89 |
90 | );
91 | };
92 |
93 | export default Projects;
94 |
--------------------------------------------------------------------------------
/react-ui/src/views/Dashboard/Billing/components/PaymentMethod.js:
--------------------------------------------------------------------------------
1 | // Chakra imports
2 | import {
3 | Button,
4 | Flex,
5 | Icon,
6 | Spacer,
7 | Text,
8 | useColorModeValue,
9 | } from "@chakra-ui/react";
10 | // Custom components
11 | import Card from "components/Card/Card.js";
12 | import CardBody from "components/Card/CardBody.js";
13 | import CardHeader from "components/Card/CardHeader.js";
14 | import IconBox from "components/Icons/IconBox";
15 | import React from "react";
16 | import { FaPencilAlt } from "react-icons/fa";
17 |
18 | const PaymentMethod = ({ title, mastercard, visa }) => {
19 | const iconTeal = useColorModeValue("teal.300", "teal.300");
20 | const textColor = useColorModeValue("gray.700", "white");
21 | const borderColor = useColorModeValue("#dee2e6", "gray.500");
22 | const bgButton = useColorModeValue(
23 | "linear-gradient(81.62deg, #313860 2.25%, #151928 79.87%)",
24 | "gray.800"
25 | );
26 |
27 | return (
28 |
29 |
30 |
31 |
32 | {title}
33 |
34 |
37 |
38 |
39 |
40 |
46 |
56 |
57 | {mastercard.icon}
58 |
59 |
60 | {mastercard.number}
61 |
62 |
63 |
71 |
72 |
80 |
81 | {visa.icon}
82 |
83 |
84 | {visa.number}
85 |
86 |
87 |
95 |
96 |
97 |
98 |
99 | );
100 | };
101 |
102 | export default PaymentMethod;
103 |
--------------------------------------------------------------------------------
/react-ui/src/assets/svg/logo.svg:
--------------------------------------------------------------------------------
1 |
22 |
--------------------------------------------------------------------------------
/react-ui/src/views/Dashboard/Billing/index.js:
--------------------------------------------------------------------------------
1 | // Chakra imports
2 | import { Box, Flex, Grid, Icon } from "@chakra-ui/react";
3 | // Assets
4 | import BackgroundCard1 from "assets/img/BackgroundCard1.png";
5 | import { MastercardIcon, VisaIcon } from "components/Icons/Icons";
6 | import React from "react";
7 | import { FaPaypal, FaWallet } from "react-icons/fa";
8 | import { RiMastercardFill } from "react-icons/ri";
9 | import {
10 | billingData,
11 | invoicesData,
12 | newestTransactions,
13 | olderTransactions,
14 | } from "variables/general";
15 | import BillingInformation from "./components/BillingInformation";
16 | import CreditCard from "./components/CreditCard";
17 | import Invoices from "./components/Invoices";
18 | import PaymentMethod from "./components/PaymentMethod";
19 | import PaymentStatistics from "./components/PaymentStatistics";
20 | import Transactions from "./components/Transactions";
21 |
22 | function Billing() {
23 | return (
24 |
25 |
26 |
27 |
35 |
54 | }
55 | />
56 | }
58 | title={"Salary"}
59 | description={"Belong interactive"}
60 | amount={2000}
61 | />
62 | }
64 | title={"Paypal"}
65 | description={"Freelance Payment"}
66 | amount={4550}
67 | />
68 |
69 | ,
73 | number: "7812 2139 0823 XXXX",
74 | }}
75 | visa={{
76 | icon: ,
77 | number: "7812 2139 0823 XXXX",
78 | }}
79 | />
80 |
81 |
82 |
83 |
84 |
85 |
91 |
92 |
93 | );
94 | }
95 |
96 | export default Billing;
97 |
--------------------------------------------------------------------------------
/react-ui/src/assets/svg/logo-colored.svg:
--------------------------------------------------------------------------------
1 |
22 |
--------------------------------------------------------------------------------
/react-ui/src/variables/charts.js:
--------------------------------------------------------------------------------
1 | export const barChartData = [
2 | {
3 | name: "Sales",
4 | data: [330, 250, 110, 300, 490, 350, 270, 130, 425],
5 | },
6 | ];
7 |
8 | export const barChartOptions = {
9 | chart: {
10 | toolbar: {
11 | show: false,
12 | },
13 | },
14 | tooltip: {
15 | style: {
16 | backgroundColor: "red",
17 | fontSize: "12px",
18 | fontFamily: undefined,
19 | },
20 | onDatasetHover: {
21 | style: {
22 | backgroundColor: "red",
23 | fontSize: "12px",
24 | fontFamily: undefined,
25 | },
26 | },
27 | theme: "dark",
28 | },
29 | xaxis: {
30 | categories: ["Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
31 | show: false,
32 | labels: {
33 | show: false,
34 | style: {
35 | colors: "#fff",
36 | fontSize: "12px",
37 | },
38 | },
39 | axisBorder: {
40 | show: false,
41 | },
42 | axisTicks: {
43 | show: false,
44 | },
45 | },
46 | yaxis: {
47 | show: true,
48 | color: "#fff",
49 | labels: {
50 | show: true,
51 | style: {
52 | colors: "#fff",
53 | fontSize: "14px",
54 | },
55 | },
56 | },
57 | grid: {
58 | show: false,
59 | },
60 | fill: {
61 | colors: "#fff",
62 | },
63 | dataLabels: {
64 | enabled: false,
65 | },
66 | plotOptions: {
67 | bar: {
68 | borderRadius: 8,
69 | columnWidth: "12px",
70 | },
71 | },
72 | responsive: [
73 | {
74 | breakpoint: 768,
75 | options: {
76 | plotOptions: {
77 | bar: {
78 | borderRadius: 0,
79 | },
80 | },
81 | },
82 | },
83 | ],
84 | };
85 |
86 | export const lineChartData = [
87 | {
88 | name: "Mobile apps",
89 | data: [50, 40, 300, 220, 500, 250, 400, 230, 500],
90 | },
91 | {
92 | name: "Websites",
93 | data: [30, 90, 40, 140, 290, 290, 340, 230, 400],
94 | },
95 | ];
96 |
97 | export const lineChartOptions = {
98 | chart: {
99 | toolbar: {
100 | show: false,
101 | },
102 | },
103 | tooltip: {
104 | theme: "dark",
105 | },
106 | dataLabels: {
107 | enabled: false,
108 | },
109 | stroke: {
110 | curve: "smooth",
111 | },
112 | xaxis: {
113 | type: "datetime",
114 | categories: [
115 | "Jan",
116 | "Feb",
117 | "Mar",
118 | "Apr",
119 | "May",
120 | "Jun",
121 | "Jul",
122 | "Aug",
123 | "Sep",
124 | "Oct",
125 | "Nov",
126 | "Dec",
127 | ],
128 | labels: {
129 | style: {
130 | colors: "#c8cfca",
131 | fontSize: "12px",
132 | },
133 | },
134 | },
135 | yaxis: {
136 | labels: {
137 | style: {
138 | colors: "#c8cfca",
139 | fontSize: "12px",
140 | },
141 | },
142 | },
143 | legend: {
144 | show: false,
145 | },
146 | grid: {
147 | strokeDashArray: 5,
148 | },
149 | fill: {
150 | type: "gradient",
151 | gradient: {
152 | shade: "light",
153 | type: "vertical",
154 | shadeIntensity: 0.5,
155 | gradientToColors: undefined, // optional, if not defined - uses the shades of same color in series
156 | inverseColors: true,
157 | opacityFrom: 0.8,
158 | opacityTo: 0,
159 | stops: [],
160 | },
161 | colors: ["#4FD1C5", "#2D3748"],
162 | },
163 | colors: ["#4FD1C5", "#2D3748"],
164 | };
165 |
--------------------------------------------------------------------------------
/react-ui/src/views/Dashboard/Profile/components/ProfileInformation.js:
--------------------------------------------------------------------------------
1 | // Chakra imports
2 | import { Flex, Icon, Link, Text, useColorModeValue } from "@chakra-ui/react";
3 | // Custom components
4 | import Card from "components/Card/Card";
5 | import CardBody from "components/Card/CardBody";
6 | import CardHeader from "components/Card/CardHeader";
7 | import React from "react";
8 | import { FaFacebook, FaInstagram, FaTwitter } from "react-icons/fa";
9 |
10 | const ProfileInformation = ({
11 | title,
12 | description,
13 | name,
14 | mobile,
15 | email,
16 | location,
17 | }) => {
18 | // Chakra color mode
19 | const textColor = useColorModeValue("gray.700", "white");
20 |
21 | return (
22 |
23 |
24 |
25 | {title}
26 |
27 |
28 |
29 |
30 |
31 | {description}
32 |
33 |
34 |
35 | Full Name:{" "}
36 |
37 |
38 | {name}
39 |
40 |
41 |
42 |
43 | Mobile:{" "}
44 |
45 |
46 | {mobile}
47 |
48 |
49 |
50 |
51 | Email:{" "}
52 |
53 |
54 | {email}
55 |
56 |
57 |
58 |
59 | Location:{" "}
60 |
61 |
62 | {location}
63 |
64 |
65 |
66 |
67 | Social Media:{" "}
68 |
69 |
70 |
76 |
77 |
78 |
84 |
85 |
86 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 | );
100 | };
101 |
102 | export default ProfileInformation;
103 |
--------------------------------------------------------------------------------
/react-ui/public/index.html:
--------------------------------------------------------------------------------
1 |
20 |
21 |
22 |
23 |
24 |
28 |
29 |
33 |
34 |
35 |
40 |
44 |
45 |
51 |
57 |
58 |
62 |
67 |
71 |
72 |
73 |
82 | Purity UI Dashboard by Creative Tim & Simmmple
83 |
84 |
85 |
86 |
87 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/react-ui/src/views/Dashboard/Dashboard/index.js:
--------------------------------------------------------------------------------
1 | // Chakra imports
2 | import {
3 | Flex,
4 | Grid,
5 | Image,
6 | SimpleGrid,
7 | useColorModeValue,
8 | } from "@chakra-ui/react";
9 | // assets
10 | import peopleImage from "assets/img/people-image.png";
11 | import logoChakra from "assets/svg/logo-white.svg";
12 | import BarChart from "components/Charts/BarChart";
13 | import LineChart from "components/Charts/LineChart";
14 | // Custom icons
15 | import {
16 | CartIcon,
17 | DocumentIcon,
18 | GlobeIcon,
19 | WalletIcon,
20 | } from "components/Icons/Icons.js";
21 | import React from "react";
22 | import { dashboardTableData, timelineData } from "variables/general";
23 | import ActiveUsers from "./components/ActiveUsers";
24 | import BuiltByDevelopers from "./components/BuiltByDevelopers";
25 | import MiniStatistics from "./components/MiniStatistics";
26 | import OrdersOverview from "./components/OrdersOverview";
27 | import Projects from "./components/Projects";
28 | import SalesOverview from "./components/SalesOverview";
29 | import WorkWithTheRockets from "./components/WorkWithTheRockets";
30 |
31 | export default function Dashboard() {
32 | const iconBoxInside = useColorModeValue("white", "white");
33 |
34 | return (
35 |
36 |
37 | }
42 | />
43 | }
48 | />
49 | }
54 | />
55 | }
60 | />
61 |
62 |
67 |
79 | }
80 | />
81 |
88 |
89 |
94 | }
98 | />
99 | }
103 | />
104 |
105 |
109 |
115 |
120 |
121 |
122 | );
123 | }
124 |
--------------------------------------------------------------------------------
/react-ui/src/views/Dashboard/RTL/index.js:
--------------------------------------------------------------------------------
1 | // Chakra imports
2 | import {
3 | Flex,
4 | Grid,
5 | Image,
6 | SimpleGrid,
7 | useColorModeValue,
8 | } from "@chakra-ui/react";
9 | // assets
10 | import peopleImage from "assets/img/people-image.png";
11 | import logoChakra from "assets/svg/logo-white.svg";
12 | import BarChart from "components/Charts/BarChart";
13 | import LineChart from "components/Charts/LineChart";
14 | // Custom icons
15 | import {
16 | CartIcon,
17 | DocumentIcon,
18 | GlobeIcon,
19 | WalletIcon,
20 | } from "components/Icons/Icons.js";
21 | import React from "react";
22 | import { rtlDashboardTableData, rtlTimelineData } from "variables/general";
23 | import ActiveUsers from "../Dashboard/components/ActiveUsers";
24 | import BuiltByDevelopers from "../Dashboard/components/BuiltByDevelopers";
25 | import MiniStatistics from "../Dashboard/components/MiniStatistics";
26 | import OrdersOverview from "../Dashboard/components/OrdersOverview";
27 | import Projects from "../Dashboard/components/Projects";
28 | import SalesOverview from "../Dashboard/components/SalesOverview";
29 | import WorkWithTheRockets from "../Dashboard/components/WorkWithTheRockets";
30 |
31 | export default function Dashboard() {
32 | // Chakra Color Mode
33 |
34 | const iconBoxInside = useColorModeValue("white", "white");
35 |
36 | return (
37 |
38 |
39 | }
44 | />
45 | }
50 | />
51 | }
56 | />
57 | }
62 | />
63 |
64 |
69 |
81 | }
82 | />
83 |
90 |
91 |
96 | }
100 | />
101 | }
105 | />
106 |
107 |
111 |
117 |
122 |
123 |
124 | );
125 | }
126 |
--------------------------------------------------------------------------------
/react-ui/src/layouts/RTL.js:
--------------------------------------------------------------------------------
1 | // Chakra imports
2 | import { ChakraProvider, Portal, useDisclosure } from '@chakra-ui/react';
3 | import { RtlProvider } from 'components/RTLProvider/RTLProvider';
4 | import Configurator from 'components/Configurator/Configurator';
5 | import Footer from 'components/Footer/Footer.js';
6 | // Layout components
7 | import AdminNavbar from 'components/Navbars/AdminNavbar.js';
8 | import Sidebar from 'components/Sidebar';
9 | import React, { useState } from 'react';
10 | import { Redirect, Route, Switch } from 'react-router-dom';
11 | import routes from 'routes.js';
12 | // Custom Chakra theme
13 | import theme from 'theme/theme.js';
14 | import FixedPlugin from '../components/FixedPlugin/FixedPlugin';
15 | // Custom components
16 | import MainPanel from '../components/Layout/MainPanel';
17 | import PanelContainer from '../components/Layout/PanelContainer';
18 | import '@fontsource/roboto/400.css';
19 | import '@fontsource/roboto/500.css';
20 | import '@fontsource/roboto/700.css';
21 | import PanelContent from '../components/Layout/PanelContent';
22 | export default function Dashboard(props) {
23 | const { ...rest } = props;
24 | // states and functions
25 | const [ sidebarVariant, setSidebarVariant ] = useState('transparent');
26 | const [ fixed, setFixed ] = useState(false);
27 | const getRoute = () => {
28 | return window.location.pathname !== '/admin/full-screen-maps';
29 | };
30 | const getActiveRoute = (routes) => {
31 | let activeRoute = 'Default Brand Text';
32 | for (let i = 0; i < routes.length; i++) {
33 | if (routes[i].collapse) {
34 | let collapseActiveRoute = getActiveRoute(routes[i].views);
35 | if (collapseActiveRoute !== activeRoute) {
36 | return collapseActiveRoute;
37 | }
38 | } else if (routes[i].category) {
39 | let categoryActiveRoute = getActiveRoute(routes[i].views);
40 | if (categoryActiveRoute !== activeRoute) {
41 | return categoryActiveRoute;
42 | }
43 | } else {
44 | if (window.location.href.indexOf(routes[i].layout + routes[i].path) !== -1) {
45 | return routes[i].name;
46 | }
47 | }
48 | }
49 | return activeRoute;
50 | };
51 | // This changes navbar state(fixed or not)
52 | const getActiveNavbar = (routes) => {
53 | let activeNavbar = false;
54 | for (let i = 0; i < routes.length; i++) {
55 | if (routes[i].category) {
56 | let categoryActiveNavbar = getActiveNavbar(routes[i].views);
57 | if (categoryActiveNavbar !== activeNavbar) {
58 | return categoryActiveNavbar;
59 | }
60 | } else {
61 | if (window.location.href.indexOf(routes[i].layout + routes[i].path) !== -1) {
62 | if (routes[i].secondaryNavbar) {
63 | return routes[i].secondaryNavbar;
64 | }
65 | }
66 | }
67 | }
68 | return activeNavbar;
69 | };
70 | const getRoutes = (routes) => {
71 | return routes.map((prop, key) => {
72 | if (prop.collapse) {
73 | return getRoutes(prop.views);
74 | }
75 | if (prop.category === 'account') {
76 | return getRoutes(prop.views);
77 | }
78 | if (prop.layout === '/rtl' || prop.layout === '/admin') {
79 | return ;
80 | } else {
81 | return null;
82 | }
83 | });
84 | };
85 | const { isOpen, onOpen, onClose } = useDisclosure();
86 | document.documentElement.dir = 'rtl';
87 | // Chakra Color Mode
88 | return (
89 |
90 |
91 |
98 |
104 |
105 |
113 |
114 | {getRoute() ? (
115 |
116 |
117 |
118 | {getRoutes(routes)}
119 |
120 |
121 |
122 |
123 | ) : null}
124 |
125 |
126 |
127 |
128 | {
134 | setFixed(value);
135 | }}
136 | onOpaque={() => setSidebarVariant('opaque')}
137 | onTransparent={() => setSidebarVariant('transparent')}
138 | />
139 |
140 |
141 |
142 | );
143 | }
144 |
--------------------------------------------------------------------------------