Upload folder using huggingface_hub
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- .github/ISSUE_TEMPLATE/bug_report.md +40 -0
- .github/ISSUE_TEMPLATE/custom.md +7 -0
- .github/ISSUE_TEMPLATE/feature_request.md +19 -0
- .github/workflows/prod.yml +48 -0
- CODE_OF_CONDUCT.md +128 -0
- LICENSE +21 -0
- README.md +174 -0
- remix/.eslintrc +56 -0
- remix/.gitignore +6 -0
- remix/.prettierrc +8 -0
- remix/README.md +57 -0
- remix/app/assets/images/auth/auth-blue-card.svg +65 -0
- remix/app/assets/images/auth/auth-pattern-dark.svg +39 -0
- remix/app/assets/images/auth/auth-pattern.svg +39 -0
- remix/app/assets/images/auth/auth-purple-card.svg +69 -0
- remix/app/assets/images/auth/auth-signup-blue-card.svg +0 -0
- remix/app/assets/images/auth/auth-signup-white-card.svg +40 -0
- remix/app/assets/images/icons/earning.svg +5 -0
- remix/app/assets/images/icons/social-google.svg +6 -0
- remix/app/assets/images/logo-dark.svg +12 -0
- remix/app/assets/images/logo-white.svg +12 -0
- remix/app/assets/images/logo.svg +12 -0
- remix/app/assets/images/maintenance/img-error-bg-dark.svg +34 -0
- remix/app/assets/images/maintenance/img-error-bg.svg +34 -0
- remix/app/assets/images/maintenance/img-error-blue.svg +43 -0
- remix/app/assets/images/maintenance/img-error-purple.svg +42 -0
- remix/app/assets/images/maintenance/img-error-text.svg +27 -0
- remix/app/assets/images/users/user-round.svg +0 -0
- remix/app/components/authentication/AuthCardWrapper.js +33 -0
- remix/app/components/authentication/AuthWrapper1.js +11 -0
- remix/app/components/authentication/auth-forms/AuthLogin.js +247 -0
- remix/app/components/authentication/auth-forms/AuthRegister.js +306 -0
- remix/app/components/dashboard/BajajAreaChartCard.client.js +63 -0
- remix/app/components/dashboard/EarningCard.js +189 -0
- remix/app/components/dashboard/PopularCard.js +311 -0
- remix/app/components/dashboard/TotalGrowthBarCard.js +84 -0
- remix/app/components/dashboard/TotalGrowthBarChart.client.js +82 -0
- remix/app/components/dashboard/TotalIncomeDarkCard.js +100 -0
- remix/app/components/dashboard/TotalIncomeLightCard.js +100 -0
- remix/app/components/dashboard/TotalOrderLineCard.js +190 -0
- remix/app/components/dashboard/TotalOrderLineChartCard.client.js +21 -0
- remix/app/components/dashboard/chart-data/bajaj-area-chart.js +42 -0
- remix/app/components/dashboard/chart-data/total-growth-bar-chart.js +87 -0
- remix/app/components/dashboard/chart-data/total-order-month-line-chart.js +52 -0
- remix/app/components/dashboard/chart-data/total-order-year-line-chart.js +52 -0
- remix/app/entry.client.js +22 -0
- remix/app/entry.server.js +30 -0
- remix/app/error/errorPage.js +124 -0
- remix/app/error/index.js +26 -0
- remix/app/hooks/useScriptRef.js +18 -0
.github/ISSUE_TEMPLATE/bug_report.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
name: Bug report
|
| 3 |
+
about: Create a report to help us improve
|
| 4 |
+
title: ''
|
| 5 |
+
labels: ''
|
| 6 |
+
assignees: ''
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
**Describe the bug**
|
| 10 |
+
A clear and concise description of what the bug is.
|
| 11 |
+
|
| 12 |
+
**To Reproduce**
|
| 13 |
+
Steps to reproduce the behavior:
|
| 14 |
+
|
| 15 |
+
1. Go to '...'
|
| 16 |
+
2. Click on '....'
|
| 17 |
+
3. Scroll down to '....'
|
| 18 |
+
4. See error
|
| 19 |
+
|
| 20 |
+
**Expected behavior**
|
| 21 |
+
A clear and concise description of what you expected to happen.
|
| 22 |
+
|
| 23 |
+
**Screenshots**
|
| 24 |
+
If applicable, add screenshots to help explain your problem.
|
| 25 |
+
|
| 26 |
+
**Desktop (please complete the following information):**
|
| 27 |
+
|
| 28 |
+
- OS: [e.g. iOS]
|
| 29 |
+
- Browser [e.g. chrome, safari]
|
| 30 |
+
- Version [e.g. 22]
|
| 31 |
+
|
| 32 |
+
**Smartphone (please complete the following information):**
|
| 33 |
+
|
| 34 |
+
- Device: [e.g. iPhone6]
|
| 35 |
+
- OS: [e.g. iOS8.1]
|
| 36 |
+
- Browser [e.g. stock browser, safari]
|
| 37 |
+
- Version [e.g. 22]
|
| 38 |
+
|
| 39 |
+
**Additional context**
|
| 40 |
+
Add any other context about the problem here.
|
.github/ISSUE_TEMPLATE/custom.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
name: Custom issue template
|
| 3 |
+
about: Describe this issue template's purpose here.
|
| 4 |
+
title: ''
|
| 5 |
+
labels: ''
|
| 6 |
+
assignees: ''
|
| 7 |
+
---
|
.github/ISSUE_TEMPLATE/feature_request.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
name: Feature request
|
| 3 |
+
about: Suggest an idea for this project
|
| 4 |
+
title: ''
|
| 5 |
+
labels: ''
|
| 6 |
+
assignees: ''
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
**Is your feature request related to a problem? Please describe.**
|
| 10 |
+
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
| 11 |
+
|
| 12 |
+
**Describe the solution you'd like**
|
| 13 |
+
A clear and concise description of what you want to happen.
|
| 14 |
+
|
| 15 |
+
**Describe alternatives you've considered**
|
| 16 |
+
A clear and concise description of any alternative solutions or features you've considered.
|
| 17 |
+
|
| 18 |
+
**Additional context**
|
| 19 |
+
Add any other context or screenshots about the feature request here.
|
.github/workflows/prod.yml
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
name: Prod deploy
|
| 2 |
+
|
| 3 |
+
# Controls when the action will run.
|
| 4 |
+
on:
|
| 5 |
+
# Triggers the workflow on push or pull request events but only for the master branch
|
| 6 |
+
push:
|
| 7 |
+
branches:
|
| 8 |
+
- main
|
| 9 |
+
pull_request:
|
| 10 |
+
types:
|
| 11 |
+
- closed
|
| 12 |
+
branches:
|
| 13 |
+
- main
|
| 14 |
+
|
| 15 |
+
jobs:
|
| 16 |
+
if_merged:
|
| 17 |
+
if: github.event.pull_request.merged == true
|
| 18 |
+
name: 🎉 Deploy
|
| 19 |
+
runs-on: ubuntu-latest
|
| 20 |
+
|
| 21 |
+
steps:
|
| 22 |
+
- name: 🚚 Get latest code
|
| 23 |
+
uses: actions/checkout@v4
|
| 24 |
+
|
| 25 |
+
- name: Use Node.js 24
|
| 26 |
+
uses: actions/setup-node@v4
|
| 27 |
+
with:
|
| 28 |
+
node-version: "24"
|
| 29 |
+
|
| 30 |
+
- name: 🔨 Build Project
|
| 31 |
+
run: |
|
| 32 |
+
cd vite
|
| 33 |
+
corepack enable
|
| 34 |
+
yarn set version 4.10.3
|
| 35 |
+
yarn
|
| 36 |
+
yarn build
|
| 37 |
+
|
| 38 |
+
- name: 📂 Deploy to Server
|
| 39 |
+
uses: easingthemes/ssh-deploy@v4
|
| 40 |
+
env:
|
| 41 |
+
SSH_PRIVATE_KEY: ${{ secrets.SERVER_SSH_KEY }}
|
| 42 |
+
# ARGS: "-rltgoDzvO --delete"
|
| 43 |
+
SOURCE: "vite/dist/"
|
| 44 |
+
REMOTE_HOST: 145.79.3.173
|
| 45 |
+
REMOTE_USER: u965251139
|
| 46 |
+
REMOTE_PORT: "65002"
|
| 47 |
+
TARGET: domains/berrydashboard.com/public_html/free
|
| 48 |
+
EXCLUDE: "/vite/node_modules/"
|
CODE_OF_CONDUCT.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Contributor Covenant Code of Conduct
|
| 2 |
+
|
| 3 |
+
## Our Pledge
|
| 4 |
+
|
| 5 |
+
We as members, contributors, and leaders pledge to make participation in our
|
| 6 |
+
community a harassment-free experience for everyone, regardless of age, body
|
| 7 |
+
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
| 8 |
+
identity and expression, level of experience, education, socio-economic status,
|
| 9 |
+
nationality, personal appearance, race, religion, or sexual identity
|
| 10 |
+
and orientation.
|
| 11 |
+
|
| 12 |
+
We pledge to act and interact in ways that contribute to an open, welcoming,
|
| 13 |
+
diverse, inclusive, and healthy community.
|
| 14 |
+
|
| 15 |
+
## Our Standards
|
| 16 |
+
|
| 17 |
+
Examples of behavior that contributes to a positive environment for our
|
| 18 |
+
community include:
|
| 19 |
+
|
| 20 |
+
- Demonstrating empathy and kindness toward other people
|
| 21 |
+
- Being respectful of differing opinions, viewpoints, and experiences
|
| 22 |
+
- Giving and gracefully accepting constructive feedback
|
| 23 |
+
- Accepting responsibility and apologizing to those affected by our mistakes,
|
| 24 |
+
and learning from the experience
|
| 25 |
+
- Focusing on what is best not just for us as individuals, but for the
|
| 26 |
+
overall community
|
| 27 |
+
|
| 28 |
+
Examples of unacceptable behavior include:
|
| 29 |
+
|
| 30 |
+
- The use of sexualized language or imagery, and sexual attention or
|
| 31 |
+
advances of any kind
|
| 32 |
+
- Trolling, insulting or derogatory comments, and personal or political attacks
|
| 33 |
+
- Public or private harassment
|
| 34 |
+
- Publishing others' private information, such as a physical or email
|
| 35 |
+
address, without their explicit permission
|
| 36 |
+
- Other conduct which could reasonably be considered inappropriate in a
|
| 37 |
+
professional setting
|
| 38 |
+
|
| 39 |
+
## Enforcement Responsibilities
|
| 40 |
+
|
| 41 |
+
Community leaders are responsible for clarifying and enforcing our standards of
|
| 42 |
+
acceptable behavior and will take appropriate and fair corrective action in
|
| 43 |
+
response to any behavior that they deem inappropriate, threatening, offensive,
|
| 44 |
+
or harmful.
|
| 45 |
+
|
| 46 |
+
Community leaders have the right and responsibility to remove, edit, or reject
|
| 47 |
+
comments, commits, code, wiki edits, issues, and other contributions that are
|
| 48 |
+
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
| 49 |
+
decisions when appropriate.
|
| 50 |
+
|
| 51 |
+
## Scope
|
| 52 |
+
|
| 53 |
+
This Code of Conduct applies within all community spaces, and also applies when
|
| 54 |
+
an individual is officially representing the community in public spaces.
|
| 55 |
+
Examples of representing our community include using an official e-mail address,
|
| 56 |
+
posting via an official social media account, or acting as an appointed
|
| 57 |
+
representative at an online or offline event.
|
| 58 |
+
|
| 59 |
+
## Enforcement
|
| 60 |
+
|
| 61 |
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
| 62 |
+
reported to the community leaders responsible for enforcement at
|
| 63 |
+
codedthemes@gmail.com.
|
| 64 |
+
All complaints will be reviewed and investigated promptly and fairly.
|
| 65 |
+
|
| 66 |
+
All community leaders are obligated to respect the privacy and security of the
|
| 67 |
+
reporter of any incident.
|
| 68 |
+
|
| 69 |
+
## Enforcement Guidelines
|
| 70 |
+
|
| 71 |
+
Community leaders will follow these Community Impact Guidelines in determining
|
| 72 |
+
the consequences for any action they deem in violation of this Code of Conduct:
|
| 73 |
+
|
| 74 |
+
### 1. Correction
|
| 75 |
+
|
| 76 |
+
**Community Impact**: Use of inappropriate language or other behavior deemed
|
| 77 |
+
unprofessional or unwelcome in the community.
|
| 78 |
+
|
| 79 |
+
**Consequence**: A private, written warning from community leaders, providing
|
| 80 |
+
clarity around the nature of the violation and an explanation of why the
|
| 81 |
+
behavior was inappropriate. A public apology may be requested.
|
| 82 |
+
|
| 83 |
+
### 2. Warning
|
| 84 |
+
|
| 85 |
+
**Community Impact**: A violation through a single incident or series
|
| 86 |
+
of actions.
|
| 87 |
+
|
| 88 |
+
**Consequence**: A warning with consequences for continued behavior. No
|
| 89 |
+
interaction with the people involved, including unsolicited interaction with
|
| 90 |
+
those enforcing the Code of Conduct, for a specified period of time. This
|
| 91 |
+
includes avoiding interactions in community spaces as well as external channels
|
| 92 |
+
like social media. Violating these terms may lead to a temporary or
|
| 93 |
+
permanent ban.
|
| 94 |
+
|
| 95 |
+
### 3. Temporary Ban
|
| 96 |
+
|
| 97 |
+
**Community Impact**: A serious violation of community standards, including
|
| 98 |
+
sustained inappropriate behavior.
|
| 99 |
+
|
| 100 |
+
**Consequence**: A temporary ban from any sort of interaction or public
|
| 101 |
+
communication with the community for a specified period of time. No public or
|
| 102 |
+
private interaction with the people involved, including unsolicited interaction
|
| 103 |
+
with those enforcing the Code of Conduct, is allowed during this period.
|
| 104 |
+
Violating these terms may lead to a permanent ban.
|
| 105 |
+
|
| 106 |
+
### 4. Permanent Ban
|
| 107 |
+
|
| 108 |
+
**Community Impact**: Demonstrating a pattern of violation of community
|
| 109 |
+
standards, including sustained inappropriate behavior, harassment of an
|
| 110 |
+
individual, or aggression toward or disparagement of classes of individuals.
|
| 111 |
+
|
| 112 |
+
**Consequence**: A permanent ban from any sort of public interaction within
|
| 113 |
+
the community.
|
| 114 |
+
|
| 115 |
+
## Attribution
|
| 116 |
+
|
| 117 |
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
| 118 |
+
version 2.0, available at
|
| 119 |
+
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
| 120 |
+
|
| 121 |
+
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
| 122 |
+
enforcement ladder](https://github.com/mozilla/diversity).
|
| 123 |
+
|
| 124 |
+
[homepage]: https://www.contributor-covenant.org
|
| 125 |
+
|
| 126 |
+
For answers to common questions about this code of conduct, see the FAQ at
|
| 127 |
+
https://www.contributor-covenant.org/faq. Translations are available at
|
| 128 |
+
https://www.contributor-covenant.org/translations.
|
LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
MIT License
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2026 CodedThemes
|
| 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.
|
README.md
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Berry Free React Material UI Admin Template [](https://twitter.com/intent/tweet?text=Get%20Berry%20React%20-%20The%20most%20beautiful%20Material%20designed%20Admin%20Dashboard%20Template%20&url=https://berrydashboard.com&via=codedthemes&hashtags=reactjs,webdev,developers,javascript)
|
| 2 |
+
|
| 3 |
+
[](https://opensource.org/licenses/MIT)
|
| 4 |
+
[](https://github.com/codedthemes/berry-free-react-admin-template/blob/main/LICENSE)
|
| 5 |
+
[](https://github.com/codedthemes/berry-free-react-admin-template/)
|
| 6 |
+
[](https://codedthemes.com/item/berry-mui-free-react-admin-template/)
|
| 7 |
+
[](https://discord.com/invite/p2E2WhCb6s)
|
| 8 |
+
|
| 9 |
+
Berry is a free Material UI admin dashboard template built with React. It is meant to provide the best possible User Experience with highly customizable feature-rich pages. It is a complete Dashboard Template that has easy and intuitive responsive design whether it is viewed on retina screens or laptops.
|
| 10 |
+
|
| 11 |
+
✨ Support us! If you like this theme, click the ⭐ (Top right) and let it shine
|
| 12 |
+
|
| 13 |
+

|
| 14 |
+
|
| 15 |
+
## Table of contents
|
| 16 |
+
|
| 17 |
+
- [Getting Started](#getting-started)
|
| 18 |
+
- [Download](#download)
|
| 19 |
+
- [Why Berry?](#why-berry)
|
| 20 |
+
- [What's included in Premium Version?](#whats-included-in-premium-version)
|
| 21 |
+
- [Documentation](#documentation)
|
| 22 |
+
- [Browser support](#browser-support)
|
| 23 |
+
- [Technology Stack](#technology-stack)
|
| 24 |
+
- [Berry Figma UI Kit](#berry-figma-ui-kit)
|
| 25 |
+
- [Other Technologies](#other-technologies)
|
| 26 |
+
- 💰[Save more with Big Bundle](#save-more-with-big-bundle)💰
|
| 27 |
+
- [More React Dashboard Templates](#more-react-dashboard-templates)
|
| 28 |
+
- [Issues?](#issues)
|
| 29 |
+
- [License](#license)
|
| 30 |
+
- [Contributor](#contributor)
|
| 31 |
+
- [Useful Resources](#useful-resources)
|
| 32 |
+
- [Community](#community)
|
| 33 |
+
- [Follow us](#follow-us)
|
| 34 |
+
|
| 35 |
+
## Getting Started
|
| 36 |
+
|
| 37 |
+
Clone from Github
|
| 38 |
+
|
| 39 |
+
```
|
| 40 |
+
git clone https://github.com/codedthemes/berry-free-react-admin-template.git
|
| 41 |
+
```
|
| 42 |
+
|
| 43 |
+
## Download
|
| 44 |
+
|
| 45 |
+
- Berry Free
|
| 46 |
+
- [Live Preview](https://berrydashboard.com/free/)
|
| 47 |
+
- [Download](https://github.com/codedthemes/berry-free-react-admin-template)
|
| 48 |
+
- Berry
|
| 49 |
+
- [Live Preview](https://berrydashboard.com)
|
| 50 |
+
- [Download](https://material-ui.com/store/items/berry-react-material-admin/)
|
| 51 |
+
|
| 52 |
+
## Why Berry?
|
| 53 |
+
|
| 54 |
+
Berry offers everything you need to create dashboards. We have included the following high-end features in our initial release:
|
| 55 |
+
|
| 56 |
+
- Modern aesthetics UI design
|
| 57 |
+
- Material-UI components
|
| 58 |
+
- Fully Responsive, all modern browser supported
|
| 59 |
+
- Easy to use code structure
|
| 60 |
+
- Flexible & High-Performance code
|
| 61 |
+
- Easy Documentation Guide
|
| 62 |
+
|
| 63 |
+
## What's included in Premium Version?
|
| 64 |
+
|
| 65 |
+
[Pro version](https://berrydashboard.com) of Berry react template contains features like TypeScript, Next.js Seed versions, Apps, Authentication Methods (i.e. JWT, Auth0, Firebase, AWS, Supabase), Advance Components, Form Plugins, Layouts, Widgets, and many more.
|
| 66 |
+
|
| 67 |
+
| [Berry Free](https://berrydashboard.com/free/) | [Berry](https://material-ui.com/store/items/berry-react-material-admin/) |
|
| 68 |
+
| ---------------------------------------------- | :----------------------------------------------------------------------- |
|
| 69 |
+
| **9** Demo pages | **45+** demo pages |
|
| 70 |
+
| - | ✓ Multi-language |
|
| 71 |
+
| - | ✓ Dark/Light Mode 🌓 |
|
| 72 |
+
| - | ✓ TypeScript version |
|
| 73 |
+
| - | ✓ Design files (Figma) |
|
| 74 |
+
| - | ✓ 6+ color Options |
|
| 75 |
+
| - | ✓ RTL |
|
| 76 |
+
| - | ✓ JWT, Firebase, Auth0, AWS, Supabase authentications |
|
| 77 |
+
| - | ✓ [More components](https://berrydashboard.com/components/autocomplete) |
|
| 78 |
+
|
| 79 |
+
## Documentation
|
| 80 |
+
|
| 81 |
+
[Berry Documentation](https://codedthemes.gitbook.io/berry/) helps you with installation, deployment, and troubleshooting.
|
| 82 |
+
|
| 83 |
+
## Browser support
|
| 84 |
+
|
| 85 |
+
<img src="https://org-public-assets.s3.us-west-2.amazonaws.com/logos/chrome.png" width="45" height="45" > <img src="https://org-public-assets.s3.us-west-2.amazonaws.com/logos/edge.png" width="45" height="45" > <img src="https://org-public-assets.s3.us-west-2.amazonaws.com/logos/safari.png" width="45" height="45" > <img src="https://org-public-assets.s3.us-west-2.amazonaws.com/logos/firefox.png" width="45" height="45" > <img src="https://org-public-assets.s3.us-west-2.amazonaws.com/logos/opera.png" width="45" height="45" >
|
| 86 |
+
|
| 87 |
+
## Technology Stack
|
| 88 |
+
|
| 89 |
+
- [Material UI V7](https://material-ui.com/)
|
| 90 |
+
- [React 19.2](https://react.dev/)
|
| 91 |
+
- Built with React Hooks API
|
| 92 |
+
- Redux & React Context API for State Management
|
| 93 |
+
- React Router for Navigation Routing
|
| 94 |
+
- Support of vite
|
| 95 |
+
- Code Splitting
|
| 96 |
+
- CSS-in-JS where CSS is composed using JavaScript instead of defined in external files
|
| 97 |
+
|
| 98 |
+
## Berry Figma UI Kit
|
| 99 |
+
|
| 100 |
+
<div>
|
| 101 |
+
<a href="https://codedthemes.com/item/berry-free-figma-ui-kit/">
|
| 102 |
+
<img src="https://org-public-assets.s3.us-west-2.amazonaws.com/Banners/Figma_Free_Berry.png" width="450" alt="Figma Free">
|
| 103 |
+
</a>
|
| 104 |
+
<a href="https://codedthemes.com/item/berry-figma-ui-kit/">
|
| 105 |
+
<img src="https://org-public-assets.s3.us-west-2.amazonaws.com/Banners/Figma-Pro-Berry.png" width="450" alt="Figma Pro">
|
| 106 |
+
</a>
|
| 107 |
+
</div>
|
| 108 |
+
|
| 109 |
+
## Other Technologies
|
| 110 |
+
|
| 111 |
+
| Technology | Free | Pro |
|
| 112 |
+
| --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
|
| 113 |
+
| <p align="center"><img src="https://org-public-assets.s3.us-west-2.amazonaws.com/logos/Angular.png" width="25" height="25"></p> | [**Free**](https://codedthemes.com/item/berry-angular-free-admin-template/) | [**Pro**](https://codedthemes.com/item/berry-angular-admin-dashboard-template/) |
|
| 114 |
+
| <p align="center"><img src="https://org-public-assets.s3.us-west-2.amazonaws.com/logos/Bootstrap.png" width="30" height="30"></p> | [**Free**](https://codedthemes.com/item/berry-bootstrap-free-admin-template/) | [**Pro**](https://codedthemes.com/item/berry-bootstrap-5-admin-template/) |
|
| 115 |
+
| <p align="center"><img src="https://org-public-assets.s3.us-west-2.amazonaws.com/logos/Vue.png" width="25" height="25"></p> | [**Free**](https://codedthemes.com/item/berry-free-vuetify-vuejs-admin-template/) | [**Pro**](https://codedthemes.com/item/berry-vue-admin-dashboard/) |
|
| 116 |
+
|
| 117 |
+
## Save more with Big Bundle
|
| 118 |
+
|
| 119 |
+
[](https://links.codedthemes.com/jhFBJ)
|
| 120 |
+
|
| 121 |
+
## More React Dashboard Templates
|
| 122 |
+
|
| 123 |
+
| Dashboard | FREE | PRO |
|
| 124 |
+
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
|
| 125 |
+
| <img src="https://org-public-assets.s3.us-west-2.amazonaws.com/logos/Mantis%20with%20name.png" height="30" style="display:inline-block; vertical-align:middle;"> | [**Free**](https://mantisdashboard.com/free/) | [**Pro**](https://mui.com/store/items/mantis-react-admin-dashboard-template/)</span> |
|
| 126 |
+
| <img src="https://org-public-assets.s3.us-west-2.amazonaws.com/logos/Datta%20with%20name.png" height="30" style="display:inline-block; vertical-align:middle;"> | [**Free**](https://codedthemes.com/item/datta-able-react-free-admin-template/) | [**Pro**](https://codedthemes.com/item/datta-able-react-admin-template/)</span> |
|
| 127 |
+
| <img src="https://org-public-assets.s3.us-west-2.amazonaws.com/logos/Gradient%20with%20name.png" height="30" style="display:inline-block; vertical-align:middle;"> | [**Free**](https://codedthemes.com/item/gradient-able-reactjs-free-admin-template/) | [**Pro**](https://codedthemes.com/item/gradient-able-reactjs-admin-dashboard/)</span> |
|
| 128 |
+
|
| 129 |
+
## Issues
|
| 130 |
+
|
| 131 |
+
To report a bug, please submit an [issue](https://github.com/codedthemes/berry-free-react-admin-template/issues) on Github. We will respond as soon as possible to resolve the issue.
|
| 132 |
+
|
| 133 |
+
## License
|
| 134 |
+
|
| 135 |
+
- Licensed cover under [MIT](https://github.com/codedthemes/berry-free-react-admin-template/blob/main/LICENSE)
|
| 136 |
+
|
| 137 |
+
## Contributor
|
| 138 |
+
|
| 139 |
+
**CodedThemes Team**
|
| 140 |
+
|
| 141 |
+
- https://x.com/codedthemes
|
| 142 |
+
- https://github.com/codedthemes
|
| 143 |
+
|
| 144 |
+
**Rakesh Nakrani**
|
| 145 |
+
|
| 146 |
+
- https://x.com/rakesh_nakrani
|
| 147 |
+
|
| 148 |
+
**Brijesh Dobariya**
|
| 149 |
+
|
| 150 |
+
- https://x.com/dobaria_brijesh
|
| 151 |
+
|
| 152 |
+
## Useful Resources
|
| 153 |
+
|
| 154 |
+
- [More Admin Templates From CodedThemes](https://codedthemes.com/item/category/admin-templates/)
|
| 155 |
+
- [Freebies From CodedThemes](https://codedthemes.com/item/category/free-templates/)
|
| 156 |
+
- [Big Bundles](https://codedthemes.com/item/big-bundle/)
|
| 157 |
+
- [Figma UI Kits](https://codedthemes.com/item/category/templates/figma/)
|
| 158 |
+
- [Affiliate Program](https://codedthemes.com/affiliate/)
|
| 159 |
+
- [Blogs](https://blog.codedthemes.com/)
|
| 160 |
+
|
| 161 |
+
## Community
|
| 162 |
+
|
| 163 |
+
- 👥Follow [@codedthemes](https://x.com/codedthemes)
|
| 164 |
+
- 🔗Join [Discord](https://discord.com/invite/p2E2WhCb6s)
|
| 165 |
+
- 🔔Subscribe to [Codedtheme Blogs](https://blog.codedthemes.com/)
|
| 166 |
+
|
| 167 |
+
## Follow us
|
| 168 |
+
|
| 169 |
+
- [Twitter](https://twitter.com/codedthemes) 🐦
|
| 170 |
+
- [Dribbble](https://dribbble.com/codedthemes) 🏀
|
| 171 |
+
- [Github](https://github.com/codedthemes) 🐙
|
| 172 |
+
- [LinkedIn](https://www.linkedin.com/company/codedthemes/) 💼
|
| 173 |
+
- [Instagram](https://www.instagram.com/codedthemes/) 📷
|
| 174 |
+
- [Facebook](https://www.facebook.com/codedthemes) 🟦
|
remix/.eslintrc
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"root": true,
|
| 3 |
+
"env": {
|
| 4 |
+
"browser": true,
|
| 5 |
+
"es2021": true
|
| 6 |
+
},
|
| 7 |
+
"extends": ["prettier", "plugin:react/jsx-runtime", "plugin:jsx-a11y/recommended", "plugin:react-hooks/recommended"],
|
| 8 |
+
"settings": {
|
| 9 |
+
"import/resolver": {
|
| 10 |
+
"node": {
|
| 11 |
+
"moduleDirectory": ["node_modules", "src/"]
|
| 12 |
+
}
|
| 13 |
+
}
|
| 14 |
+
},
|
| 15 |
+
"parser": "@babel/eslint-parser",
|
| 16 |
+
"parserOptions": {
|
| 17 |
+
"ecmaFeatures": {
|
| 18 |
+
"experimentalObjectRestSpread": true,
|
| 19 |
+
"impliedStrict": true
|
| 20 |
+
},
|
| 21 |
+
"ecmaVersion": 12
|
| 22 |
+
},
|
| 23 |
+
"plugins": ["prettier", "react", "react-hooks"],
|
| 24 |
+
"rules": {
|
| 25 |
+
"react/jsx-filename-extension": 0,
|
| 26 |
+
"no-param-reassign": 0,
|
| 27 |
+
"react/prop-types": 1,
|
| 28 |
+
"react/require-default-props": 0,
|
| 29 |
+
"react/no-array-index-key": 0,
|
| 30 |
+
"react/jsx-props-no-spreading": 0,
|
| 31 |
+
"react/forbid-prop-types": 0,
|
| 32 |
+
"import/order": 0,
|
| 33 |
+
"no-console": 0,
|
| 34 |
+
"jsx-a11y/anchor-is-valid": 0,
|
| 35 |
+
"prefer-destructuring": 0,
|
| 36 |
+
"no-shadow": 0,
|
| 37 |
+
"no-unused-vars": [
|
| 38 |
+
1,
|
| 39 |
+
{
|
| 40 |
+
"ignoreRestSiblings": false
|
| 41 |
+
}
|
| 42 |
+
],
|
| 43 |
+
"prettier/prettier": [
|
| 44 |
+
2,
|
| 45 |
+
{
|
| 46 |
+
"bracketSpacing": true,
|
| 47 |
+
"printWidth": 140,
|
| 48 |
+
"singleQuote": true,
|
| 49 |
+
"trailingComma": "none",
|
| 50 |
+
"tabWidth": 4,
|
| 51 |
+
"useTabs": false,
|
| 52 |
+
"endOfLine": "auto"
|
| 53 |
+
}
|
| 54 |
+
]
|
| 55 |
+
}
|
| 56 |
+
}
|
remix/.gitignore
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
node_modules
|
| 2 |
+
|
| 3 |
+
/.cache
|
| 4 |
+
/build
|
| 5 |
+
/public/build
|
| 6 |
+
.env
|
remix/.prettierrc
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"bracketSpacing": true,
|
| 3 |
+
"printWidth": 140,
|
| 4 |
+
"singleQuote": true,
|
| 5 |
+
"trailingComma": "none",
|
| 6 |
+
"tabWidth": 4,
|
| 7 |
+
"useTabs": false
|
| 8 |
+
}
|
remix/README.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Welcome to Remix!
|
| 2 |
+
|
| 3 |
+
- [Remix Docs](https://remix.run/docs)
|
| 4 |
+
|
| 5 |
+
## Development
|
| 6 |
+
|
| 7 |
+
From your terminal:
|
| 8 |
+
|
| 9 |
+
```sh
|
| 10 |
+
npm install
|
| 11 |
+
```
|
| 12 |
+
|
| 13 |
+
```sh
|
| 14 |
+
npm run dev
|
| 15 |
+
```
|
| 16 |
+
|
| 17 |
+
This starts your app in development mode, rebuilding assets on file changes.
|
| 18 |
+
|
| 19 |
+
## Deployment
|
| 20 |
+
|
| 21 |
+
First, build your app for production:
|
| 22 |
+
|
| 23 |
+
```sh
|
| 24 |
+
npm run build
|
| 25 |
+
```
|
| 26 |
+
|
| 27 |
+
Then run the app in production mode:
|
| 28 |
+
|
| 29 |
+
```sh
|
| 30 |
+
npm start
|
| 31 |
+
```
|
| 32 |
+
|
| 33 |
+
Now you'll need to pick a host to deploy it to.
|
| 34 |
+
|
| 35 |
+
### DIY
|
| 36 |
+
|
| 37 |
+
If you're familiar with deploying node applications, the built-in Remix app server is production-ready.
|
| 38 |
+
|
| 39 |
+
Make sure to deploy the output of `remix build`
|
| 40 |
+
|
| 41 |
+
- `build/`
|
| 42 |
+
- `public/build/`
|
| 43 |
+
|
| 44 |
+
### Using a Template
|
| 45 |
+
|
| 46 |
+
When you ran `npx create-remix@latest` there were a few choices for hosting. You can run that again to create a new project, then copy over your `app/` folder to the new project that's pre-configured for your target server.
|
| 47 |
+
|
| 48 |
+
```sh
|
| 49 |
+
cd ..
|
| 50 |
+
# create a new project, and pick a pre-configured host
|
| 51 |
+
npx create-remix@latest
|
| 52 |
+
cd my-new-remix-app
|
| 53 |
+
# remove the new project's app (not the old one!)
|
| 54 |
+
rm -rf app
|
| 55 |
+
# copy your app over
|
| 56 |
+
cp -R ../my-old-remix-app/app app
|
| 57 |
+
```
|
remix/app/assets/images/auth/auth-blue-card.svg
ADDED
|
|
remix/app/assets/images/auth/auth-pattern-dark.svg
ADDED
|
|
remix/app/assets/images/auth/auth-pattern.svg
ADDED
|
|
remix/app/assets/images/auth/auth-purple-card.svg
ADDED
|
|
remix/app/assets/images/auth/auth-signup-blue-card.svg
ADDED
|
|
remix/app/assets/images/auth/auth-signup-white-card.svg
ADDED
|
|
remix/app/assets/images/icons/earning.svg
ADDED
|
|
remix/app/assets/images/icons/social-google.svg
ADDED
|
|
remix/app/assets/images/logo-dark.svg
ADDED
|
|
remix/app/assets/images/logo-white.svg
ADDED
|
|
remix/app/assets/images/logo.svg
ADDED
|
|
remix/app/assets/images/maintenance/img-error-bg-dark.svg
ADDED
|
|
remix/app/assets/images/maintenance/img-error-bg.svg
ADDED
|
|
remix/app/assets/images/maintenance/img-error-blue.svg
ADDED
|
|
remix/app/assets/images/maintenance/img-error-purple.svg
ADDED
|
|
remix/app/assets/images/maintenance/img-error-text.svg
ADDED
|
|
remix/app/assets/images/users/user-round.svg
ADDED
|
|
remix/app/components/authentication/AuthCardWrapper.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// material-ui
|
| 2 |
+
import { Box } from '@mui/material';
|
| 3 |
+
|
| 4 |
+
// project import
|
| 5 |
+
import MainCard from 'ui-component/cards/MainCard';
|
| 6 |
+
|
| 7 |
+
//types
|
| 8 |
+
import PropTypes from 'prop-types';
|
| 9 |
+
|
| 10 |
+
// ==============================|| AUTHENTICATION CARD WRAPPER ||============================== //
|
| 11 |
+
|
| 12 |
+
const AuthCardWrapper = ({ children, ...other }) => (
|
| 13 |
+
<MainCard
|
| 14 |
+
sx={{
|
| 15 |
+
maxWidth: { xs: 400, lg: 475 },
|
| 16 |
+
margin: { xs: 2.5, md: 3 },
|
| 17 |
+
'& > *': {
|
| 18 |
+
flexGrow: 1,
|
| 19 |
+
flexBasis: '50%'
|
| 20 |
+
}
|
| 21 |
+
}}
|
| 22 |
+
content={false}
|
| 23 |
+
{...other}
|
| 24 |
+
>
|
| 25 |
+
<Box sx={{ p: { xs: 2, sm: 3, xl: 5 } }}>{children}</Box>
|
| 26 |
+
</MainCard>
|
| 27 |
+
);
|
| 28 |
+
|
| 29 |
+
AuthCardWrapper.propTypes = {
|
| 30 |
+
children: PropTypes.node
|
| 31 |
+
};
|
| 32 |
+
|
| 33 |
+
export default AuthCardWrapper;
|
remix/app/components/authentication/AuthWrapper1.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// material-ui
|
| 2 |
+
import { styled } from '@mui/material/styles';
|
| 3 |
+
|
| 4 |
+
// ==============================|| AUTHENTICATION 1 WRAPPER ||============================== //
|
| 5 |
+
|
| 6 |
+
const AuthWrapper1 = styled('div')(({ theme }) => ({
|
| 7 |
+
backgroundColor: theme.palette.primary.light,
|
| 8 |
+
minHeight: '100vh'
|
| 9 |
+
}));
|
| 10 |
+
|
| 11 |
+
export default AuthWrapper1;
|
remix/app/components/authentication/auth-forms/AuthLogin.js
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { useState } from 'react';
|
| 2 |
+
import { useSelector } from 'react-redux';
|
| 3 |
+
|
| 4 |
+
// material-ui
|
| 5 |
+
import { useTheme } from '@mui/material/styles';
|
| 6 |
+
import {
|
| 7 |
+
Box,
|
| 8 |
+
Button,
|
| 9 |
+
Checkbox,
|
| 10 |
+
Divider,
|
| 11 |
+
FormControl,
|
| 12 |
+
FormControlLabel,
|
| 13 |
+
FormHelperText,
|
| 14 |
+
Grid,
|
| 15 |
+
IconButton,
|
| 16 |
+
InputAdornment,
|
| 17 |
+
InputLabel,
|
| 18 |
+
OutlinedInput,
|
| 19 |
+
Stack,
|
| 20 |
+
Typography,
|
| 21 |
+
useMediaQuery
|
| 22 |
+
} from '@mui/material';
|
| 23 |
+
|
| 24 |
+
// third party
|
| 25 |
+
import * as Yup from 'yup';
|
| 26 |
+
import { Formik } from 'formik';
|
| 27 |
+
|
| 28 |
+
// project imports
|
| 29 |
+
import useScriptRef from 'hooks/useScriptRef';
|
| 30 |
+
import AnimateButton from 'ui-component/extended/AnimateButton';
|
| 31 |
+
|
| 32 |
+
// assets
|
| 33 |
+
import Visibility from '@mui/icons-material/Visibility';
|
| 34 |
+
import VisibilityOff from '@mui/icons-material/VisibilityOff';
|
| 35 |
+
|
| 36 |
+
import Google from 'assets/images/icons/social-google.svg';
|
| 37 |
+
|
| 38 |
+
// ============================|| FIREBASE - LOGIN ||============================ //
|
| 39 |
+
|
| 40 |
+
const FirebaseLogin = ({ ...others }) => {
|
| 41 |
+
const theme = useTheme();
|
| 42 |
+
const scriptedRef = useScriptRef();
|
| 43 |
+
const matchDownSM = useMediaQuery(theme.breakpoints.down('md'));
|
| 44 |
+
const customization = useSelector((state) => state.customization);
|
| 45 |
+
const [checked, setChecked] = useState(true);
|
| 46 |
+
|
| 47 |
+
const googleHandler = async () => {
|
| 48 |
+
console.error('Login');
|
| 49 |
+
};
|
| 50 |
+
|
| 51 |
+
const [showPassword, setShowPassword] = useState(false);
|
| 52 |
+
const handleClickShowPassword = () => {
|
| 53 |
+
setShowPassword(!showPassword);
|
| 54 |
+
};
|
| 55 |
+
|
| 56 |
+
const handleMouseDownPassword = (event) => {
|
| 57 |
+
event.preventDefault();
|
| 58 |
+
};
|
| 59 |
+
|
| 60 |
+
return (
|
| 61 |
+
<>
|
| 62 |
+
<Grid container direction="column" justifyContent="center" spacing={2}>
|
| 63 |
+
<Grid item xs={12}>
|
| 64 |
+
<AnimateButton>
|
| 65 |
+
<Button
|
| 66 |
+
disableElevation
|
| 67 |
+
fullWidth
|
| 68 |
+
onClick={googleHandler}
|
| 69 |
+
size="large"
|
| 70 |
+
variant="outlined"
|
| 71 |
+
sx={{
|
| 72 |
+
color: 'grey.700',
|
| 73 |
+
backgroundColor: theme.palette.grey[50],
|
| 74 |
+
borderColor: theme.palette.grey[100]
|
| 75 |
+
}}
|
| 76 |
+
>
|
| 77 |
+
<Box sx={{ mr: { xs: 1, sm: 2, width: 20 } }}>
|
| 78 |
+
<img src={Google} alt="google" width={16} height={16} style={{ marginRight: matchDownSM ? 8 : 16 }} />
|
| 79 |
+
</Box>
|
| 80 |
+
Sign in with Google
|
| 81 |
+
</Button>
|
| 82 |
+
</AnimateButton>
|
| 83 |
+
</Grid>
|
| 84 |
+
<Grid item xs={12}>
|
| 85 |
+
<Box
|
| 86 |
+
sx={{
|
| 87 |
+
alignItems: 'center',
|
| 88 |
+
display: 'flex'
|
| 89 |
+
}}
|
| 90 |
+
>
|
| 91 |
+
<Divider sx={{ flexGrow: 1 }} orientation="horizontal" />
|
| 92 |
+
|
| 93 |
+
<Button
|
| 94 |
+
variant="outlined"
|
| 95 |
+
sx={{
|
| 96 |
+
cursor: 'unset',
|
| 97 |
+
m: 2,
|
| 98 |
+
py: 0.5,
|
| 99 |
+
px: 7,
|
| 100 |
+
borderColor: `${theme.palette.grey[100]} !important`,
|
| 101 |
+
color: `${theme.palette.grey[900]}!important`,
|
| 102 |
+
fontWeight: 500,
|
| 103 |
+
borderRadius: `${customization.borderRadius}px`
|
| 104 |
+
}}
|
| 105 |
+
disableRipple
|
| 106 |
+
disabled
|
| 107 |
+
>
|
| 108 |
+
OR
|
| 109 |
+
</Button>
|
| 110 |
+
|
| 111 |
+
<Divider sx={{ flexGrow: 1 }} orientation="horizontal" />
|
| 112 |
+
</Box>
|
| 113 |
+
</Grid>
|
| 114 |
+
<Grid item xs={12} container alignItems="center" justifyContent="center">
|
| 115 |
+
<Box sx={{ mb: 2 }}>
|
| 116 |
+
<Typography variant="subtitle1">Sign in with Email address</Typography>
|
| 117 |
+
</Box>
|
| 118 |
+
</Grid>
|
| 119 |
+
</Grid>
|
| 120 |
+
|
| 121 |
+
<Formik
|
| 122 |
+
initialValues={{
|
| 123 |
+
email: 'info@codedthemes.com',
|
| 124 |
+
password: '123456',
|
| 125 |
+
submit: null
|
| 126 |
+
}}
|
| 127 |
+
validationSchema={Yup.object().shape({
|
| 128 |
+
email: Yup.string().email('Must be a valid email').max(255).required('Email is required'),
|
| 129 |
+
password: Yup.string().max(255).required('Password is required')
|
| 130 |
+
})}
|
| 131 |
+
onSubmit={async (values, { setErrors, setStatus, setSubmitting }) => {
|
| 132 |
+
try {
|
| 133 |
+
if (scriptedRef.current) {
|
| 134 |
+
setStatus({ success: true });
|
| 135 |
+
setSubmitting(false);
|
| 136 |
+
}
|
| 137 |
+
} catch (err) {
|
| 138 |
+
console.error(err);
|
| 139 |
+
if (scriptedRef.current) {
|
| 140 |
+
setStatus({ success: false });
|
| 141 |
+
setErrors({ submit: err.message });
|
| 142 |
+
setSubmitting(false);
|
| 143 |
+
}
|
| 144 |
+
}
|
| 145 |
+
}}
|
| 146 |
+
>
|
| 147 |
+
{({ errors, handleBlur, handleChange, handleSubmit, isSubmitting, touched, values }) => (
|
| 148 |
+
<form noValidate onSubmit={handleSubmit} {...others}>
|
| 149 |
+
<FormControl fullWidth error={Boolean(touched.email && errors.email)} sx={{ ...theme.typography.customInput }}>
|
| 150 |
+
<InputLabel htmlFor="outlined-adornment-email-login">Email Address / Username</InputLabel>
|
| 151 |
+
<OutlinedInput
|
| 152 |
+
id="outlined-adornment-email-login"
|
| 153 |
+
type="email"
|
| 154 |
+
value={values.email}
|
| 155 |
+
name="email"
|
| 156 |
+
onBlur={handleBlur}
|
| 157 |
+
onChange={handleChange}
|
| 158 |
+
label="Email Address / Username"
|
| 159 |
+
inputProps={{}}
|
| 160 |
+
/>
|
| 161 |
+
{touched.email && errors.email && (
|
| 162 |
+
<FormHelperText error id="standard-weight-helper-text-email-login">
|
| 163 |
+
{errors.email}
|
| 164 |
+
</FormHelperText>
|
| 165 |
+
)}
|
| 166 |
+
</FormControl>
|
| 167 |
+
|
| 168 |
+
<FormControl
|
| 169 |
+
fullWidth
|
| 170 |
+
error={Boolean(touched.password && errors.password)}
|
| 171 |
+
sx={{ ...theme.typography.customInput }}
|
| 172 |
+
>
|
| 173 |
+
<InputLabel htmlFor="outlined-adornment-password-login">Password</InputLabel>
|
| 174 |
+
<OutlinedInput
|
| 175 |
+
id="outlined-adornment-password-login"
|
| 176 |
+
type={showPassword ? 'text' : 'password'}
|
| 177 |
+
value={values.password}
|
| 178 |
+
name="password"
|
| 179 |
+
onBlur={handleBlur}
|
| 180 |
+
onChange={handleChange}
|
| 181 |
+
endAdornment={
|
| 182 |
+
<InputAdornment position="end">
|
| 183 |
+
<IconButton
|
| 184 |
+
aria-label="toggle password visibility"
|
| 185 |
+
onClick={handleClickShowPassword}
|
| 186 |
+
onMouseDown={handleMouseDownPassword}
|
| 187 |
+
edge="end"
|
| 188 |
+
size="large"
|
| 189 |
+
>
|
| 190 |
+
{showPassword ? <Visibility /> : <VisibilityOff />}
|
| 191 |
+
</IconButton>
|
| 192 |
+
</InputAdornment>
|
| 193 |
+
}
|
| 194 |
+
label="Password"
|
| 195 |
+
inputProps={{}}
|
| 196 |
+
/>
|
| 197 |
+
{touched.password && errors.password && (
|
| 198 |
+
<FormHelperText error id="standard-weight-helper-text-password-login">
|
| 199 |
+
{errors.password}
|
| 200 |
+
</FormHelperText>
|
| 201 |
+
)}
|
| 202 |
+
</FormControl>
|
| 203 |
+
<Stack direction="row" alignItems="center" justifyContent="space-between" spacing={1}>
|
| 204 |
+
<FormControlLabel
|
| 205 |
+
control={
|
| 206 |
+
<Checkbox
|
| 207 |
+
checked={checked}
|
| 208 |
+
onChange={(event) => setChecked(event.target.checked)}
|
| 209 |
+
name="checked"
|
| 210 |
+
color="primary"
|
| 211 |
+
/>
|
| 212 |
+
}
|
| 213 |
+
label="Remember me"
|
| 214 |
+
/>
|
| 215 |
+
<Typography variant="subtitle1" color="secondary" sx={{ textDecoration: 'none', cursor: 'pointer' }}>
|
| 216 |
+
Forgot Password?
|
| 217 |
+
</Typography>
|
| 218 |
+
</Stack>
|
| 219 |
+
{errors.submit && (
|
| 220 |
+
<Box sx={{ mt: 3 }}>
|
| 221 |
+
<FormHelperText error>{errors.submit}</FormHelperText>
|
| 222 |
+
</Box>
|
| 223 |
+
)}
|
| 224 |
+
|
| 225 |
+
<Box sx={{ mt: 2 }}>
|
| 226 |
+
<AnimateButton>
|
| 227 |
+
<Button
|
| 228 |
+
disableElevation
|
| 229 |
+
disabled={isSubmitting}
|
| 230 |
+
fullWidth
|
| 231 |
+
size="large"
|
| 232 |
+
type="submit"
|
| 233 |
+
variant="contained"
|
| 234 |
+
color="secondary"
|
| 235 |
+
>
|
| 236 |
+
Sign in
|
| 237 |
+
</Button>
|
| 238 |
+
</AnimateButton>
|
| 239 |
+
</Box>
|
| 240 |
+
</form>
|
| 241 |
+
)}
|
| 242 |
+
</Formik>
|
| 243 |
+
</>
|
| 244 |
+
);
|
| 245 |
+
};
|
| 246 |
+
|
| 247 |
+
export default FirebaseLogin;
|
remix/app/components/authentication/auth-forms/AuthRegister.js
ADDED
|
@@ -0,0 +1,306 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { Link } from '@remix-run/react';
|
| 2 |
+
import { useState, useEffect } from 'react';
|
| 3 |
+
import { useSelector } from 'react-redux';
|
| 4 |
+
|
| 5 |
+
// material-ui
|
| 6 |
+
import { useTheme } from '@mui/material/styles';
|
| 7 |
+
import {
|
| 8 |
+
Box,
|
| 9 |
+
Button,
|
| 10 |
+
Checkbox,
|
| 11 |
+
Divider,
|
| 12 |
+
FormControl,
|
| 13 |
+
FormControlLabel,
|
| 14 |
+
FormHelperText,
|
| 15 |
+
Grid,
|
| 16 |
+
IconButton,
|
| 17 |
+
InputAdornment,
|
| 18 |
+
InputLabel,
|
| 19 |
+
OutlinedInput,
|
| 20 |
+
TextField,
|
| 21 |
+
Typography,
|
| 22 |
+
useMediaQuery
|
| 23 |
+
} from '@mui/material';
|
| 24 |
+
|
| 25 |
+
// third party
|
| 26 |
+
import * as Yup from 'yup';
|
| 27 |
+
import { Formik } from 'formik';
|
| 28 |
+
|
| 29 |
+
// project imports
|
| 30 |
+
import useScriptRef from 'hooks/useScriptRef';
|
| 31 |
+
import Google from 'assets/images/icons/social-google.svg';
|
| 32 |
+
import AnimateButton from 'ui-component/extended/AnimateButton';
|
| 33 |
+
import { strengthColor, strengthIndicator } from 'utils/password-strength';
|
| 34 |
+
|
| 35 |
+
// assets
|
| 36 |
+
import Visibility from '@mui/icons-material/Visibility';
|
| 37 |
+
import VisibilityOff from '@mui/icons-material/VisibilityOff';
|
| 38 |
+
|
| 39 |
+
// ===========================|| FIREBASE - REGISTER ||=========================== //
|
| 40 |
+
|
| 41 |
+
const FirebaseRegister = ({ ...others }) => {
|
| 42 |
+
const theme = useTheme();
|
| 43 |
+
const scriptedRef = useScriptRef();
|
| 44 |
+
const matchDownSM = useMediaQuery(theme.breakpoints.down('md'));
|
| 45 |
+
const customization = useSelector((state) => state.customization);
|
| 46 |
+
const [showPassword, setShowPassword] = useState(false);
|
| 47 |
+
const [checked, setChecked] = useState(true);
|
| 48 |
+
|
| 49 |
+
const [strength, setStrength] = useState(0);
|
| 50 |
+
const [level, setLevel] = useState();
|
| 51 |
+
|
| 52 |
+
const googleHandler = async () => {
|
| 53 |
+
console.error('Register');
|
| 54 |
+
};
|
| 55 |
+
|
| 56 |
+
const handleClickShowPassword = () => {
|
| 57 |
+
setShowPassword(!showPassword);
|
| 58 |
+
};
|
| 59 |
+
|
| 60 |
+
const handleMouseDownPassword = (event) => {
|
| 61 |
+
event.preventDefault();
|
| 62 |
+
};
|
| 63 |
+
|
| 64 |
+
const changePassword = (value) => {
|
| 65 |
+
const temp = strengthIndicator(value);
|
| 66 |
+
setStrength(temp);
|
| 67 |
+
setLevel(strengthColor(temp));
|
| 68 |
+
};
|
| 69 |
+
|
| 70 |
+
useEffect(() => {
|
| 71 |
+
changePassword('123456');
|
| 72 |
+
}, []);
|
| 73 |
+
|
| 74 |
+
return (
|
| 75 |
+
<>
|
| 76 |
+
<Grid container direction="column" justifyContent="center" spacing={2}>
|
| 77 |
+
<Grid item xs={12}>
|
| 78 |
+
<AnimateButton>
|
| 79 |
+
<Button
|
| 80 |
+
variant="outlined"
|
| 81 |
+
fullWidth
|
| 82 |
+
onClick={googleHandler}
|
| 83 |
+
size="large"
|
| 84 |
+
sx={{
|
| 85 |
+
color: 'grey.700',
|
| 86 |
+
backgroundColor: theme.palette.grey[50],
|
| 87 |
+
borderColor: theme.palette.grey[100]
|
| 88 |
+
}}
|
| 89 |
+
>
|
| 90 |
+
<Box sx={{ mr: { xs: 1, sm: 2, width: 20 } }}>
|
| 91 |
+
<img src={Google} alt="google" width={16} height={16} style={{ marginRight: matchDownSM ? 8 : 16 }} />
|
| 92 |
+
</Box>
|
| 93 |
+
Sign up with Google
|
| 94 |
+
</Button>
|
| 95 |
+
</AnimateButton>
|
| 96 |
+
</Grid>
|
| 97 |
+
<Grid item xs={12}>
|
| 98 |
+
<Box sx={{ alignItems: 'center', display: 'flex' }}>
|
| 99 |
+
<Divider sx={{ flexGrow: 1 }} orientation="horizontal" />
|
| 100 |
+
<Button
|
| 101 |
+
variant="outlined"
|
| 102 |
+
sx={{
|
| 103 |
+
cursor: 'unset',
|
| 104 |
+
m: 2,
|
| 105 |
+
py: 0.5,
|
| 106 |
+
px: 7,
|
| 107 |
+
borderColor: `${theme.palette.grey[100]} !important`,
|
| 108 |
+
color: `${theme.palette.grey[900]}!important`,
|
| 109 |
+
fontWeight: 500,
|
| 110 |
+
borderRadius: `${customization.borderRadius}px`
|
| 111 |
+
}}
|
| 112 |
+
disableRipple
|
| 113 |
+
disabled
|
| 114 |
+
>
|
| 115 |
+
OR
|
| 116 |
+
</Button>
|
| 117 |
+
<Divider sx={{ flexGrow: 1 }} orientation="horizontal" />
|
| 118 |
+
</Box>
|
| 119 |
+
</Grid>
|
| 120 |
+
<Grid item xs={12} container alignItems="center" justifyContent="center">
|
| 121 |
+
<Box sx={{ mb: 2 }}>
|
| 122 |
+
<Typography variant="subtitle1">Sign up with Email address</Typography>
|
| 123 |
+
</Box>
|
| 124 |
+
</Grid>
|
| 125 |
+
</Grid>
|
| 126 |
+
|
| 127 |
+
<Formik
|
| 128 |
+
initialValues={{
|
| 129 |
+
email: '',
|
| 130 |
+
password: '',
|
| 131 |
+
submit: null
|
| 132 |
+
}}
|
| 133 |
+
validationSchema={Yup.object().shape({
|
| 134 |
+
email: Yup.string().email('Must be a valid email').max(255).required('Email is required'),
|
| 135 |
+
password: Yup.string().max(255).required('Password is required')
|
| 136 |
+
})}
|
| 137 |
+
onSubmit={async (values, { setErrors, setStatus, setSubmitting }) => {
|
| 138 |
+
try {
|
| 139 |
+
if (scriptedRef.current) {
|
| 140 |
+
setStatus({ success: true });
|
| 141 |
+
setSubmitting(false);
|
| 142 |
+
}
|
| 143 |
+
} catch (err) {
|
| 144 |
+
console.error(err);
|
| 145 |
+
if (scriptedRef.current) {
|
| 146 |
+
setStatus({ success: false });
|
| 147 |
+
setErrors({ submit: err.message });
|
| 148 |
+
setSubmitting(false);
|
| 149 |
+
}
|
| 150 |
+
}
|
| 151 |
+
}}
|
| 152 |
+
>
|
| 153 |
+
{({ errors, handleBlur, handleChange, handleSubmit, isSubmitting, touched, values }) => (
|
| 154 |
+
<form noValidate onSubmit={handleSubmit} {...others}>
|
| 155 |
+
<Grid container spacing={matchDownSM ? 0 : 2}>
|
| 156 |
+
<Grid item xs={12} sm={6}>
|
| 157 |
+
<TextField
|
| 158 |
+
fullWidth
|
| 159 |
+
label="First Name"
|
| 160 |
+
margin="normal"
|
| 161 |
+
name="fname"
|
| 162 |
+
type="text"
|
| 163 |
+
defaultValue=""
|
| 164 |
+
sx={{ ...theme.typography.customInput }}
|
| 165 |
+
/>
|
| 166 |
+
</Grid>
|
| 167 |
+
<Grid item xs={12} sm={6}>
|
| 168 |
+
<TextField
|
| 169 |
+
fullWidth
|
| 170 |
+
label="Last Name"
|
| 171 |
+
margin="normal"
|
| 172 |
+
name="lname"
|
| 173 |
+
type="text"
|
| 174 |
+
defaultValue=""
|
| 175 |
+
sx={{ ...theme.typography.customInput }}
|
| 176 |
+
/>
|
| 177 |
+
</Grid>
|
| 178 |
+
</Grid>
|
| 179 |
+
<FormControl fullWidth error={Boolean(touched.email && errors.email)} sx={{ ...theme.typography.customInput }}>
|
| 180 |
+
<InputLabel htmlFor="outlined-adornment-email-register">Email Address / Username</InputLabel>
|
| 181 |
+
<OutlinedInput
|
| 182 |
+
id="outlined-adornment-email-register"
|
| 183 |
+
type="email"
|
| 184 |
+
value={values.email}
|
| 185 |
+
name="email"
|
| 186 |
+
onBlur={handleBlur}
|
| 187 |
+
onChange={handleChange}
|
| 188 |
+
inputProps={{}}
|
| 189 |
+
/>
|
| 190 |
+
{touched.email && errors.email && (
|
| 191 |
+
<FormHelperText error id="standard-weight-helper-text--register">
|
| 192 |
+
{errors.email}
|
| 193 |
+
</FormHelperText>
|
| 194 |
+
)}
|
| 195 |
+
</FormControl>
|
| 196 |
+
|
| 197 |
+
<FormControl
|
| 198 |
+
fullWidth
|
| 199 |
+
error={Boolean(touched.password && errors.password)}
|
| 200 |
+
sx={{ ...theme.typography.customInput }}
|
| 201 |
+
>
|
| 202 |
+
<InputLabel htmlFor="outlined-adornment-password-register">Password</InputLabel>
|
| 203 |
+
<OutlinedInput
|
| 204 |
+
id="outlined-adornment-password-register"
|
| 205 |
+
type={showPassword ? 'text' : 'password'}
|
| 206 |
+
value={values.password}
|
| 207 |
+
name="password"
|
| 208 |
+
label="Password"
|
| 209 |
+
onBlur={handleBlur}
|
| 210 |
+
onChange={(e) => {
|
| 211 |
+
handleChange(e);
|
| 212 |
+
changePassword(e.target.value);
|
| 213 |
+
}}
|
| 214 |
+
endAdornment={
|
| 215 |
+
<InputAdornment position="end">
|
| 216 |
+
<IconButton
|
| 217 |
+
aria-label="toggle password visibility"
|
| 218 |
+
onClick={handleClickShowPassword}
|
| 219 |
+
onMouseDown={handleMouseDownPassword}
|
| 220 |
+
edge="end"
|
| 221 |
+
size="large"
|
| 222 |
+
>
|
| 223 |
+
{showPassword ? <Visibility /> : <VisibilityOff />}
|
| 224 |
+
</IconButton>
|
| 225 |
+
</InputAdornment>
|
| 226 |
+
}
|
| 227 |
+
inputProps={{}}
|
| 228 |
+
/>
|
| 229 |
+
{touched.password && errors.password && (
|
| 230 |
+
<FormHelperText error id="standard-weight-helper-text-password-register">
|
| 231 |
+
{errors.password}
|
| 232 |
+
</FormHelperText>
|
| 233 |
+
)}
|
| 234 |
+
</FormControl>
|
| 235 |
+
|
| 236 |
+
{strength !== 0 && (
|
| 237 |
+
<FormControl fullWidth>
|
| 238 |
+
<Box sx={{ mb: 2 }}>
|
| 239 |
+
<Grid container spacing={2} alignItems="center">
|
| 240 |
+
<Grid item>
|
| 241 |
+
<Box
|
| 242 |
+
style={{ backgroundColor: level?.color }}
|
| 243 |
+
sx={{ width: 85, height: 8, borderRadius: '7px' }}
|
| 244 |
+
/>
|
| 245 |
+
</Grid>
|
| 246 |
+
<Grid item>
|
| 247 |
+
<Typography variant="subtitle1" fontSize="0.75rem">
|
| 248 |
+
{level?.label}
|
| 249 |
+
</Typography>
|
| 250 |
+
</Grid>
|
| 251 |
+
</Grid>
|
| 252 |
+
</Box>
|
| 253 |
+
</FormControl>
|
| 254 |
+
)}
|
| 255 |
+
|
| 256 |
+
<Grid container alignItems="center" justifyContent="space-between">
|
| 257 |
+
<Grid item>
|
| 258 |
+
<FormControlLabel
|
| 259 |
+
control={
|
| 260 |
+
<Checkbox
|
| 261 |
+
checked={checked}
|
| 262 |
+
onChange={(event) => setChecked(event.target.checked)}
|
| 263 |
+
name="checked"
|
| 264 |
+
color="primary"
|
| 265 |
+
/>
|
| 266 |
+
}
|
| 267 |
+
label={
|
| 268 |
+
<Typography variant="subtitle1">
|
| 269 |
+
Agree with
|
| 270 |
+
<Typography variant="subtitle1" component={Link} to="#">
|
| 271 |
+
Terms & Condition.
|
| 272 |
+
</Typography>
|
| 273 |
+
</Typography>
|
| 274 |
+
}
|
| 275 |
+
/>
|
| 276 |
+
</Grid>
|
| 277 |
+
</Grid>
|
| 278 |
+
{errors.submit && (
|
| 279 |
+
<Box sx={{ mt: 3 }}>
|
| 280 |
+
<FormHelperText error>{errors.submit}</FormHelperText>
|
| 281 |
+
</Box>
|
| 282 |
+
)}
|
| 283 |
+
|
| 284 |
+
<Box sx={{ mt: 2 }}>
|
| 285 |
+
<AnimateButton>
|
| 286 |
+
<Button
|
| 287 |
+
disableElevation
|
| 288 |
+
disabled={isSubmitting}
|
| 289 |
+
fullWidth
|
| 290 |
+
size="large"
|
| 291 |
+
type="submit"
|
| 292 |
+
variant="contained"
|
| 293 |
+
color="secondary"
|
| 294 |
+
>
|
| 295 |
+
Sign up
|
| 296 |
+
</Button>
|
| 297 |
+
</AnimateButton>
|
| 298 |
+
</Box>
|
| 299 |
+
</form>
|
| 300 |
+
)}
|
| 301 |
+
</Formik>
|
| 302 |
+
</>
|
| 303 |
+
);
|
| 304 |
+
};
|
| 305 |
+
|
| 306 |
+
export default FirebaseRegister;
|
remix/app/components/dashboard/BajajAreaChartCard.client.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { useEffect } from 'react';
|
| 2 |
+
import { useSelector } from 'react-redux';
|
| 3 |
+
|
| 4 |
+
// material-ui
|
| 5 |
+
import { useTheme } from '@mui/material/styles';
|
| 6 |
+
import { Card, Grid, Typography } from '@mui/material';
|
| 7 |
+
|
| 8 |
+
// project imports
|
| 9 |
+
import chartData from './chart-data/bajaj-area-chart';
|
| 10 |
+
|
| 11 |
+
// third-party
|
| 12 |
+
import ApexCharts from 'apexcharts';
|
| 13 |
+
import Chart from 'react-apexcharts';
|
| 14 |
+
|
| 15 |
+
// ===========================|| DASHBOARD DEFAULT - BAJAJ AREA CHART CARD ||=========================== //
|
| 16 |
+
|
| 17 |
+
const BajajAreaChartCard = () => {
|
| 18 |
+
const theme = useTheme();
|
| 19 |
+
const customization = useSelector((state) => state.customization);
|
| 20 |
+
const { navType } = customization;
|
| 21 |
+
|
| 22 |
+
const orangeDark = theme.palette.secondary[800];
|
| 23 |
+
|
| 24 |
+
useEffect(() => {
|
| 25 |
+
const newSupportChart = {
|
| 26 |
+
...chartData.options,
|
| 27 |
+
colors: [orangeDark],
|
| 28 |
+
tooltip: {
|
| 29 |
+
theme: 'light'
|
| 30 |
+
}
|
| 31 |
+
};
|
| 32 |
+
ApexCharts.exec(`support-chart`, 'updateOptions', newSupportChart);
|
| 33 |
+
}, [navType, orangeDark]);
|
| 34 |
+
|
| 35 |
+
return (
|
| 36 |
+
<Card sx={{ bgcolor: 'secondary.light' }}>
|
| 37 |
+
<Grid container sx={{ p: 2, pb: 0, color: '#fff' }}>
|
| 38 |
+
<Grid item xs={12}>
|
| 39 |
+
<Grid container alignItems="center" justifyContent="space-between">
|
| 40 |
+
<Grid item>
|
| 41 |
+
<Typography variant="subtitle1" sx={{ color: theme.palette.secondary.dark }}>
|
| 42 |
+
Bajaj Finery
|
| 43 |
+
</Typography>
|
| 44 |
+
</Grid>
|
| 45 |
+
<Grid item>
|
| 46 |
+
<Typography variant="h4" sx={{ color: theme.palette.grey[800] }}>
|
| 47 |
+
$1839.00
|
| 48 |
+
</Typography>
|
| 49 |
+
</Grid>
|
| 50 |
+
</Grid>
|
| 51 |
+
</Grid>
|
| 52 |
+
<Grid item xs={12}>
|
| 53 |
+
<Typography variant="subtitle2" sx={{ color: theme.palette.grey[800] }}>
|
| 54 |
+
10% Profit
|
| 55 |
+
</Typography>
|
| 56 |
+
</Grid>
|
| 57 |
+
</Grid>
|
| 58 |
+
<Chart {...chartData} />
|
| 59 |
+
</Card>
|
| 60 |
+
);
|
| 61 |
+
};
|
| 62 |
+
|
| 63 |
+
export default BajajAreaChartCard;
|
remix/app/components/dashboard/EarningCard.js
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { useState } from 'react';
|
| 2 |
+
|
| 3 |
+
// material-ui
|
| 4 |
+
import { styled, useTheme } from '@mui/material/styles';
|
| 5 |
+
import { Avatar, Box, Grid, Menu, MenuItem, Typography } from '@mui/material';
|
| 6 |
+
|
| 7 |
+
// project imports
|
| 8 |
+
import MainCard from 'ui-component/cards/MainCard';
|
| 9 |
+
import SkeletonEarningCard from 'ui-component/cards/Skeleton/EarningCard';
|
| 10 |
+
|
| 11 |
+
// types
|
| 12 |
+
import PropTypes from 'prop-types';
|
| 13 |
+
|
| 14 |
+
// assets
|
| 15 |
+
import EarningIcon from 'assets/images/icons/earning.svg';
|
| 16 |
+
import MoreHorizIcon from '@mui/icons-material/MoreHoriz';
|
| 17 |
+
import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward';
|
| 18 |
+
import GetAppTwoToneIcon from '@mui/icons-material/GetAppOutlined';
|
| 19 |
+
import FileCopyTwoToneIcon from '@mui/icons-material/FileCopyOutlined';
|
| 20 |
+
import PictureAsPdfTwoToneIcon from '@mui/icons-material/PictureAsPdfOutlined';
|
| 21 |
+
import ArchiveTwoToneIcon from '@mui/icons-material/ArchiveOutlined';
|
| 22 |
+
|
| 23 |
+
const CardWrapper = styled(MainCard)(({ theme }) => ({
|
| 24 |
+
backgroundColor: theme.palette.secondary.dark,
|
| 25 |
+
color: '#fff',
|
| 26 |
+
overflow: 'hidden',
|
| 27 |
+
position: 'relative',
|
| 28 |
+
'&:after': {
|
| 29 |
+
content: '""',
|
| 30 |
+
position: 'absolute',
|
| 31 |
+
width: 210,
|
| 32 |
+
height: 210,
|
| 33 |
+
background: theme.palette.secondary[800],
|
| 34 |
+
borderRadius: '50%',
|
| 35 |
+
top: -85,
|
| 36 |
+
right: -95,
|
| 37 |
+
[theme.breakpoints.down('sm')]: {
|
| 38 |
+
top: -105,
|
| 39 |
+
right: -140
|
| 40 |
+
}
|
| 41 |
+
},
|
| 42 |
+
'&:before': {
|
| 43 |
+
content: '""',
|
| 44 |
+
position: 'absolute',
|
| 45 |
+
width: 210,
|
| 46 |
+
height: 210,
|
| 47 |
+
background: theme.palette.secondary[800],
|
| 48 |
+
borderRadius: '50%',
|
| 49 |
+
top: -125,
|
| 50 |
+
right: -15,
|
| 51 |
+
opacity: 0.5,
|
| 52 |
+
[theme.breakpoints.down('sm')]: {
|
| 53 |
+
top: -155,
|
| 54 |
+
right: -70
|
| 55 |
+
}
|
| 56 |
+
}
|
| 57 |
+
}));
|
| 58 |
+
|
| 59 |
+
// ===========================|| DASHBOARD DEFAULT - EARNING CARD ||=========================== //
|
| 60 |
+
|
| 61 |
+
const EarningCard = ({ isLoading }) => {
|
| 62 |
+
const theme = useTheme();
|
| 63 |
+
|
| 64 |
+
const [anchorEl, setAnchorEl] = useState(null);
|
| 65 |
+
|
| 66 |
+
const handleClick = (event) => {
|
| 67 |
+
setAnchorEl(event.currentTarget);
|
| 68 |
+
};
|
| 69 |
+
|
| 70 |
+
const handleClose = () => {
|
| 71 |
+
setAnchorEl(null);
|
| 72 |
+
};
|
| 73 |
+
|
| 74 |
+
return (
|
| 75 |
+
<>
|
| 76 |
+
{isLoading ? (
|
| 77 |
+
<SkeletonEarningCard />
|
| 78 |
+
) : (
|
| 79 |
+
<CardWrapper border={false} content={false}>
|
| 80 |
+
<Box sx={{ p: 2.25 }}>
|
| 81 |
+
<Grid container direction="column">
|
| 82 |
+
<Grid item>
|
| 83 |
+
<Grid container justifyContent="space-between">
|
| 84 |
+
<Grid item>
|
| 85 |
+
<Avatar
|
| 86 |
+
variant="rounded"
|
| 87 |
+
sx={{
|
| 88 |
+
...theme.typography.commonAvatar,
|
| 89 |
+
...theme.typography.largeAvatar,
|
| 90 |
+
backgroundColor: theme.palette.secondary[800],
|
| 91 |
+
mt: 1
|
| 92 |
+
}}
|
| 93 |
+
>
|
| 94 |
+
<img src={EarningIcon} alt="Notification" />
|
| 95 |
+
</Avatar>
|
| 96 |
+
</Grid>
|
| 97 |
+
<Grid item>
|
| 98 |
+
<Avatar
|
| 99 |
+
variant="rounded"
|
| 100 |
+
sx={{
|
| 101 |
+
...theme.typography.commonAvatar,
|
| 102 |
+
...theme.typography.mediumAvatar,
|
| 103 |
+
backgroundColor: theme.palette.secondary.dark,
|
| 104 |
+
color: theme.palette.secondary[200],
|
| 105 |
+
zIndex: 1
|
| 106 |
+
}}
|
| 107 |
+
aria-controls="menu-earning-card"
|
| 108 |
+
aria-haspopup="true"
|
| 109 |
+
onClick={handleClick}
|
| 110 |
+
>
|
| 111 |
+
<MoreHorizIcon fontSize="inherit" />
|
| 112 |
+
</Avatar>
|
| 113 |
+
<Menu
|
| 114 |
+
id="menu-earning-card"
|
| 115 |
+
anchorEl={anchorEl}
|
| 116 |
+
keepMounted
|
| 117 |
+
open={Boolean(anchorEl)}
|
| 118 |
+
onClose={handleClose}
|
| 119 |
+
variant="selectedMenu"
|
| 120 |
+
anchorOrigin={{
|
| 121 |
+
vertical: 'bottom',
|
| 122 |
+
horizontal: 'right'
|
| 123 |
+
}}
|
| 124 |
+
transformOrigin={{
|
| 125 |
+
vertical: 'top',
|
| 126 |
+
horizontal: 'right'
|
| 127 |
+
}}
|
| 128 |
+
>
|
| 129 |
+
<MenuItem onClick={handleClose}>
|
| 130 |
+
<GetAppTwoToneIcon sx={{ mr: 1.75 }} /> Import Card
|
| 131 |
+
</MenuItem>
|
| 132 |
+
<MenuItem onClick={handleClose}>
|
| 133 |
+
<FileCopyTwoToneIcon sx={{ mr: 1.75 }} /> Copy Data
|
| 134 |
+
</MenuItem>
|
| 135 |
+
<MenuItem onClick={handleClose}>
|
| 136 |
+
<PictureAsPdfTwoToneIcon sx={{ mr: 1.75 }} /> Export
|
| 137 |
+
</MenuItem>
|
| 138 |
+
<MenuItem onClick={handleClose}>
|
| 139 |
+
<ArchiveTwoToneIcon sx={{ mr: 1.75 }} /> Archive File
|
| 140 |
+
</MenuItem>
|
| 141 |
+
</Menu>
|
| 142 |
+
</Grid>
|
| 143 |
+
</Grid>
|
| 144 |
+
</Grid>
|
| 145 |
+
<Grid item>
|
| 146 |
+
<Grid container alignItems="center">
|
| 147 |
+
<Grid item>
|
| 148 |
+
<Typography sx={{ fontSize: '2.125rem', fontWeight: 500, mr: 1, mt: 1.75, mb: 0.75 }}>
|
| 149 |
+
$500.00
|
| 150 |
+
</Typography>
|
| 151 |
+
</Grid>
|
| 152 |
+
<Grid item>
|
| 153 |
+
<Avatar
|
| 154 |
+
sx={{
|
| 155 |
+
cursor: 'pointer',
|
| 156 |
+
...theme.typography.smallAvatar,
|
| 157 |
+
backgroundColor: theme.palette.secondary[200],
|
| 158 |
+
color: theme.palette.secondary.dark
|
| 159 |
+
}}
|
| 160 |
+
>
|
| 161 |
+
<ArrowUpwardIcon fontSize="inherit" sx={{ transform: 'rotate3d(1, 1, 1, 45deg)' }} />
|
| 162 |
+
</Avatar>
|
| 163 |
+
</Grid>
|
| 164 |
+
</Grid>
|
| 165 |
+
</Grid>
|
| 166 |
+
<Grid item sx={{ mb: 1.25 }}>
|
| 167 |
+
<Typography
|
| 168 |
+
sx={{
|
| 169 |
+
fontSize: '1rem',
|
| 170 |
+
fontWeight: 500,
|
| 171 |
+
color: theme.palette.secondary[200]
|
| 172 |
+
}}
|
| 173 |
+
>
|
| 174 |
+
Total Earning
|
| 175 |
+
</Typography>
|
| 176 |
+
</Grid>
|
| 177 |
+
</Grid>
|
| 178 |
+
</Box>
|
| 179 |
+
</CardWrapper>
|
| 180 |
+
)}
|
| 181 |
+
</>
|
| 182 |
+
);
|
| 183 |
+
};
|
| 184 |
+
|
| 185 |
+
EarningCard.propTypes = {
|
| 186 |
+
isLoading: PropTypes.bool
|
| 187 |
+
};
|
| 188 |
+
|
| 189 |
+
export default EarningCard;
|
remix/app/components/dashboard/PopularCard.js
ADDED
|
@@ -0,0 +1,311 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { useState } from 'react';
|
| 2 |
+
|
| 3 |
+
// material-ui
|
| 4 |
+
import { useTheme } from '@mui/material/styles';
|
| 5 |
+
import { Avatar, Button, CardActions, CardContent, Divider, Grid, Menu, MenuItem, Typography } from '@mui/material';
|
| 6 |
+
|
| 7 |
+
// project imports
|
| 8 |
+
import { gridSpacing } from 'store/constant';
|
| 9 |
+
import MainCard from 'ui-component/cards/MainCard';
|
| 10 |
+
import SkeletonPopularCard from 'ui-component/cards/Skeleton/PopularCard';
|
| 11 |
+
import BajajAreaChartCard from './BajajAreaChartCard.client';
|
| 12 |
+
|
| 13 |
+
// types
|
| 14 |
+
import PropTypes from 'prop-types';
|
| 15 |
+
|
| 16 |
+
// assets
|
| 17 |
+
import ChevronRightOutlinedIcon from '@mui/icons-material/ChevronRightOutlined';
|
| 18 |
+
import MoreHorizOutlinedIcon from '@mui/icons-material/MoreHorizOutlined';
|
| 19 |
+
import KeyboardArrowUpOutlinedIcon from '@mui/icons-material/KeyboardArrowUpOutlined';
|
| 20 |
+
import KeyboardArrowDownOutlinedIcon from '@mui/icons-material/KeyboardArrowDownOutlined';
|
| 21 |
+
|
| 22 |
+
// ==============================|| DASHBOARD DEFAULT - POPULAR CARD ||============================== //
|
| 23 |
+
|
| 24 |
+
const PopularCard = ({ isLoading }) => {
|
| 25 |
+
const theme = useTheme();
|
| 26 |
+
|
| 27 |
+
const [anchorEl, setAnchorEl] = useState(null);
|
| 28 |
+
|
| 29 |
+
const handleClick = (event) => {
|
| 30 |
+
setAnchorEl(event.currentTarget);
|
| 31 |
+
};
|
| 32 |
+
|
| 33 |
+
const handleClose = () => {
|
| 34 |
+
setAnchorEl(null);
|
| 35 |
+
};
|
| 36 |
+
|
| 37 |
+
return (
|
| 38 |
+
<>
|
| 39 |
+
{isLoading ? (
|
| 40 |
+
<SkeletonPopularCard />
|
| 41 |
+
) : (
|
| 42 |
+
<MainCard content={false}>
|
| 43 |
+
<CardContent>
|
| 44 |
+
<Grid container spacing={gridSpacing}>
|
| 45 |
+
<Grid item xs={12}>
|
| 46 |
+
<Grid container alignContent="center" justifyContent="space-between">
|
| 47 |
+
<Grid item>
|
| 48 |
+
<Typography variant="h4">Popular Stocks</Typography>
|
| 49 |
+
</Grid>
|
| 50 |
+
<Grid item>
|
| 51 |
+
<MoreHorizOutlinedIcon
|
| 52 |
+
fontSize="small"
|
| 53 |
+
sx={{
|
| 54 |
+
color: theme.palette.primary[200],
|
| 55 |
+
cursor: 'pointer'
|
| 56 |
+
}}
|
| 57 |
+
aria-controls="menu-popular-card"
|
| 58 |
+
aria-haspopup="true"
|
| 59 |
+
onClick={handleClick}
|
| 60 |
+
/>
|
| 61 |
+
<Menu
|
| 62 |
+
id="menu-popular-card"
|
| 63 |
+
anchorEl={anchorEl}
|
| 64 |
+
keepMounted
|
| 65 |
+
open={Boolean(anchorEl)}
|
| 66 |
+
onClose={handleClose}
|
| 67 |
+
variant="selectedMenu"
|
| 68 |
+
anchorOrigin={{
|
| 69 |
+
vertical: 'bottom',
|
| 70 |
+
horizontal: 'right'
|
| 71 |
+
}}
|
| 72 |
+
transformOrigin={{
|
| 73 |
+
vertical: 'top',
|
| 74 |
+
horizontal: 'right'
|
| 75 |
+
}}
|
| 76 |
+
>
|
| 77 |
+
<MenuItem onClick={handleClose}> Today</MenuItem>
|
| 78 |
+
<MenuItem onClick={handleClose}> This Month</MenuItem>
|
| 79 |
+
<MenuItem onClick={handleClose}> This Year </MenuItem>
|
| 80 |
+
</Menu>
|
| 81 |
+
</Grid>
|
| 82 |
+
</Grid>
|
| 83 |
+
</Grid>
|
| 84 |
+
<Grid item xs={12} sx={{ pt: '16px !important' }}>
|
| 85 |
+
<BajajAreaChartCard />
|
| 86 |
+
</Grid>
|
| 87 |
+
<Grid item xs={12}>
|
| 88 |
+
<Grid container direction="column">
|
| 89 |
+
<Grid item>
|
| 90 |
+
<Grid container alignItems="center" justifyContent="space-between">
|
| 91 |
+
<Grid item>
|
| 92 |
+
<Typography variant="subtitle1" color="inherit">
|
| 93 |
+
Bajaj Finery
|
| 94 |
+
</Typography>
|
| 95 |
+
</Grid>
|
| 96 |
+
<Grid item>
|
| 97 |
+
<Grid container alignItems="center" justifyContent="space-between">
|
| 98 |
+
<Grid item>
|
| 99 |
+
<Typography variant="subtitle1" color="inherit">
|
| 100 |
+
$1839.00
|
| 101 |
+
</Typography>
|
| 102 |
+
</Grid>
|
| 103 |
+
<Grid item>
|
| 104 |
+
<Avatar
|
| 105 |
+
variant="rounded"
|
| 106 |
+
sx={{
|
| 107 |
+
width: 16,
|
| 108 |
+
height: 16,
|
| 109 |
+
borderRadius: '5px',
|
| 110 |
+
backgroundColor: theme.palette.success.light,
|
| 111 |
+
color: theme.palette.success.dark,
|
| 112 |
+
ml: 2
|
| 113 |
+
}}
|
| 114 |
+
>
|
| 115 |
+
<KeyboardArrowUpOutlinedIcon fontSize="small" color="inherit" />
|
| 116 |
+
</Avatar>
|
| 117 |
+
</Grid>
|
| 118 |
+
</Grid>
|
| 119 |
+
</Grid>
|
| 120 |
+
</Grid>
|
| 121 |
+
</Grid>
|
| 122 |
+
<Grid item>
|
| 123 |
+
<Typography variant="subtitle2" sx={{ color: 'success.dark' }}>
|
| 124 |
+
10% Profit
|
| 125 |
+
</Typography>
|
| 126 |
+
</Grid>
|
| 127 |
+
</Grid>
|
| 128 |
+
<Divider sx={{ my: 1.5 }} />
|
| 129 |
+
<Grid container direction="column">
|
| 130 |
+
<Grid item>
|
| 131 |
+
<Grid container alignItems="center" justifyContent="space-between">
|
| 132 |
+
<Grid item>
|
| 133 |
+
<Typography variant="subtitle1" color="inherit">
|
| 134 |
+
TTML
|
| 135 |
+
</Typography>
|
| 136 |
+
</Grid>
|
| 137 |
+
<Grid item>
|
| 138 |
+
<Grid container alignItems="center" justifyContent="space-between">
|
| 139 |
+
<Grid item>
|
| 140 |
+
<Typography variant="subtitle1" color="inherit">
|
| 141 |
+
$100.00
|
| 142 |
+
</Typography>
|
| 143 |
+
</Grid>
|
| 144 |
+
<Grid item>
|
| 145 |
+
<Avatar
|
| 146 |
+
variant="rounded"
|
| 147 |
+
sx={{
|
| 148 |
+
width: 16,
|
| 149 |
+
height: 16,
|
| 150 |
+
borderRadius: '5px',
|
| 151 |
+
backgroundColor: theme.palette.orange.light,
|
| 152 |
+
color: theme.palette.orange.dark,
|
| 153 |
+
marginLeft: 1.875
|
| 154 |
+
}}
|
| 155 |
+
>
|
| 156 |
+
<KeyboardArrowDownOutlinedIcon fontSize="small" color="inherit" />
|
| 157 |
+
</Avatar>
|
| 158 |
+
</Grid>
|
| 159 |
+
</Grid>
|
| 160 |
+
</Grid>
|
| 161 |
+
</Grid>
|
| 162 |
+
</Grid>
|
| 163 |
+
<Grid item>
|
| 164 |
+
<Typography variant="subtitle2" sx={{ color: theme.palette.orange.dark }}>
|
| 165 |
+
10% loss
|
| 166 |
+
</Typography>
|
| 167 |
+
</Grid>
|
| 168 |
+
</Grid>
|
| 169 |
+
<Divider sx={{ my: 1.5 }} />
|
| 170 |
+
<Grid container direction="column">
|
| 171 |
+
<Grid item>
|
| 172 |
+
<Grid container alignItems="center" justifyContent="space-between">
|
| 173 |
+
<Grid item>
|
| 174 |
+
<Typography variant="subtitle1" color="inherit">
|
| 175 |
+
Reliance
|
| 176 |
+
</Typography>
|
| 177 |
+
</Grid>
|
| 178 |
+
<Grid item>
|
| 179 |
+
<Grid container alignItems="center" justifyContent="space-between">
|
| 180 |
+
<Grid item>
|
| 181 |
+
<Typography variant="subtitle1" color="inherit">
|
| 182 |
+
$200.00
|
| 183 |
+
</Typography>
|
| 184 |
+
</Grid>
|
| 185 |
+
<Grid item>
|
| 186 |
+
<Avatar
|
| 187 |
+
variant="rounded"
|
| 188 |
+
sx={{
|
| 189 |
+
width: 16,
|
| 190 |
+
height: 16,
|
| 191 |
+
borderRadius: '5px',
|
| 192 |
+
backgroundColor: theme.palette.success.light,
|
| 193 |
+
color: theme.palette.success.dark,
|
| 194 |
+
ml: 2
|
| 195 |
+
}}
|
| 196 |
+
>
|
| 197 |
+
<KeyboardArrowUpOutlinedIcon fontSize="small" color="inherit" />
|
| 198 |
+
</Avatar>
|
| 199 |
+
</Grid>
|
| 200 |
+
</Grid>
|
| 201 |
+
</Grid>
|
| 202 |
+
</Grid>
|
| 203 |
+
</Grid>
|
| 204 |
+
<Grid item>
|
| 205 |
+
<Typography variant="subtitle2" sx={{ color: theme.palette.success.dark }}>
|
| 206 |
+
10% Profit
|
| 207 |
+
</Typography>
|
| 208 |
+
</Grid>
|
| 209 |
+
</Grid>
|
| 210 |
+
<Divider sx={{ my: 1.5 }} />
|
| 211 |
+
<Grid container direction="column">
|
| 212 |
+
<Grid item>
|
| 213 |
+
<Grid container alignItems="center" justifyContent="space-between">
|
| 214 |
+
<Grid item>
|
| 215 |
+
<Typography variant="subtitle1" color="inherit">
|
| 216 |
+
TTML
|
| 217 |
+
</Typography>
|
| 218 |
+
</Grid>
|
| 219 |
+
<Grid item>
|
| 220 |
+
<Grid container alignItems="center" justifyContent="space-between">
|
| 221 |
+
<Grid item>
|
| 222 |
+
<Typography variant="subtitle1" color="inherit">
|
| 223 |
+
$189.00
|
| 224 |
+
</Typography>
|
| 225 |
+
</Grid>
|
| 226 |
+
<Grid item>
|
| 227 |
+
<Avatar
|
| 228 |
+
variant="rounded"
|
| 229 |
+
sx={{
|
| 230 |
+
width: 16,
|
| 231 |
+
height: 16,
|
| 232 |
+
borderRadius: '5px',
|
| 233 |
+
backgroundColor: theme.palette.orange.light,
|
| 234 |
+
color: theme.palette.orange.dark,
|
| 235 |
+
ml: 2
|
| 236 |
+
}}
|
| 237 |
+
>
|
| 238 |
+
<KeyboardArrowDownOutlinedIcon fontSize="small" color="inherit" />
|
| 239 |
+
</Avatar>
|
| 240 |
+
</Grid>
|
| 241 |
+
</Grid>
|
| 242 |
+
</Grid>
|
| 243 |
+
</Grid>
|
| 244 |
+
</Grid>
|
| 245 |
+
<Grid item>
|
| 246 |
+
<Typography variant="subtitle2" sx={{ color: theme.palette.orange.dark }}>
|
| 247 |
+
10% loss
|
| 248 |
+
</Typography>
|
| 249 |
+
</Grid>
|
| 250 |
+
</Grid>
|
| 251 |
+
<Divider sx={{ my: 1.5 }} />
|
| 252 |
+
<Grid container direction="column">
|
| 253 |
+
<Grid item>
|
| 254 |
+
<Grid container alignItems="center" justifyContent="space-between">
|
| 255 |
+
<Grid item>
|
| 256 |
+
<Typography variant="subtitle1" color="inherit">
|
| 257 |
+
Stolon
|
| 258 |
+
</Typography>
|
| 259 |
+
</Grid>
|
| 260 |
+
<Grid item>
|
| 261 |
+
<Grid container alignItems="center" justifyContent="space-between">
|
| 262 |
+
<Grid item>
|
| 263 |
+
<Typography variant="subtitle1" color="inherit">
|
| 264 |
+
$189.00
|
| 265 |
+
</Typography>
|
| 266 |
+
</Grid>
|
| 267 |
+
<Grid item>
|
| 268 |
+
<Avatar
|
| 269 |
+
variant="rounded"
|
| 270 |
+
sx={{
|
| 271 |
+
width: 16,
|
| 272 |
+
height: 16,
|
| 273 |
+
borderRadius: '5px',
|
| 274 |
+
backgroundColor: theme.palette.orange.light,
|
| 275 |
+
color: theme.palette.orange.dark,
|
| 276 |
+
ml: 2
|
| 277 |
+
}}
|
| 278 |
+
>
|
| 279 |
+
<KeyboardArrowDownOutlinedIcon fontSize="small" color="inherit" />
|
| 280 |
+
</Avatar>
|
| 281 |
+
</Grid>
|
| 282 |
+
</Grid>
|
| 283 |
+
</Grid>
|
| 284 |
+
</Grid>
|
| 285 |
+
</Grid>
|
| 286 |
+
<Grid item>
|
| 287 |
+
<Typography variant="subtitle2" sx={{ color: theme.palette.orange.dark }}>
|
| 288 |
+
10% loss
|
| 289 |
+
</Typography>
|
| 290 |
+
</Grid>
|
| 291 |
+
</Grid>
|
| 292 |
+
</Grid>
|
| 293 |
+
</Grid>
|
| 294 |
+
</CardContent>
|
| 295 |
+
<CardActions sx={{ p: 1.25, pt: 0, justifyContent: 'center' }}>
|
| 296 |
+
<Button size="small" disableElevation>
|
| 297 |
+
View All
|
| 298 |
+
<ChevronRightOutlinedIcon />
|
| 299 |
+
</Button>
|
| 300 |
+
</CardActions>
|
| 301 |
+
</MainCard>
|
| 302 |
+
)}
|
| 303 |
+
</>
|
| 304 |
+
);
|
| 305 |
+
};
|
| 306 |
+
|
| 307 |
+
PopularCard.propTypes = {
|
| 308 |
+
isLoading: PropTypes.bool
|
| 309 |
+
};
|
| 310 |
+
|
| 311 |
+
export default PopularCard;
|
remix/app/components/dashboard/TotalGrowthBarCard.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { useState } from 'react';
|
| 2 |
+
|
| 3 |
+
// material-ui
|
| 4 |
+
import { Grid, MenuItem, TextField, Typography } from '@mui/material';
|
| 5 |
+
|
| 6 |
+
// project imports
|
| 7 |
+
import { gridSpacing } from 'store/constant';
|
| 8 |
+
import MainCard from 'ui-component/cards/MainCard';
|
| 9 |
+
import SkeletonTotalGrowthBarChart from 'ui-component/cards/Skeleton/TotalGrowthBarChart';
|
| 10 |
+
import TotalGrowthBarChart from './TotalGrowthBarChart.client';
|
| 11 |
+
|
| 12 |
+
// types
|
| 13 |
+
import PropTypes from 'prop-types';
|
| 14 |
+
|
| 15 |
+
const status = [
|
| 16 |
+
{
|
| 17 |
+
value: 'today',
|
| 18 |
+
label: 'Today'
|
| 19 |
+
},
|
| 20 |
+
{
|
| 21 |
+
value: 'month',
|
| 22 |
+
label: 'This Month'
|
| 23 |
+
},
|
| 24 |
+
{
|
| 25 |
+
value: 'year',
|
| 26 |
+
label: 'This Year'
|
| 27 |
+
}
|
| 28 |
+
];
|
| 29 |
+
|
| 30 |
+
// ==============================|| DASHBOARD DEFAULT - TOTAL GROWTH BAR CHART CARD ||============================== //
|
| 31 |
+
|
| 32 |
+
const TotalGrowthBarCard = ({ isLoading }) => {
|
| 33 |
+
const [value, setValue] = useState('today');
|
| 34 |
+
|
| 35 |
+
return (
|
| 36 |
+
<>
|
| 37 |
+
{isLoading ? (
|
| 38 |
+
<SkeletonTotalGrowthBarChart />
|
| 39 |
+
) : (
|
| 40 |
+
<MainCard>
|
| 41 |
+
<Grid container spacing={gridSpacing}>
|
| 42 |
+
<Grid item xs={12}>
|
| 43 |
+
<Grid container alignItems="center" justifyContent="space-between">
|
| 44 |
+
<Grid item>
|
| 45 |
+
<Grid container direction="column" spacing={1}>
|
| 46 |
+
<Grid item>
|
| 47 |
+
<Typography variant="subtitle2">Total Growth</Typography>
|
| 48 |
+
</Grid>
|
| 49 |
+
<Grid item>
|
| 50 |
+
<Typography variant="h3">$2,324.00</Typography>
|
| 51 |
+
</Grid>
|
| 52 |
+
</Grid>
|
| 53 |
+
</Grid>
|
| 54 |
+
<Grid item>
|
| 55 |
+
<TextField
|
| 56 |
+
id="standard-select-currency"
|
| 57 |
+
select
|
| 58 |
+
value={value}
|
| 59 |
+
onChange={(e) => setValue(e.target.value)}
|
| 60 |
+
>
|
| 61 |
+
{status.map((option) => (
|
| 62 |
+
<MenuItem key={option.value} value={option.value}>
|
| 63 |
+
{option.label}
|
| 64 |
+
</MenuItem>
|
| 65 |
+
))}
|
| 66 |
+
</TextField>
|
| 67 |
+
</Grid>
|
| 68 |
+
</Grid>
|
| 69 |
+
</Grid>
|
| 70 |
+
<Grid item xs={12}>
|
| 71 |
+
<TotalGrowthBarChart isLoading={isLoading} />
|
| 72 |
+
</Grid>
|
| 73 |
+
</Grid>
|
| 74 |
+
</MainCard>
|
| 75 |
+
)}
|
| 76 |
+
</>
|
| 77 |
+
);
|
| 78 |
+
};
|
| 79 |
+
|
| 80 |
+
TotalGrowthBarCard.propTypes = {
|
| 81 |
+
isLoading: PropTypes.bool
|
| 82 |
+
};
|
| 83 |
+
|
| 84 |
+
export default TotalGrowthBarCard;
|
remix/app/components/dashboard/TotalGrowthBarChart.client.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { useEffect } from 'react';
|
| 2 |
+
import { useSelector } from 'react-redux';
|
| 3 |
+
|
| 4 |
+
// material-ui
|
| 5 |
+
import { useTheme } from '@mui/material/styles';
|
| 6 |
+
|
| 7 |
+
// third-party
|
| 8 |
+
import ApexCharts from 'apexcharts';
|
| 9 |
+
import Chart from 'react-apexcharts';
|
| 10 |
+
|
| 11 |
+
// chart data
|
| 12 |
+
import chartData from './chart-data/total-growth-bar-chart';
|
| 13 |
+
|
| 14 |
+
// types
|
| 15 |
+
import PropTypes from 'prop-types';
|
| 16 |
+
|
| 17 |
+
// ==============================|| DASHBOARD DEFAULT - TOTAL GROWTH BAR CHART ||============================== //
|
| 18 |
+
|
| 19 |
+
const TotalGrowthBarChart = ({ isLoading }) => {
|
| 20 |
+
const theme = useTheme();
|
| 21 |
+
const customization = useSelector((state) => state.customization);
|
| 22 |
+
|
| 23 |
+
const { navType } = customization;
|
| 24 |
+
const { primary } = theme.palette.text;
|
| 25 |
+
const darkLight = theme.palette.dark.light;
|
| 26 |
+
const grey200 = theme.palette.grey[200];
|
| 27 |
+
const grey500 = theme.palette.grey[500];
|
| 28 |
+
|
| 29 |
+
const primary200 = theme.palette.primary[200];
|
| 30 |
+
const primaryDark = theme.palette.primary.dark;
|
| 31 |
+
const secondaryMain = theme.palette.secondary.main;
|
| 32 |
+
const secondaryLight = theme.palette.secondary.light;
|
| 33 |
+
|
| 34 |
+
useEffect(() => {
|
| 35 |
+
const newChartData = {
|
| 36 |
+
...chartData.options,
|
| 37 |
+
colors: [primary200, primaryDark, secondaryMain, secondaryLight],
|
| 38 |
+
xaxis: {
|
| 39 |
+
labels: {
|
| 40 |
+
style: {
|
| 41 |
+
colors: [primary, primary, primary, primary, primary, primary, primary, primary, primary, primary, primary, primary]
|
| 42 |
+
}
|
| 43 |
+
}
|
| 44 |
+
},
|
| 45 |
+
yaxis: {
|
| 46 |
+
labels: {
|
| 47 |
+
style: {
|
| 48 |
+
colors: [primary]
|
| 49 |
+
}
|
| 50 |
+
}
|
| 51 |
+
},
|
| 52 |
+
grid: {
|
| 53 |
+
borderColor: grey200
|
| 54 |
+
},
|
| 55 |
+
tooltip: {
|
| 56 |
+
theme: 'light'
|
| 57 |
+
},
|
| 58 |
+
legend: {
|
| 59 |
+
labels: {
|
| 60 |
+
colors: grey500
|
| 61 |
+
}
|
| 62 |
+
}
|
| 63 |
+
};
|
| 64 |
+
|
| 65 |
+
// do not load chart when loading
|
| 66 |
+
if (!isLoading) {
|
| 67 |
+
ApexCharts.exec(`bar-chart`, 'updateOptions', newChartData);
|
| 68 |
+
}
|
| 69 |
+
}, [navType, primary200, primaryDark, secondaryMain, secondaryLight, primary, darkLight, grey200, isLoading, grey500]);
|
| 70 |
+
|
| 71 |
+
return (
|
| 72 |
+
<>
|
| 73 |
+
<Chart {...chartData} />
|
| 74 |
+
</>
|
| 75 |
+
);
|
| 76 |
+
};
|
| 77 |
+
|
| 78 |
+
TotalGrowthBarChart.propTypes = {
|
| 79 |
+
isLoading: PropTypes.bool
|
| 80 |
+
};
|
| 81 |
+
|
| 82 |
+
export default TotalGrowthBarChart;
|
remix/app/components/dashboard/TotalIncomeDarkCard.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// material-ui
|
| 2 |
+
import { styled, useTheme } from '@mui/material/styles';
|
| 3 |
+
import { Avatar, Box, List, ListItem, ListItemAvatar, ListItemText, Typography } from '@mui/material';
|
| 4 |
+
|
| 5 |
+
// project imports
|
| 6 |
+
import MainCard from 'ui-component/cards/MainCard';
|
| 7 |
+
import TotalIncomeCard from 'ui-component/cards/Skeleton/TotalIncomeCard';
|
| 8 |
+
|
| 9 |
+
// assets
|
| 10 |
+
import TableChartOutlinedIcon from '@mui/icons-material/TableChartOutlined';
|
| 11 |
+
|
| 12 |
+
// types
|
| 13 |
+
import PropTypes from 'prop-types';
|
| 14 |
+
|
| 15 |
+
// styles
|
| 16 |
+
const CardWrapper = styled(MainCard)(({ theme }) => ({
|
| 17 |
+
backgroundColor: theme.palette.primary.dark,
|
| 18 |
+
color: theme.palette.primary.light,
|
| 19 |
+
overflow: 'hidden',
|
| 20 |
+
position: 'relative',
|
| 21 |
+
'&:after': {
|
| 22 |
+
content: '""',
|
| 23 |
+
position: 'absolute',
|
| 24 |
+
width: 210,
|
| 25 |
+
height: 210,
|
| 26 |
+
background: `linear-gradient(210.04deg, ${theme.palette.primary[200]} -50.94%, rgba(144, 202, 249, 0) 83.49%)`,
|
| 27 |
+
borderRadius: '50%',
|
| 28 |
+
top: -30,
|
| 29 |
+
right: -180
|
| 30 |
+
},
|
| 31 |
+
'&:before': {
|
| 32 |
+
content: '""',
|
| 33 |
+
position: 'absolute',
|
| 34 |
+
width: 210,
|
| 35 |
+
height: 210,
|
| 36 |
+
background: `linear-gradient(140.9deg, ${theme.palette.primary[200]} -14.02%, rgba(144, 202, 249, 0) 77.58%)`,
|
| 37 |
+
borderRadius: '50%',
|
| 38 |
+
top: -160,
|
| 39 |
+
right: -130
|
| 40 |
+
}
|
| 41 |
+
}));
|
| 42 |
+
|
| 43 |
+
// ==============================|| DASHBOARD - TOTAL INCOME DARK CARD ||============================== //
|
| 44 |
+
|
| 45 |
+
const TotalIncomeDarkCard = ({ isLoading }) => {
|
| 46 |
+
const theme = useTheme();
|
| 47 |
+
|
| 48 |
+
return (
|
| 49 |
+
<>
|
| 50 |
+
{isLoading ? (
|
| 51 |
+
<TotalIncomeCard />
|
| 52 |
+
) : (
|
| 53 |
+
<CardWrapper border={false} content={false}>
|
| 54 |
+
<Box sx={{ p: 2 }}>
|
| 55 |
+
<List sx={{ py: 0 }}>
|
| 56 |
+
<ListItem alignItems="center" disableGutters sx={{ py: 0 }}>
|
| 57 |
+
<ListItemAvatar>
|
| 58 |
+
<Avatar
|
| 59 |
+
variant="rounded"
|
| 60 |
+
sx={{
|
| 61 |
+
...theme.typography.commonAvatar,
|
| 62 |
+
...theme.typography.largeAvatar,
|
| 63 |
+
backgroundColor: theme.palette.primary[800],
|
| 64 |
+
color: '#fff'
|
| 65 |
+
}}
|
| 66 |
+
>
|
| 67 |
+
<TableChartOutlinedIcon fontSize="inherit" />
|
| 68 |
+
</Avatar>
|
| 69 |
+
</ListItemAvatar>
|
| 70 |
+
<ListItemText
|
| 71 |
+
sx={{
|
| 72 |
+
py: 0,
|
| 73 |
+
mt: 0.45,
|
| 74 |
+
mb: 0.45
|
| 75 |
+
}}
|
| 76 |
+
primary={
|
| 77 |
+
<Typography variant="h4" sx={{ color: '#fff' }}>
|
| 78 |
+
$203k
|
| 79 |
+
</Typography>
|
| 80 |
+
}
|
| 81 |
+
secondary={
|
| 82 |
+
<Typography variant="subtitle2" sx={{ color: 'primary.light', mt: 0.25 }}>
|
| 83 |
+
Total Income
|
| 84 |
+
</Typography>
|
| 85 |
+
}
|
| 86 |
+
/>
|
| 87 |
+
</ListItem>
|
| 88 |
+
</List>
|
| 89 |
+
</Box>
|
| 90 |
+
</CardWrapper>
|
| 91 |
+
)}
|
| 92 |
+
</>
|
| 93 |
+
);
|
| 94 |
+
};
|
| 95 |
+
|
| 96 |
+
TotalIncomeDarkCard.propTypes = {
|
| 97 |
+
isLoading: PropTypes.bool
|
| 98 |
+
};
|
| 99 |
+
|
| 100 |
+
export default TotalIncomeDarkCard;
|
remix/app/components/dashboard/TotalIncomeLightCard.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// material-ui
|
| 2 |
+
import { useTheme, styled } from '@mui/material/styles';
|
| 3 |
+
import { Avatar, Box, List, ListItem, ListItemAvatar, ListItemText, Typography } from '@mui/material';
|
| 4 |
+
|
| 5 |
+
// project imports
|
| 6 |
+
import MainCard from 'ui-component/cards/MainCard';
|
| 7 |
+
import TotalIncomeCard from 'ui-component/cards/Skeleton/TotalIncomeCard';
|
| 8 |
+
|
| 9 |
+
// assets
|
| 10 |
+
import StorefrontTwoToneIcon from '@mui/icons-material/StorefrontTwoTone';
|
| 11 |
+
|
| 12 |
+
// types
|
| 13 |
+
import PropTypes from 'prop-types';
|
| 14 |
+
|
| 15 |
+
// styles
|
| 16 |
+
const CardWrapper = styled(MainCard)(({ theme }) => ({
|
| 17 |
+
overflow: 'hidden',
|
| 18 |
+
position: 'relative',
|
| 19 |
+
'&:after': {
|
| 20 |
+
content: '""',
|
| 21 |
+
position: 'absolute',
|
| 22 |
+
width: 210,
|
| 23 |
+
height: 210,
|
| 24 |
+
background: `linear-gradient(210.04deg, ${theme.palette.warning.dark} -50.94%, rgba(144, 202, 249, 0) 83.49%)`,
|
| 25 |
+
borderRadius: '50%',
|
| 26 |
+
top: -30,
|
| 27 |
+
right: -180
|
| 28 |
+
},
|
| 29 |
+
'&:before': {
|
| 30 |
+
content: '""',
|
| 31 |
+
position: 'absolute',
|
| 32 |
+
width: 210,
|
| 33 |
+
height: 210,
|
| 34 |
+
background: `linear-gradient(140.9deg, ${theme.palette.warning.dark} -14.02%, rgba(144, 202, 249, 0) 70.50%)`,
|
| 35 |
+
borderRadius: '50%',
|
| 36 |
+
top: -160,
|
| 37 |
+
right: -130
|
| 38 |
+
}
|
| 39 |
+
}));
|
| 40 |
+
|
| 41 |
+
// ==============================|| DASHBOARD - TOTAL INCOME LIGHT CARD ||============================== //
|
| 42 |
+
|
| 43 |
+
const TotalIncomeLightCard = ({ isLoading }) => {
|
| 44 |
+
const theme = useTheme();
|
| 45 |
+
|
| 46 |
+
return (
|
| 47 |
+
<>
|
| 48 |
+
{isLoading ? (
|
| 49 |
+
<TotalIncomeCard />
|
| 50 |
+
) : (
|
| 51 |
+
<CardWrapper border={false} content={false}>
|
| 52 |
+
<Box sx={{ p: 2 }}>
|
| 53 |
+
<List sx={{ py: 0 }}>
|
| 54 |
+
<ListItem alignItems="center" disableGutters sx={{ py: 0 }}>
|
| 55 |
+
<ListItemAvatar>
|
| 56 |
+
<Avatar
|
| 57 |
+
variant="rounded"
|
| 58 |
+
sx={{
|
| 59 |
+
...theme.typography.commonAvatar,
|
| 60 |
+
...theme.typography.largeAvatar,
|
| 61 |
+
backgroundColor: theme.palette.warning.light,
|
| 62 |
+
color: theme.palette.warning.dark
|
| 63 |
+
}}
|
| 64 |
+
>
|
| 65 |
+
<StorefrontTwoToneIcon fontSize="inherit" />
|
| 66 |
+
</Avatar>
|
| 67 |
+
</ListItemAvatar>
|
| 68 |
+
<ListItemText
|
| 69 |
+
sx={{
|
| 70 |
+
py: 0,
|
| 71 |
+
mt: 0.45,
|
| 72 |
+
mb: 0.45
|
| 73 |
+
}}
|
| 74 |
+
primary={<Typography variant="h4">$203k</Typography>}
|
| 75 |
+
secondary={
|
| 76 |
+
<Typography
|
| 77 |
+
variant="subtitle2"
|
| 78 |
+
sx={{
|
| 79 |
+
color: theme.palette.grey[500],
|
| 80 |
+
mt: 0.5
|
| 81 |
+
}}
|
| 82 |
+
>
|
| 83 |
+
Total Income
|
| 84 |
+
</Typography>
|
| 85 |
+
}
|
| 86 |
+
/>
|
| 87 |
+
</ListItem>
|
| 88 |
+
</List>
|
| 89 |
+
</Box>
|
| 90 |
+
</CardWrapper>
|
| 91 |
+
)}
|
| 92 |
+
</>
|
| 93 |
+
);
|
| 94 |
+
};
|
| 95 |
+
|
| 96 |
+
TotalIncomeLightCard.propTypes = {
|
| 97 |
+
isLoading: PropTypes.bool
|
| 98 |
+
};
|
| 99 |
+
|
| 100 |
+
export default TotalIncomeLightCard;
|
remix/app/components/dashboard/TotalOrderLineCard.js
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { useState } from 'react';
|
| 2 |
+
|
| 3 |
+
// material-ui
|
| 4 |
+
import { useTheme, styled } from '@mui/material/styles';
|
| 5 |
+
import { Avatar, Box, Button, Grid, Typography } from '@mui/material';
|
| 6 |
+
|
| 7 |
+
// project imports
|
| 8 |
+
import MainCard from 'ui-component/cards/MainCard';
|
| 9 |
+
import SkeletonTotalOrderCard from 'ui-component/cards/Skeleton/EarningCard';
|
| 10 |
+
import TotalOrderLineChartCard from './TotalOrderLineChartCard.client';
|
| 11 |
+
|
| 12 |
+
// assets
|
| 13 |
+
import LocalMallOutlinedIcon from '@mui/icons-material/LocalMallOutlined';
|
| 14 |
+
import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';
|
| 15 |
+
|
| 16 |
+
// types
|
| 17 |
+
import PropTypes from 'prop-types';
|
| 18 |
+
|
| 19 |
+
const CardWrapper = styled(MainCard)(({ theme }) => ({
|
| 20 |
+
backgroundColor: theme.palette.primary.dark,
|
| 21 |
+
color: '#fff',
|
| 22 |
+
overflow: 'hidden',
|
| 23 |
+
position: 'relative',
|
| 24 |
+
'&>div': {
|
| 25 |
+
position: 'relative',
|
| 26 |
+
zIndex: 5
|
| 27 |
+
},
|
| 28 |
+
'&:after': {
|
| 29 |
+
content: '""',
|
| 30 |
+
position: 'absolute',
|
| 31 |
+
width: 210,
|
| 32 |
+
height: 210,
|
| 33 |
+
background: theme.palette.primary[800],
|
| 34 |
+
borderRadius: '50%',
|
| 35 |
+
zIndex: 1,
|
| 36 |
+
top: -85,
|
| 37 |
+
right: -95,
|
| 38 |
+
[theme.breakpoints.down('sm')]: {
|
| 39 |
+
top: -105,
|
| 40 |
+
right: -140
|
| 41 |
+
}
|
| 42 |
+
},
|
| 43 |
+
'&:before': {
|
| 44 |
+
content: '""',
|
| 45 |
+
position: 'absolute',
|
| 46 |
+
zIndex: 1,
|
| 47 |
+
width: 210,
|
| 48 |
+
height: 210,
|
| 49 |
+
background: theme.palette.primary[800],
|
| 50 |
+
borderRadius: '50%',
|
| 51 |
+
top: -125,
|
| 52 |
+
right: -15,
|
| 53 |
+
opacity: 0.5,
|
| 54 |
+
[theme.breakpoints.down('sm')]: {
|
| 55 |
+
top: -155,
|
| 56 |
+
right: -70
|
| 57 |
+
}
|
| 58 |
+
}
|
| 59 |
+
}));
|
| 60 |
+
|
| 61 |
+
// ==============================|| DASHBOARD - TOTAL ORDER LINE CHART CARD ||============================== //
|
| 62 |
+
|
| 63 |
+
const TotalOrderLineCard = ({ isLoading }) => {
|
| 64 |
+
const theme = useTheme();
|
| 65 |
+
|
| 66 |
+
const [timeValue, setTimeValue] = useState(false);
|
| 67 |
+
const handleChangeTime = (event, newValue) => {
|
| 68 |
+
setTimeValue(newValue);
|
| 69 |
+
};
|
| 70 |
+
|
| 71 |
+
return (
|
| 72 |
+
<>
|
| 73 |
+
{isLoading ? (
|
| 74 |
+
<SkeletonTotalOrderCard />
|
| 75 |
+
) : (
|
| 76 |
+
<CardWrapper border={false} content={false}>
|
| 77 |
+
<Box sx={{ p: 2.25 }}>
|
| 78 |
+
<Grid container direction="column">
|
| 79 |
+
<Grid item>
|
| 80 |
+
<Grid container justifyContent="space-between">
|
| 81 |
+
<Grid item>
|
| 82 |
+
<Avatar
|
| 83 |
+
variant="rounded"
|
| 84 |
+
sx={{
|
| 85 |
+
...theme.typography.commonAvatar,
|
| 86 |
+
...theme.typography.largeAvatar,
|
| 87 |
+
backgroundColor: theme.palette.primary[800],
|
| 88 |
+
color: '#fff',
|
| 89 |
+
mt: 1
|
| 90 |
+
}}
|
| 91 |
+
>
|
| 92 |
+
<LocalMallOutlinedIcon fontSize="inherit" />
|
| 93 |
+
</Avatar>
|
| 94 |
+
</Grid>
|
| 95 |
+
<Grid item>
|
| 96 |
+
<Button
|
| 97 |
+
disableElevation
|
| 98 |
+
variant={timeValue ? 'contained' : 'text'}
|
| 99 |
+
size="small"
|
| 100 |
+
sx={{ color: 'inherit' }}
|
| 101 |
+
onClick={(e) => handleChangeTime(e, true)}
|
| 102 |
+
>
|
| 103 |
+
Month
|
| 104 |
+
</Button>
|
| 105 |
+
<Button
|
| 106 |
+
disableElevation
|
| 107 |
+
variant={!timeValue ? 'contained' : 'text'}
|
| 108 |
+
size="small"
|
| 109 |
+
sx={{ color: 'inherit' }}
|
| 110 |
+
onClick={(e) => handleChangeTime(e, false)}
|
| 111 |
+
>
|
| 112 |
+
Year
|
| 113 |
+
</Button>
|
| 114 |
+
</Grid>
|
| 115 |
+
</Grid>
|
| 116 |
+
</Grid>
|
| 117 |
+
<Grid item sx={{ mb: 0.75 }}>
|
| 118 |
+
<Grid container alignItems="center">
|
| 119 |
+
<Grid item xs={6}>
|
| 120 |
+
<Grid container alignItems="center">
|
| 121 |
+
<Grid item>
|
| 122 |
+
{timeValue ? (
|
| 123 |
+
<Typography
|
| 124 |
+
sx={{
|
| 125 |
+
fontSize: '2.125rem',
|
| 126 |
+
fontWeight: 500,
|
| 127 |
+
mr: 1,
|
| 128 |
+
mt: 1.75,
|
| 129 |
+
mb: 0.75
|
| 130 |
+
}}
|
| 131 |
+
>
|
| 132 |
+
$108
|
| 133 |
+
</Typography>
|
| 134 |
+
) : (
|
| 135 |
+
<Typography
|
| 136 |
+
sx={{
|
| 137 |
+
fontSize: '2.125rem',
|
| 138 |
+
fontWeight: 500,
|
| 139 |
+
mr: 1,
|
| 140 |
+
mt: 1.75,
|
| 141 |
+
mb: 0.75
|
| 142 |
+
}}
|
| 143 |
+
>
|
| 144 |
+
$961
|
| 145 |
+
</Typography>
|
| 146 |
+
)}
|
| 147 |
+
</Grid>
|
| 148 |
+
<Grid item>
|
| 149 |
+
<Avatar
|
| 150 |
+
sx={{
|
| 151 |
+
...theme.typography.smallAvatar,
|
| 152 |
+
cursor: 'pointer',
|
| 153 |
+
backgroundColor: theme.palette.primary[200],
|
| 154 |
+
color: theme.palette.primary.dark
|
| 155 |
+
}}
|
| 156 |
+
>
|
| 157 |
+
<ArrowDownwardIcon fontSize="inherit" sx={{ transform: 'rotate3d(1, 1, 1, 45deg)' }} />
|
| 158 |
+
</Avatar>
|
| 159 |
+
</Grid>
|
| 160 |
+
<Grid item xs={12}>
|
| 161 |
+
<Typography
|
| 162 |
+
sx={{
|
| 163 |
+
fontSize: '1rem',
|
| 164 |
+
fontWeight: 500,
|
| 165 |
+
color: theme.palette.primary[200]
|
| 166 |
+
}}
|
| 167 |
+
>
|
| 168 |
+
Total Order
|
| 169 |
+
</Typography>
|
| 170 |
+
</Grid>
|
| 171 |
+
</Grid>
|
| 172 |
+
</Grid>
|
| 173 |
+
<Grid item xs={6}>
|
| 174 |
+
<TotalOrderLineChartCard timeValue={timeValue} />
|
| 175 |
+
</Grid>
|
| 176 |
+
</Grid>
|
| 177 |
+
</Grid>
|
| 178 |
+
</Grid>
|
| 179 |
+
</Box>
|
| 180 |
+
</CardWrapper>
|
| 181 |
+
)}
|
| 182 |
+
</>
|
| 183 |
+
);
|
| 184 |
+
};
|
| 185 |
+
|
| 186 |
+
TotalOrderLineCard.propTypes = {
|
| 187 |
+
isLoading: PropTypes.bool
|
| 188 |
+
};
|
| 189 |
+
|
| 190 |
+
export default TotalOrderLineCard;
|
remix/app/components/dashboard/TotalOrderLineChartCard.client.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// third-party
|
| 2 |
+
import Chart from 'react-apexcharts';
|
| 3 |
+
|
| 4 |
+
// chart data
|
| 5 |
+
import ChartDataMonth from './chart-data/total-order-month-line-chart';
|
| 6 |
+
import ChartDataYear from './chart-data/total-order-year-line-chart';
|
| 7 |
+
|
| 8 |
+
// types
|
| 9 |
+
import PropTypes from 'prop-types';
|
| 10 |
+
|
| 11 |
+
// ==============================|| DASHBOARD - TOTAL ORDER LINE CHART CARD ||============================== //
|
| 12 |
+
|
| 13 |
+
const TotalOrderLineChartCard = ({ timeValue }) => {
|
| 14 |
+
return <>{timeValue ? <Chart {...ChartDataMonth} /> : <Chart {...ChartDataYear} />}</>;
|
| 15 |
+
};
|
| 16 |
+
|
| 17 |
+
TotalOrderLineChartCard.propTypes = {
|
| 18 |
+
timeValue: PropTypes.bool
|
| 19 |
+
};
|
| 20 |
+
|
| 21 |
+
export default TotalOrderLineChartCard;
|
remix/app/components/dashboard/chart-data/bajaj-area-chart.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// ===========================|| DASHBOARD - BAJAJ AREA CHART ||=========================== //
|
| 2 |
+
|
| 3 |
+
const chartData = {
|
| 4 |
+
type: 'area',
|
| 5 |
+
height: 95,
|
| 6 |
+
options: {
|
| 7 |
+
chart: {
|
| 8 |
+
id: 'support-chart',
|
| 9 |
+
sparkline: {
|
| 10 |
+
enabled: true
|
| 11 |
+
}
|
| 12 |
+
},
|
| 13 |
+
dataLabels: {
|
| 14 |
+
enabled: false
|
| 15 |
+
},
|
| 16 |
+
stroke: {
|
| 17 |
+
curve: 'smooth',
|
| 18 |
+
width: 1
|
| 19 |
+
},
|
| 20 |
+
tooltip: {
|
| 21 |
+
fixed: {
|
| 22 |
+
enabled: false
|
| 23 |
+
},
|
| 24 |
+
x: {
|
| 25 |
+
show: false
|
| 26 |
+
},
|
| 27 |
+
y: {
|
| 28 |
+
title: 'Ticket '
|
| 29 |
+
},
|
| 30 |
+
marker: {
|
| 31 |
+
show: false
|
| 32 |
+
}
|
| 33 |
+
}
|
| 34 |
+
},
|
| 35 |
+
series: [
|
| 36 |
+
{
|
| 37 |
+
data: [0, 15, 10, 50, 30, 40, 25]
|
| 38 |
+
}
|
| 39 |
+
]
|
| 40 |
+
};
|
| 41 |
+
|
| 42 |
+
export default chartData;
|
remix/app/components/dashboard/chart-data/total-growth-bar-chart.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// ===========================|| DASHBOARD - TOTAL GROWTH BAR CHART ||=========================== //
|
| 2 |
+
|
| 3 |
+
const chartData = {
|
| 4 |
+
height: 480,
|
| 5 |
+
type: 'bar',
|
| 6 |
+
options: {
|
| 7 |
+
chart: {
|
| 8 |
+
id: 'bar-chart',
|
| 9 |
+
stacked: true,
|
| 10 |
+
toolbar: {
|
| 11 |
+
show: true
|
| 12 |
+
},
|
| 13 |
+
zoom: {
|
| 14 |
+
enabled: true
|
| 15 |
+
}
|
| 16 |
+
},
|
| 17 |
+
responsive: [
|
| 18 |
+
{
|
| 19 |
+
breakpoint: 480,
|
| 20 |
+
options: {
|
| 21 |
+
legend: {
|
| 22 |
+
position: 'bottom',
|
| 23 |
+
offsetX: -10,
|
| 24 |
+
offsetY: 0
|
| 25 |
+
}
|
| 26 |
+
}
|
| 27 |
+
}
|
| 28 |
+
],
|
| 29 |
+
plotOptions: {
|
| 30 |
+
bar: {
|
| 31 |
+
horizontal: false,
|
| 32 |
+
columnWidth: '50%'
|
| 33 |
+
}
|
| 34 |
+
},
|
| 35 |
+
xaxis: {
|
| 36 |
+
type: 'category',
|
| 37 |
+
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
|
| 38 |
+
},
|
| 39 |
+
legend: {
|
| 40 |
+
show: true,
|
| 41 |
+
fontSize: '14px',
|
| 42 |
+
fontFamily: `'Roboto', sans-serif`,
|
| 43 |
+
position: 'bottom',
|
| 44 |
+
offsetX: 20,
|
| 45 |
+
labels: {
|
| 46 |
+
useSeriesColors: false
|
| 47 |
+
},
|
| 48 |
+
markers: {
|
| 49 |
+
width: 16,
|
| 50 |
+
height: 16,
|
| 51 |
+
radius: 5
|
| 52 |
+
},
|
| 53 |
+
itemMargin: {
|
| 54 |
+
horizontal: 15,
|
| 55 |
+
vertical: 8
|
| 56 |
+
}
|
| 57 |
+
},
|
| 58 |
+
fill: {
|
| 59 |
+
type: 'solid'
|
| 60 |
+
},
|
| 61 |
+
dataLabels: {
|
| 62 |
+
enabled: false
|
| 63 |
+
},
|
| 64 |
+
grid: {
|
| 65 |
+
show: true
|
| 66 |
+
}
|
| 67 |
+
},
|
| 68 |
+
series: [
|
| 69 |
+
{
|
| 70 |
+
name: 'Investment',
|
| 71 |
+
data: [35, 125, 35, 35, 35, 80, 35, 20, 35, 45, 15, 75]
|
| 72 |
+
},
|
| 73 |
+
{
|
| 74 |
+
name: 'Loss',
|
| 75 |
+
data: [35, 15, 15, 35, 65, 40, 80, 25, 15, 85, 25, 75]
|
| 76 |
+
},
|
| 77 |
+
{
|
| 78 |
+
name: 'Profit',
|
| 79 |
+
data: [35, 145, 35, 35, 20, 105, 100, 10, 65, 45, 30, 10]
|
| 80 |
+
},
|
| 81 |
+
{
|
| 82 |
+
name: 'Maintenance',
|
| 83 |
+
data: [0, 0, 75, 0, 0, 115, 0, 0, 0, 0, 150, 0]
|
| 84 |
+
}
|
| 85 |
+
]
|
| 86 |
+
};
|
| 87 |
+
export default chartData;
|
remix/app/components/dashboard/chart-data/total-order-month-line-chart.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// ===========================|| DASHBOARD - TOTAL ORDER MONTH CHART ||=========================== //
|
| 2 |
+
|
| 3 |
+
const chartData = {
|
| 4 |
+
type: 'line',
|
| 5 |
+
height: 90,
|
| 6 |
+
options: {
|
| 7 |
+
chart: {
|
| 8 |
+
sparkline: {
|
| 9 |
+
enabled: true
|
| 10 |
+
}
|
| 11 |
+
},
|
| 12 |
+
dataLabels: {
|
| 13 |
+
enabled: false
|
| 14 |
+
},
|
| 15 |
+
colors: ['#fff'],
|
| 16 |
+
fill: {
|
| 17 |
+
type: 'solid',
|
| 18 |
+
opacity: 1
|
| 19 |
+
},
|
| 20 |
+
stroke: {
|
| 21 |
+
curve: 'smooth',
|
| 22 |
+
width: 3
|
| 23 |
+
},
|
| 24 |
+
yaxis: {
|
| 25 |
+
min: 0,
|
| 26 |
+
max: 100
|
| 27 |
+
},
|
| 28 |
+
tooltip: {
|
| 29 |
+
theme: 'dark',
|
| 30 |
+
fixed: {
|
| 31 |
+
enabled: false
|
| 32 |
+
},
|
| 33 |
+
x: {
|
| 34 |
+
show: false
|
| 35 |
+
},
|
| 36 |
+
y: {
|
| 37 |
+
title: 'Total Order'
|
| 38 |
+
},
|
| 39 |
+
marker: {
|
| 40 |
+
show: false
|
| 41 |
+
}
|
| 42 |
+
}
|
| 43 |
+
},
|
| 44 |
+
series: [
|
| 45 |
+
{
|
| 46 |
+
name: 'series1',
|
| 47 |
+
data: [45, 66, 41, 89, 25, 44, 9, 54]
|
| 48 |
+
}
|
| 49 |
+
]
|
| 50 |
+
};
|
| 51 |
+
|
| 52 |
+
export default chartData;
|
remix/app/components/dashboard/chart-data/total-order-year-line-chart.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// ===========================|| DASHBOARD - TOTAL ORDER YEAR CHART ||=========================== //
|
| 2 |
+
|
| 3 |
+
const chartData = {
|
| 4 |
+
type: 'line',
|
| 5 |
+
height: 90,
|
| 6 |
+
options: {
|
| 7 |
+
chart: {
|
| 8 |
+
sparkline: {
|
| 9 |
+
enabled: true
|
| 10 |
+
}
|
| 11 |
+
},
|
| 12 |
+
dataLabels: {
|
| 13 |
+
enabled: false
|
| 14 |
+
},
|
| 15 |
+
colors: ['#fff'],
|
| 16 |
+
fill: {
|
| 17 |
+
type: 'solid',
|
| 18 |
+
opacity: 1
|
| 19 |
+
},
|
| 20 |
+
stroke: {
|
| 21 |
+
curve: 'smooth',
|
| 22 |
+
width: 3
|
| 23 |
+
},
|
| 24 |
+
yaxis: {
|
| 25 |
+
min: 0,
|
| 26 |
+
max: 100
|
| 27 |
+
},
|
| 28 |
+
tooltip: {
|
| 29 |
+
theme: 'dark',
|
| 30 |
+
fixed: {
|
| 31 |
+
enabled: false
|
| 32 |
+
},
|
| 33 |
+
x: {
|
| 34 |
+
show: false
|
| 35 |
+
},
|
| 36 |
+
y: {
|
| 37 |
+
title: 'Total Order'
|
| 38 |
+
},
|
| 39 |
+
marker: {
|
| 40 |
+
show: false
|
| 41 |
+
}
|
| 42 |
+
}
|
| 43 |
+
},
|
| 44 |
+
series: [
|
| 45 |
+
{
|
| 46 |
+
name: 'series1',
|
| 47 |
+
data: [35, 44, 9, 54, 45, 66, 41, 69]
|
| 48 |
+
}
|
| 49 |
+
]
|
| 50 |
+
};
|
| 51 |
+
|
| 52 |
+
export default chartData;
|
remix/app/entry.client.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { RemixBrowser } from '@remix-run/react';
|
| 2 |
+
import { startTransition, StrictMode } from 'react';
|
| 3 |
+
import { hydrateRoot } from 'react-dom/client';
|
| 4 |
+
|
| 5 |
+
function hydrate() {
|
| 6 |
+
startTransition(() => {
|
| 7 |
+
hydrateRoot(
|
| 8 |
+
document,
|
| 9 |
+
<StrictMode>
|
| 10 |
+
<RemixBrowser />
|
| 11 |
+
</StrictMode>
|
| 12 |
+
);
|
| 13 |
+
});
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
if (typeof requestIdleCallback === 'function') {
|
| 17 |
+
requestIdleCallback(hydrate);
|
| 18 |
+
} else {
|
| 19 |
+
// Safari doesn't support requestIdleCallback
|
| 20 |
+
// https://caniuse.com/requestidlecallback
|
| 21 |
+
setTimeout(hydrate, 1);
|
| 22 |
+
}
|
remix/app/entry.server.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { renderToString } from 'react-dom/server';
|
| 2 |
+
import { RemixServer } from '@remix-run/react';
|
| 3 |
+
|
| 4 |
+
import createCache from '@emotion/cache';
|
| 5 |
+
import { CacheProvider } from '@emotion/react';
|
| 6 |
+
import createEmotionServer from '@emotion/server/create-instance';
|
| 7 |
+
|
| 8 |
+
const key = 'custom';
|
| 9 |
+
const cache = createCache({ key });
|
| 10 |
+
const { extractCriticalToChunks, constructStyleTagsFromChunks } = createEmotionServer(cache);
|
| 11 |
+
|
| 12 |
+
export default function handleRequest(request, responseStatusCode, responseHeaders, remixContext) {
|
| 13 |
+
let markup = renderToString(
|
| 14 |
+
<CacheProvider value={cache}>
|
| 15 |
+
<RemixServer context={remixContext} url={request.url} />
|
| 16 |
+
</CacheProvider>
|
| 17 |
+
);
|
| 18 |
+
|
| 19 |
+
const chunks = extractCriticalToChunks(markup);
|
| 20 |
+
const styles = constructStyleTagsFromChunks(chunks);
|
| 21 |
+
|
| 22 |
+
markup = markup.replace('__STYLES__', styles);
|
| 23 |
+
|
| 24 |
+
responseHeaders.set('Content-Type', 'text/html');
|
| 25 |
+
|
| 26 |
+
return new Response('<!DOCTYPE html>' + markup, {
|
| 27 |
+
status: responseStatusCode,
|
| 28 |
+
headers: responseHeaders
|
| 29 |
+
});
|
| 30 |
+
}
|
remix/app/error/errorPage.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { useNavigate } from '@remix-run/react';
|
| 2 |
+
|
| 3 |
+
// material-ui
|
| 4 |
+
import { useTheme, styled } from '@mui/material/styles';
|
| 5 |
+
import { Button, Card, CardContent, CardMedia, Grid, Typography } from '@mui/material';
|
| 6 |
+
|
| 7 |
+
// project imports
|
| 8 |
+
import AnimateButton from 'ui-component/extended/AnimateButton';
|
| 9 |
+
import { gridSpacing } from 'store/constant';
|
| 10 |
+
|
| 11 |
+
// assets
|
| 12 |
+
import HomeTwoToneIcon from '@mui/icons-material/HomeTwoTone';
|
| 13 |
+
|
| 14 |
+
import imageBackground from 'assets/images/maintenance/img-error-bg.svg';
|
| 15 |
+
import imageDarkBackground from 'assets/images/maintenance/img-error-bg-dark.svg';
|
| 16 |
+
import imageBlue from 'assets/images/maintenance/img-error-blue.svg';
|
| 17 |
+
import imageText from 'assets/images/maintenance/img-error-text.svg';
|
| 18 |
+
import imagePurple from 'assets/images/maintenance/img-error-purple.svg';
|
| 19 |
+
|
| 20 |
+
// styles
|
| 21 |
+
const CardMediaWrapper = styled('div')({
|
| 22 |
+
maxWidth: 720,
|
| 23 |
+
margin: '0 auto',
|
| 24 |
+
position: 'relative'
|
| 25 |
+
});
|
| 26 |
+
|
| 27 |
+
const ErrorWrapper = styled('div')({
|
| 28 |
+
maxWidth: 350,
|
| 29 |
+
margin: '0 auto',
|
| 30 |
+
textAlign: 'center'
|
| 31 |
+
});
|
| 32 |
+
|
| 33 |
+
const ErrorCard = styled(Card)({
|
| 34 |
+
minHeight: '100vh',
|
| 35 |
+
display: 'flex',
|
| 36 |
+
alignItems: 'center',
|
| 37 |
+
justifyContent: 'center'
|
| 38 |
+
});
|
| 39 |
+
|
| 40 |
+
const CardMediaBlock = styled('img')({
|
| 41 |
+
position: 'absolute',
|
| 42 |
+
top: 0,
|
| 43 |
+
left: 0,
|
| 44 |
+
width: '100%',
|
| 45 |
+
animation: '3s bounce ease-in-out infinite'
|
| 46 |
+
});
|
| 47 |
+
|
| 48 |
+
const CardMediaBlue = styled('img')({
|
| 49 |
+
position: 'absolute',
|
| 50 |
+
top: 0,
|
| 51 |
+
left: 0,
|
| 52 |
+
width: '100%',
|
| 53 |
+
animation: '15s wings ease-in-out infinite'
|
| 54 |
+
});
|
| 55 |
+
|
| 56 |
+
const CardMediaPurple = styled('img')({
|
| 57 |
+
position: 'absolute',
|
| 58 |
+
top: 0,
|
| 59 |
+
left: 0,
|
| 60 |
+
width: '100%',
|
| 61 |
+
animation: '12s wings ease-in-out infinite'
|
| 62 |
+
});
|
| 63 |
+
|
| 64 |
+
// ==============================|| ERROR PAGE ||============================== //
|
| 65 |
+
|
| 66 |
+
const ErrorPage = () => {
|
| 67 |
+
const theme = useTheme();
|
| 68 |
+
const navigate = useNavigate();
|
| 69 |
+
|
| 70 |
+
return (
|
| 71 |
+
<ErrorCard>
|
| 72 |
+
<CardContent>
|
| 73 |
+
<Grid container justifyContent="center" spacing={gridSpacing}>
|
| 74 |
+
<Grid item xs={12}>
|
| 75 |
+
<CardMediaWrapper>
|
| 76 |
+
<CardMedia
|
| 77 |
+
component="img"
|
| 78 |
+
image={theme.palette.mode === 'dark' ? imageDarkBackground : imageBackground}
|
| 79 |
+
title="Slider5 image"
|
| 80 |
+
/>
|
| 81 |
+
<CardMediaBlock src={imageText} title="Slider 1 image" />
|
| 82 |
+
<CardMediaBlue src={imageBlue} title="Slider 2 image" />
|
| 83 |
+
<CardMediaPurple src={imagePurple} title="Slider 3 image" />
|
| 84 |
+
</CardMediaWrapper>
|
| 85 |
+
</Grid>
|
| 86 |
+
<Grid item xs={12}>
|
| 87 |
+
<ErrorWrapper>
|
| 88 |
+
<Grid container spacing={gridSpacing}>
|
| 89 |
+
<Grid item xs={12}>
|
| 90 |
+
<Typography variant="h1" component="div">
|
| 91 |
+
Something is wrong
|
| 92 |
+
</Typography>
|
| 93 |
+
</Grid>
|
| 94 |
+
<Grid item xs={12}>
|
| 95 |
+
<Typography variant="body2">
|
| 96 |
+
The page you are looking was moved, removed, renamed, or might never exist!{' '}
|
| 97 |
+
</Typography>
|
| 98 |
+
</Grid>
|
| 99 |
+
<Grid item xs={12}>
|
| 100 |
+
<AnimateButton>
|
| 101 |
+
<Button
|
| 102 |
+
variant="contained"
|
| 103 |
+
size="large"
|
| 104 |
+
// component={Link}
|
| 105 |
+
// to='/'
|
| 106 |
+
onClick={() => {
|
| 107 |
+
navigate(-1);
|
| 108 |
+
}}
|
| 109 |
+
>
|
| 110 |
+
<HomeTwoToneIcon sx={{ fontSize: '1.3rem', mr: 0.75 }} /> Home
|
| 111 |
+
</Button>
|
| 112 |
+
{/* <Link to='/'>BACK TO HOME</Link> */}
|
| 113 |
+
</AnimateButton>
|
| 114 |
+
</Grid>
|
| 115 |
+
</Grid>
|
| 116 |
+
</ErrorWrapper>
|
| 117 |
+
</Grid>
|
| 118 |
+
</Grid>
|
| 119 |
+
</CardContent>
|
| 120 |
+
</ErrorCard>
|
| 121 |
+
);
|
| 122 |
+
};
|
| 123 |
+
|
| 124 |
+
export default ErrorPage;
|
remix/app/error/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { useSelector } from 'react-redux';
|
| 2 |
+
|
| 3 |
+
// material-ui
|
| 4 |
+
import { CssBaseline, StyledEngineProvider } from '@mui/material';
|
| 5 |
+
import { ThemeProvider } from '@mui/material/styles';
|
| 6 |
+
|
| 7 |
+
// project imports
|
| 8 |
+
import NavigationScroll from 'layout/NavigationScroll';
|
| 9 |
+
import theme from 'themes';
|
| 10 |
+
import ErrorPage from './errorPage';
|
| 11 |
+
|
| 12 |
+
const Error = () => {
|
| 13 |
+
const customization = useSelector((state) => state.customization);
|
| 14 |
+
return (
|
| 15 |
+
<StyledEngineProvider injectfirst>
|
| 16 |
+
<ThemeProvider theme={theme(customization)}>
|
| 17 |
+
<CssBaseline />
|
| 18 |
+
<NavigationScroll>
|
| 19 |
+
<ErrorPage />
|
| 20 |
+
</NavigationScroll>
|
| 21 |
+
</ThemeProvider>
|
| 22 |
+
</StyledEngineProvider>
|
| 23 |
+
);
|
| 24 |
+
};
|
| 25 |
+
|
| 26 |
+
export default Error;
|
remix/app/hooks/useScriptRef.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { useEffect, useRef } from 'react';
|
| 2 |
+
|
| 3 |
+
// ==============================|| ELEMENT REFERENCE HOOKS ||============================== //
|
| 4 |
+
|
| 5 |
+
const useScriptRef = () => {
|
| 6 |
+
const scripted = useRef(true);
|
| 7 |
+
|
| 8 |
+
useEffect(
|
| 9 |
+
() => () => {
|
| 10 |
+
scripted.current = false;
|
| 11 |
+
},
|
| 12 |
+
[]
|
| 13 |
+
);
|
| 14 |
+
|
| 15 |
+
return scripted;
|
| 16 |
+
};
|
| 17 |
+
|
| 18 |
+
export default useScriptRef;
|