Initial commit. UI localisation works.

main
Josef Rokos 2 years ago
commit 9f17393310

13
.gitignore vendored

@ -0,0 +1,13 @@
# Generated by Cargo
# will have compiled files and executables
/target/
pkg
# These are backup files generated by rustfmt
**/*.rs.bk
# node e2e test tools and outputs
node_modules/
test-results/
end2end/playwright-report/
playwright/.cache/

2858
Cargo.lock generated

File diff suppressed because it is too large Load Diff

@ -0,0 +1,85 @@
[package]
name = "rezervator"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib", "rlib"]
[dependencies]
actix-files = { version = "0.6", optional = true }
actix-web = { version = "4", optional = true, features = ["macros"] }
actix-session = { version = "0.7.2", optional = true, features = ["cookie-session"] }
console_error_panic_hook = "0.1"
cfg-if = "1"
leptos = { version = "0.4.8" }
leptos_meta = { version = "0.4.8" }
leptos_actix = { version = "0.4.8", optional = true }
leptos_router = { version = "0.4.8" }
serde = { version = "1", features = ["derive"] }
wasm-bindgen = "=0.2.87"
web-sys = { version = "0.3.61", features = ["Navigator"] }
lazy_static = "1.4.0"
[features]
csr = ["leptos/csr", "leptos_meta/csr", "leptos_router/csr"]
hydrate = ["leptos/hydrate", "leptos_meta/hydrate", "leptos_router/hydrate"]
ssr = [
"dep:actix-files",
"dep:actix-web",
"dep:leptos_actix",
"dep:actix-session",
"leptos/ssr",
"leptos_meta/ssr",
"leptos_router/ssr",
]
[package.metadata.leptos]
# The name used by wasm-bindgen/cargo-leptos for the JS/WASM bundle. Defaults to the crate name
output-name = "rezervator"
# The site root folder is where cargo-leptos generate all output. WARNING: all content of this folder will be erased on a rebuild. Use it in your server setup.
site-root = "target/site"
# The site-root relative folder where all compiled output (JS, WASM and CSS) is written
# Defaults to pkg
site-pkg-dir = "pkg"
# [Optional] The source CSS file. If it ends with .sass or .scss then it will be compiled by dart-sass into CSS. The CSS is optimized by Lightning CSS before being written to <site-root>/<site-pkg>/app.css
style-file = "style/main.scss"
# Assets source dir. All files found here will be copied and synchronized to site-root.
# The assets-dir cannot have a sub directory with the same name/path as site-pkg-dir.
#
# Optional. Env: LEPTOS_ASSETS_DIR.
assets-dir = "assets"
# The IP and port (ex: 127.0.0.1:3000) where the server serves the content. Use it in your server setup.
site-addr = "127.0.0.1:3000"
# The port to use for automatic reload monitoring
reload-port = 3001
# [Optional] Command to use when running end2end tests. It will run in the end2end dir.
# [Windows] for non-WSL use "npx.cmd playwright test"
# This binary name can be checked in Powershell with Get-Command npx
end2end-cmd = "npx playwright test"
end2end-dir = "end2end"
# The browserlist query used for optimizing the CSS.
browserquery = "defaults"
# Set by cargo-leptos watch when building with that tool. Controls whether autoreload JS will be included in the head
watch = false
# The environment Leptos will run in, usually either "DEV" or "PROD"
env = "DEV"
# The features to use when compiling the bin target
#
# Optional. Can be over-ridden with the command line parameter --bin-features
bin-features = ["ssr"]
# If the --no-default-features flag should be used when compiling the bin target
#
# Optional. Defaults to false.
bin-default-features = false
# The features to use when compiling the lib target
#
# Optional. Can be over-ridden with the command line parameter --lib-features
lib-features = ["hydrate"]
# If the --no-default-features flag should be used when compiling the lib target
#
# Optional. Defaults to false.
lib-default-features = false

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 henrik
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,107 @@
/*
* demo.css
* File include item demo only specific css only
******************************************************************************/
.menu .app-brand.demo {
height: 64px;
margin-top: 12px;
}
.app-brand-logo.demo svg {
width: 22px;
height: 38px;
}
.app-brand-text.demo {
font-size: 1.75rem;
letter-spacing: -0.5px;
text-transform: lowercase;
}
/* ! For .layout-navbar-fixed added fix padding top tpo .layout-page */
/* Detached navbar */
.layout-navbar-fixed .layout-wrapper:not(.layout-horizontal):not(.layout-without-menu) .layout-page {
padding-top: 76px !important;
}
/* Default navbar */
.layout-navbar-fixed .layout-wrapper:not(.layout-without-menu) .layout-page {
padding-top: 64px !important;
}
/* Navbar page z-index issue solution */
.content-wrapper .navbar {
z-index: auto;
}
/*
* Content
******************************************************************************/
.demo-blocks > * {
display: block !important;
}
.demo-inline-spacing > * {
margin: 1rem 0.375rem 0 0 !important;
}
/* ? .demo-vertical-spacing class is used to have vertical margins between elements. To remove margin-top from the first-child, use .demo-only-element class with .demo-vertical-spacing class. For example, we have used this class in forms-input-groups.html file. */
.demo-vertical-spacing > * {
margin-top: 1rem !important;
margin-bottom: 0 !important;
}
.demo-vertical-spacing.demo-only-element > :first-child {
margin-top: 0 !important;
}
.demo-vertical-spacing-lg > * {
margin-top: 1.875rem !important;
margin-bottom: 0 !important;
}
.demo-vertical-spacing-lg.demo-only-element > :first-child {
margin-top: 0 !important;
}
.demo-vertical-spacing-xl > * {
margin-top: 5rem !important;
margin-bottom: 0 !important;
}
.demo-vertical-spacing-xl.demo-only-element > :first-child {
margin-top: 0 !important;
}
.rtl-only {
display: none !important;
text-align: left !important;
direction: ltr !important;
}
[dir='rtl'] .rtl-only {
display: block !important;
}
/*
* Layout demo
******************************************************************************/
.layout-demo-wrapper {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
margin-top: 1rem;
}
.layout-demo-placeholder img {
width: 900px;
}
.layout-demo-info {
text-align: center;
margin-top: 1rem;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 681 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 702 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 776 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 689 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 936 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 920 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

@ -0,0 +1,27 @@
/**
* Config
* -------------------------------------------------------------------------------------
* ! IMPORTANT: Make sure you clear the browser local storage In order to see the config changes in the template.
* ! To clear local storage: (https://www.leadshook.com/help/how-to-clear-local-storage-in-google-chrome-browser/).
*/
'use strict';
// JS global variables
let config = {
colors: {
primary: '#696cff',
secondary: '#8592a3',
success: '#71dd37',
info: '#03c3ec',
warning: '#ffab00',
danger: '#ff3e1d',
dark: '#233446',
black: '#000',
white: '#fff',
body: '#f4f5fb',
headingColor: '#566a7f',
axisColor: '#a1acb8',
borderColor: '#eceef1'
}
};

@ -0,0 +1,662 @@
/**
* Dashboard Analytics
*/
'use strict';
(function () {
let cardColor, headingColor, axisColor, shadeColor, borderColor;
cardColor = config.colors.white;
headingColor = config.colors.headingColor;
axisColor = config.colors.axisColor;
borderColor = config.colors.borderColor;
// Total Revenue Report Chart - Bar Chart
// --------------------------------------------------------------------
const totalRevenueChartEl = document.querySelector('#totalRevenueChart'),
totalRevenueChartOptions = {
series: [
{
name: '2021',
data: [18, 7, 15, 29, 18, 12, 9]
},
{
name: '2020',
data: [-13, -18, -9, -14, -5, -17, -15]
}
],
chart: {
height: 300,
stacked: true,
type: 'bar',
toolbar: { show: false }
},
plotOptions: {
bar: {
horizontal: false,
columnWidth: '33%',
borderRadius: 12,
startingShape: 'rounded',
endingShape: 'rounded'
}
},
colors: [config.colors.primary, config.colors.info],
dataLabels: {
enabled: false
},
stroke: {
curve: 'smooth',
width: 6,
lineCap: 'round',
colors: [cardColor]
},
legend: {
show: true,
horizontalAlign: 'left',
position: 'top',
markers: {
height: 8,
width: 8,
radius: 12,
offsetX: -3
},
labels: {
colors: axisColor
},
itemMargin: {
horizontal: 10
}
},
grid: {
borderColor: borderColor,
padding: {
top: 0,
bottom: -8,
left: 20,
right: 20
}
},
xaxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul'],
labels: {
style: {
fontSize: '13px',
colors: axisColor
}
},
axisTicks: {
show: false
},
axisBorder: {
show: false
}
},
yaxis: {
labels: {
style: {
fontSize: '13px',
colors: axisColor
}
}
},
responsive: [
{
breakpoint: 1700,
options: {
plotOptions: {
bar: {
borderRadius: 10,
columnWidth: '32%'
}
}
}
},
{
breakpoint: 1580,
options: {
plotOptions: {
bar: {
borderRadius: 10,
columnWidth: '35%'
}
}
}
},
{
breakpoint: 1440,
options: {
plotOptions: {
bar: {
borderRadius: 10,
columnWidth: '42%'
}
}
}
},
{
breakpoint: 1300,
options: {
plotOptions: {
bar: {
borderRadius: 10,
columnWidth: '48%'
}
}
}
},
{
breakpoint: 1200,
options: {
plotOptions: {
bar: {
borderRadius: 10,
columnWidth: '40%'
}
}
}
},
{
breakpoint: 1040,
options: {
plotOptions: {
bar: {
borderRadius: 11,
columnWidth: '48%'
}
}
}
},
{
breakpoint: 991,
options: {
plotOptions: {
bar: {
borderRadius: 10,
columnWidth: '30%'
}
}
}
},
{
breakpoint: 840,
options: {
plotOptions: {
bar: {
borderRadius: 10,
columnWidth: '35%'
}
}
}
},
{
breakpoint: 768,
options: {
plotOptions: {
bar: {
borderRadius: 10,
columnWidth: '28%'
}
}
}
},
{
breakpoint: 640,
options: {
plotOptions: {
bar: {
borderRadius: 10,
columnWidth: '32%'
}
}
}
},
{
breakpoint: 576,
options: {
plotOptions: {
bar: {
borderRadius: 10,
columnWidth: '37%'
}
}
}
},
{
breakpoint: 480,
options: {
plotOptions: {
bar: {
borderRadius: 10,
columnWidth: '45%'
}
}
}
},
{
breakpoint: 420,
options: {
plotOptions: {
bar: {
borderRadius: 10,
columnWidth: '52%'
}
}
}
},
{
breakpoint: 380,
options: {
plotOptions: {
bar: {
borderRadius: 10,
columnWidth: '60%'
}
}
}
}
],
states: {
hover: {
filter: {
type: 'none'
}
},
active: {
filter: {
type: 'none'
}
}
}
};
if (typeof totalRevenueChartEl !== undefined && totalRevenueChartEl !== null) {
const totalRevenueChart = new ApexCharts(totalRevenueChartEl, totalRevenueChartOptions);
totalRevenueChart.render();
}
// Growth Chart - Radial Bar Chart
// --------------------------------------------------------------------
const growthChartEl = document.querySelector('#growthChart'),
growthChartOptions = {
series: [78],
labels: ['Growth'],
chart: {
height: 240,
type: 'radialBar'
},
plotOptions: {
radialBar: {
size: 150,
offsetY: 10,
startAngle: -150,
endAngle: 150,
hollow: {
size: '55%'
},
track: {
background: cardColor,
strokeWidth: '100%'
},
dataLabels: {
name: {
offsetY: 15,
color: headingColor,
fontSize: '15px',
fontWeight: '600',
fontFamily: 'Public Sans'
},
value: {
offsetY: -25,
color: headingColor,
fontSize: '22px',
fontWeight: '500',
fontFamily: 'Public Sans'
}
}
}
},
colors: [config.colors.primary],
fill: {
type: 'gradient',
gradient: {
shade: 'dark',
shadeIntensity: 0.5,
gradientToColors: [config.colors.primary],
inverseColors: true,
opacityFrom: 1,
opacityTo: 0.6,
stops: [30, 70, 100]
}
},
stroke: {
dashArray: 5
},
grid: {
padding: {
top: -35,
bottom: -10
}
},
states: {
hover: {
filter: {
type: 'none'
}
},
active: {
filter: {
type: 'none'
}
}
}
};
if (typeof growthChartEl !== undefined && growthChartEl !== null) {
const growthChart = new ApexCharts(growthChartEl, growthChartOptions);
growthChart.render();
}
// Profit Report Line Chart
// --------------------------------------------------------------------
const profileReportChartEl = document.querySelector('#profileReportChart'),
profileReportChartConfig = {
chart: {
height: 80,
// width: 175,
type: 'line',
toolbar: {
show: false
},
dropShadow: {
enabled: true,
top: 10,
left: 5,
blur: 3,
color: config.colors.warning,
opacity: 0.15
},
sparkline: {
enabled: true
}
},
grid: {
show: false,
padding: {
right: 8
}
},
colors: [config.colors.warning],
dataLabels: {
enabled: false
},
stroke: {
width: 5,
curve: 'smooth'
},
series: [
{
data: [110, 270, 145, 245, 205, 285]
}
],
xaxis: {
show: false,
lines: {
show: false
},
labels: {
show: false
},
axisBorder: {
show: false
}
},
yaxis: {
show: false
}
};
if (typeof profileReportChartEl !== undefined && profileReportChartEl !== null) {
const profileReportChart = new ApexCharts(profileReportChartEl, profileReportChartConfig);
profileReportChart.render();
}
// Order Statistics Chart
// --------------------------------------------------------------------
const chartOrderStatistics = document.querySelector('#orderStatisticsChart'),
orderChartConfig = {
chart: {
height: 165,
width: 130,
type: 'donut'
},
labels: ['Electronic', 'Sports', 'Decor', 'Fashion'],
series: [85, 15, 50, 50],
colors: [config.colors.primary, config.colors.secondary, config.colors.info, config.colors.success],
stroke: {
width: 5,
colors: cardColor
},
dataLabels: {
enabled: false,
formatter: function (val, opt) {
return parseInt(val) + '%';
}
},
legend: {
show: false
},
grid: {
padding: {
top: 0,
bottom: 0,
right: 15
}
},
plotOptions: {
pie: {
donut: {
size: '75%',
labels: {
show: true,
value: {
fontSize: '1.5rem',
fontFamily: 'Public Sans',
color: headingColor,
offsetY: -15,
formatter: function (val) {
return parseInt(val) + '%';
}
},
name: {
offsetY: 20,
fontFamily: 'Public Sans'
},
total: {
show: true,
fontSize: '0.8125rem',
color: axisColor,
label: 'Weekly',
formatter: function (w) {
return '38%';
}
}
}
}
}
}
};
if (typeof chartOrderStatistics !== undefined && chartOrderStatistics !== null) {
const statisticsChart = new ApexCharts(chartOrderStatistics, orderChartConfig);
statisticsChart.render();
}
// Income Chart - Area chart
// --------------------------------------------------------------------
const incomeChartEl = document.querySelector('#incomeChart'),
incomeChartConfig = {
series: [
{
data: [24, 21, 30, 22, 42, 26, 35, 29]
}
],
chart: {
height: 215,
parentHeightOffset: 0,
parentWidthOffset: 0,
toolbar: {
show: false
},
type: 'area'
},
dataLabels: {
enabled: false
},
stroke: {
width: 2,
curve: 'smooth'
},
legend: {
show: false
},
markers: {
size: 6,
colors: 'transparent',
strokeColors: 'transparent',
strokeWidth: 4,
discrete: [
{
fillColor: config.colors.white,
seriesIndex: 0,
dataPointIndex: 7,
strokeColor: config.colors.primary,
strokeWidth: 2,
size: 6,
radius: 8
}
],
hover: {
size: 7
}
},
colors: [config.colors.primary],
fill: {
type: 'gradient',
gradient: {
shade: shadeColor,
shadeIntensity: 0.6,
opacityFrom: 0.5,
opacityTo: 0.25,
stops: [0, 95, 100]
}
},
grid: {
borderColor: borderColor,
strokeDashArray: 3,
padding: {
top: -20,
bottom: -8,
left: -10,
right: 8
}
},
xaxis: {
categories: ['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul'],
axisBorder: {
show: false
},
axisTicks: {
show: false
},
labels: {
show: true,
style: {
fontSize: '13px',
colors: axisColor
}
}
},
yaxis: {
labels: {
show: false
},
min: 10,
max: 50,
tickAmount: 4
}
};
if (typeof incomeChartEl !== undefined && incomeChartEl !== null) {
const incomeChart = new ApexCharts(incomeChartEl, incomeChartConfig);
incomeChart.render();
}
// Expenses Mini Chart - Radial Chart
// --------------------------------------------------------------------
const weeklyExpensesEl = document.querySelector('#expensesOfWeek'),
weeklyExpensesConfig = {
series: [65],
chart: {
width: 60,
height: 60,
type: 'radialBar'
},
plotOptions: {
radialBar: {
startAngle: 0,
endAngle: 360,
strokeWidth: '8',
hollow: {
margin: 2,
size: '45%'
},
track: {
strokeWidth: '50%',
background: borderColor
},
dataLabels: {
show: true,
name: {
show: false
},
value: {
formatter: function (val) {
return '$' + parseInt(val);
},
offsetY: 5,
color: '#697a8d',
fontSize: '13px',
show: true
}
}
}
},
fill: {
type: 'solid',
colors: config.colors.primary
},
stroke: {
lineCap: 'round'
},
grid: {
padding: {
top: -10,
bottom: -15,
left: -10,
right: -10
}
},
states: {
hover: {
filter: {
type: 'none'
}
},
active: {
filter: {
type: 'none'
}
}
}
};
if (typeof weeklyExpensesEl !== undefined && weeklyExpensesEl !== null) {
const weeklyExpenses = new ApexCharts(weeklyExpensesEl, weeklyExpensesConfig);
weeklyExpenses.render();
}
})();

@ -0,0 +1,37 @@
/**
* Perfect Scrollbar
*/
'use strict';
document.addEventListener('DOMContentLoaded', function () {
(function () {
const verticalExample = document.getElementById('vertical-example'),
horizontalExample = document.getElementById('horizontal-example'),
horizVertExample = document.getElementById('both-scrollbars-example');
// Vertical Example
// --------------------------------------------------------------------
if (verticalExample) {
new PerfectScrollbar(verticalExample, {
wheelPropagation: false
});
}
// Horizontal Example
// --------------------------------------------------------------------
if (horizontalExample) {
new PerfectScrollbar(horizontalExample, {
wheelPropagation: false,
suppressScrollY: true
});
}
// Both vertical and Horizontal Example
// --------------------------------------------------------------------
if (horizVertExample) {
new PerfectScrollbar(horizVertExample, {
wheelPropagation: false
});
}
})();
});

@ -0,0 +1,11 @@
/**
* Form Basic Inputs
*/
'use strict';
(function () {
// Indeterminate checkbox
const checkbox = document.getElementById('defaultCheck2');
checkbox.indeterminate = true;
})();

@ -0,0 +1,118 @@
/**
* Main
*/
'use strict';
let menu, animate;
(function () {
// Initialize menu
//-----------------
let layoutMenuEl = document.querySelectorAll('#layout-menu');
layoutMenuEl.forEach(function (element) {
menu = new Menu(element, {
orientation: 'vertical',
closeChildren: false
});
// Change parameter to true if you want scroll animation
window.Helpers.scrollToActive((animate = false));
window.Helpers.mainMenu = menu;
});
// Initialize menu togglers and bind click on each
let menuToggler = document.querySelectorAll('.layout-menu-toggle');
menuToggler.forEach(item => {
item.addEventListener('click', event => {
event.preventDefault();
window.Helpers.toggleCollapsed();
});
});
// Display menu toggle (layout-menu-toggle) on hover with delay
let delay = function (elem, callback) {
let timeout = null;
elem.onmouseenter = function () {
// Set timeout to be a timer which will invoke callback after 300ms (not for small screen)
if (!Helpers.isSmallScreen()) {
timeout = setTimeout(callback, 300);
} else {
timeout = setTimeout(callback, 0);
}
};
elem.onmouseleave = function () {
// Clear any timers set to timeout
document.querySelector('.layout-menu-toggle').classList.remove('d-block');
clearTimeout(timeout);
};
};
if (document.getElementById('layout-menu')) {
delay(document.getElementById('layout-menu'), function () {
// not for small screen
if (!Helpers.isSmallScreen()) {
document.querySelector('.layout-menu-toggle').classList.add('d-block');
}
});
}
// Display in main menu when menu scrolls
let menuInnerContainer = document.getElementsByClassName('menu-inner'),
menuInnerShadow = document.getElementsByClassName('menu-inner-shadow')[0];
if (menuInnerContainer.length > 0 && menuInnerShadow) {
menuInnerContainer[0].addEventListener('ps-scroll-y', function () {
if (this.querySelector('.ps__thumb-y').offsetTop) {
menuInnerShadow.style.display = 'block';
} else {
menuInnerShadow.style.display = 'none';
}
});
}
// Init helpers & misc
// --------------------
// Init BS Tooltip
const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
tooltipTriggerList.map(function (tooltipTriggerEl) {
return new bootstrap.Tooltip(tooltipTriggerEl);
});
// Accordion active class
const accordionActiveFunction = function (e) {
if (e.type == 'show.bs.collapse' || e.type == 'show.bs.collapse') {
e.target.closest('.accordion-item').classList.add('active');
} else {
e.target.closest('.accordion-item').classList.remove('active');
}
};
const accordionTriggerList = [].slice.call(document.querySelectorAll('.accordion'));
const accordionList = accordionTriggerList.map(function (accordionTriggerEl) {
accordionTriggerEl.addEventListener('show.bs.collapse', accordionActiveFunction);
accordionTriggerEl.addEventListener('hide.bs.collapse', accordionActiveFunction);
});
// Auto update layout based on screen size
window.Helpers.setAutoUpdate(true);
// Toggle Password Visibility
window.Helpers.initPasswordToggle();
// Speech To Text
window.Helpers.initSpeechToText();
// Manage menu expanded/collapsed with templateCustomizer & local storage
//------------------------------------------------------------------
// If current layout is horizontal OR current window screen is small (overlay menu) than return from here
if (window.Helpers.isSmallScreen()) {
return;
}
// If current layout is vertical and current window screen is > small
// Auto update menu collapsed/expanded based on the themeConfig
window.Helpers.setCollapsed(true, false);
})();

@ -0,0 +1,29 @@
/**
* Account Settings - Account
*/
'use strict';
document.addEventListener('DOMContentLoaded', function (e) {
(function () {
const deactivateAcc = document.querySelector('#formAccountDeactivation');
// Update/reset user image of account page
let accountUserImage = document.getElementById('uploadedAvatar');
const fileInput = document.querySelector('.account-file-input'),
resetFileInput = document.querySelector('.account-image-reset');
if (accountUserImage) {
const resetImage = accountUserImage.src;
fileInput.onchange = () => {
if (fileInput.files[0]) {
accountUserImage.src = window.URL.createObjectURL(fileInput.files[0]);
}
};
resetFileInput.onclick = () => {
fileInput.value = '';
accountUserImage.src = resetImage;
};
}
})();
});

@ -0,0 +1,33 @@
/**
* UI Modals
*/
'use strict';
(function () {
// On hiding modal, remove iframe video/audio to stop playing
const youTubeModal = document.querySelector('#youTubeModal'),
youTubeModalVideo = youTubeModal.querySelector('iframe');
youTubeModal.addEventListener('hidden.bs.modal', function () {
youTubeModalVideo.setAttribute('src', '');
});
// Function to get and auto play youTube video
const autoPlayYouTubeModal = function () {
const modalTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="modal"]'));
modalTriggerList.map(function (modalTriggerEl) {
modalTriggerEl.onclick = function () {
const theModal = this.getAttribute('data-bs-target'),
videoSRC = this.getAttribute('data-theVideo'),
videoSRCauto = `${videoSRC}?autoplay=1`,
modalVideo = document.querySelector(`${theModal} iframe`);
if (modalVideo) {
modalVideo.setAttribute('src', videoSRCauto);
}
};
});
};
// Calling function on load
autoPlayYouTubeModal();
})();

@ -0,0 +1,13 @@
// /**
// * UI Tooltips & Popovers
// */
'use strict';
(function () {
const popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]'));
const popoverList = popoverTriggerList.map(function (popoverTriggerEl) {
// added { html: true, sanitize: false } option to render button in content area of popover
return new bootstrap.Popover(popoverTriggerEl, { html: true, sanitize: false });
});
})();

@ -0,0 +1,39 @@
/**
* UI Toasts
*/
'use strict';
(function () {
// Bootstrap toasts example
// --------------------------------------------------------------------
const toastPlacementExample = document.querySelector('.toast-placement-ex'),
toastPlacementBtn = document.querySelector('#showToastPlacement');
let selectedType, selectedPlacement, toastPlacement;
// Dispose toast when open another
function toastDispose(toast) {
if (toast && toast._element !== null) {
if (toastPlacementExample) {
toastPlacementExample.classList.remove(selectedType);
DOMTokenList.prototype.remove.apply(toastPlacementExample.classList, selectedPlacement);
}
toast.dispose();
}
}
// Placement Button click
if (toastPlacementBtn) {
toastPlacementBtn.onclick = function () {
if (toastPlacement) {
toastDispose(toastPlacement);
}
selectedType = document.querySelector('#selectTypeOpt').value;
selectedPlacement = document.querySelector('#selectPlacement').value.split(' ');
toastPlacementExample.classList.add(selectedType);
DOMTokenList.prototype.add.apply(toastPlacementExample.classList, selectedPlacement);
toastPlacement = new bootstrap.Toast(toastPlacementExample);
toastPlacement.show();
};
}
})();

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -0,0 +1,7 @@
.api-key-actions {
position: absolute !important;
top: 0.75rem;
right: 0.5rem;
}
/*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhZ2VzL3BhZ2UtYWNjb3VudC1zZXR0aW5ncy5jc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7RUFDRSw2QkFBNkI7RUFDN0IsWUFBWTtFQUNaLGFBQWE7QUFDZiIsImZpbGUiOiJwYWdlcy9wYWdlLWFjY291bnQtc2V0dGluZ3MuY3NzIiwic291cmNlc0NvbnRlbnQiOlsiLmFwaS1rZXktYWN0aW9ucyB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZSAhaW1wb3J0YW50O1xuICB0b3A6IDAuNzVyZW07XG4gIHJpZ2h0OiAwLjVyZW07XG59XG4iXX0= */

File diff suppressed because one or more lines are too long

@ -0,0 +1,29 @@
#icons-container .icon-card {
width: 128px;
}
#icons-container .icon-card i {
font-size: 2rem;
}
@media (max-width: 1024px) {
#icons-container .icon-card {
width: 126px;
}
}
@media (max-width: 767.98px) {
#icons-container .icon-card {
width: 131px;
}
}
@media (max-width: 414px) {
#icons-container .icon-card {
width: 110px;
}
}
@media (max-width: 375px) {
#icons-container .icon-card {
width: 150px;
}
}
/*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhZ2VzL3BhZ2UtaWNvbnMuY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0VBQ0UsWUFBWTtBQUNkO0FBQ0E7RUFDRSxlQUFlO0FBQ2pCOztBQUVBO0VBQ0U7SUFDRSxZQUFZO0VBQ2Q7QUFDRjtBQUNBO0VBQ0U7SUFDRSxZQUFZO0VBQ2Q7QUFDRjtBQUNBO0VBQ0U7SUFDRSxZQUFZO0VBQ2Q7QUFDRjtBQUNBO0VBQ0U7SUFDRSxZQUFZO0VBQ2Q7QUFDRiIsImZpbGUiOiJwYWdlcy9wYWdlLWljb25zLmNzcyIsInNvdXJjZXNDb250ZW50IjpbIiNpY29ucy1jb250YWluZXIgLmljb24tY2FyZCB7XG4gIHdpZHRoOiAxMjhweDtcbn1cbiNpY29ucy1jb250YWluZXIgLmljb24tY2FyZCBpIHtcbiAgZm9udC1zaXplOiAycmVtO1xufVxuXG5AbWVkaWEgKG1heC13aWR0aDogMTAyNHB4KSB7XG4gICNpY29ucy1jb250YWluZXIgLmljb24tY2FyZCB7XG4gICAgd2lkdGg6IDEyNnB4O1xuICB9XG59XG5AbWVkaWEgKG1heC13aWR0aDogNzY3Ljk4cHgpIHtcbiAgI2ljb25zLWNvbnRhaW5lciAuaWNvbi1jYXJkIHtcbiAgICB3aWR0aDogMTMxcHg7XG4gIH1cbn1cbkBtZWRpYSAobWF4LXdpZHRoOiA0MTRweCkge1xuICAjaWNvbnMtY29udGFpbmVyIC5pY29uLWNhcmQge1xuICAgIHdpZHRoOiAxMTBweDtcbiAgfVxufVxuQG1lZGlhIChtYXgtd2lkdGg6IDM3NXB4KSB7XG4gICNpY29ucy1jb250YWluZXIgLmljb24tY2FyZCB7XG4gICAgd2lkdGg6IDE1MHB4O1xuICB9XG59XG4iXX0= */

@ -0,0 +1,10 @@
.misc-wrapper {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
min-height: calc(100vh - (1.625rem * 2));
text-align: center;
}
/*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhZ2VzL3BhZ2UtbWlzYy5jc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7RUFDRSxhQUFhO0VBQ2Isc0JBQXNCO0VBQ3RCLHVCQUF1QjtFQUN2QixtQkFBbUI7RUFDbkIsd0NBQXdDO0VBQ3hDLGtCQUFrQjtBQUNwQiIsImZpbGUiOiJwYWdlcy9wYWdlLW1pc2MuY3NzIiwic291cmNlc0NvbnRlbnQiOlsiLm1pc2Mtd3JhcHBlciB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBtaW4taGVpZ2h0OiBjYWxjKDEwMHZoIC0gKDEuNjI1cmVtICogMikpO1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG59XG4iXX0= */

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,746 @@
/**
* Apex Charts
*/
.apexcharts-canvas {
position: relative;
user-select: none;
/* cannot give overflow: hidden as it will crop tooltips which overflow outside chart area */
}
/* scrollbar is not visible by default for legend, hence forcing the visibility */
.apexcharts-canvas ::-webkit-scrollbar {
-webkit-appearance: none;
width: 6px;
}
.apexcharts-canvas ::-webkit-scrollbar-thumb {
border-radius: 4px;
background-color: rgba(0, 0, 0, 0.5);
box-shadow: 0 0 1px rgba(255, 255, 255, 0.5);
-webkit-box-shadow: 0 0 1px rgba(255, 255, 255, 0.5);
}
.apexcharts-inner {
position: relative;
}
.apexcharts-text tspan {
font-family: inherit;
}
.legend-mouseover-inactive {
transition: 0.15s ease all;
opacity: 0.2;
}
.apexcharts-series-collapsed {
opacity: 0;
}
.apexcharts-tooltip {
border-radius: 5px;
box-shadow: 2px 2px 6px -4px #999;
cursor: default;
font-size: 14px;
left: 62px;
opacity: 0;
pointer-events: none;
position: absolute;
top: 20px;
display: flex;
flex-direction: column;
overflow: hidden;
white-space: nowrap;
z-index: 12;
transition: 0.15s ease all;
}
.apexcharts-tooltip.apexcharts-active {
opacity: 1;
transition: 0.15s ease all;
}
.apexcharts-tooltip.apexcharts-theme-light {
border: 1px solid #e3e3e3;
background: rgba(255, 255, 255, 0.96);
}
.apexcharts-tooltip.apexcharts-theme-dark {
color: #fff;
background: rgba(30, 30, 30, 0.8);
}
.apexcharts-tooltip * {
font-family: inherit;
}
.apexcharts-tooltip-title {
padding: 6px;
font-size: 15px;
margin-bottom: 4px;
}
.apexcharts-tooltip.apexcharts-theme-light .apexcharts-tooltip-title {
background: #ECEFF1;
border-bottom: 1px solid #ddd;
}
.apexcharts-tooltip.apexcharts-theme-dark .apexcharts-tooltip-title {
background: rgba(0, 0, 0, 0.7);
border-bottom: 1px solid #333;
}
.apexcharts-tooltip-text-y-value,
.apexcharts-tooltip-text-goals-value,
.apexcharts-tooltip-text-z-value {
display: inline-block;
font-weight: 600;
margin-left: 5px;
}
.apexcharts-tooltip-text-y-label:empty,
.apexcharts-tooltip-text-y-value:empty,
.apexcharts-tooltip-text-goals-label:empty,
.apexcharts-tooltip-text-goals-value:empty,
.apexcharts-tooltip-text-z-value:empty {
display: none;
}
.apexcharts-tooltip-text-y-value,
.apexcharts-tooltip-text-goals-value,
.apexcharts-tooltip-text-z-value {
font-weight: 600;
}
.apexcharts-tooltip-text-goals-label,
.apexcharts-tooltip-text-goals-value {
padding: 6px 0 5px;
}
.apexcharts-tooltip-goals-group,
.apexcharts-tooltip-text-goals-label,
.apexcharts-tooltip-text-goals-value {
display: flex;
}
.apexcharts-tooltip-text-goals-label:not(:empty),
.apexcharts-tooltip-text-goals-value:not(:empty) {
margin-top: -6px;
}
.apexcharts-tooltip-marker {
width: 12px;
height: 12px;
position: relative;
top: 0px;
margin-right: 10px;
border-radius: 50%;
}
.apexcharts-tooltip-series-group {
padding: 0 10px;
display: none;
text-align: left;
justify-content: left;
align-items: center;
}
.apexcharts-tooltip-series-group.apexcharts-active .apexcharts-tooltip-marker {
opacity: 1;
}
.apexcharts-tooltip-series-group.apexcharts-active,
.apexcharts-tooltip-series-group:last-child {
padding-bottom: 4px;
}
.apexcharts-tooltip-series-group-hidden {
opacity: 0;
height: 0;
line-height: 0;
padding: 0 !important;
}
.apexcharts-tooltip-y-group {
padding: 6px 0 5px;
}
.apexcharts-tooltip-box, .apexcharts-custom-tooltip {
padding: 4px 8px;
}
.apexcharts-tooltip-boxPlot {
display: flex;
flex-direction: column-reverse;
}
.apexcharts-tooltip-box > div {
margin: 4px 0;
}
.apexcharts-tooltip-box span.value {
font-weight: bold;
}
.apexcharts-tooltip-rangebar {
padding: 5px 8px;
}
.apexcharts-tooltip-rangebar .category {
font-weight: 600;
color: #777;
}
.apexcharts-tooltip-rangebar .series-name {
font-weight: bold;
display: block;
margin-bottom: 5px;
}
.apexcharts-xaxistooltip {
opacity: 0;
padding: 9px 10px;
pointer-events: none;
color: #373d3f;
font-size: 13px;
text-align: center;
border-radius: 2px;
position: absolute;
z-index: 10;
background: #ECEFF1;
border: 1px solid #90A4AE;
transition: 0.15s ease all;
}
.apexcharts-xaxistooltip.apexcharts-theme-dark {
background: rgba(0, 0, 0, 0.7);
border: 1px solid rgba(0, 0, 0, 0.5);
color: #fff;
}
.apexcharts-xaxistooltip:after,
.apexcharts-xaxistooltip:before {
left: 50%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.apexcharts-xaxistooltip:after {
border-color: rgba(236, 239, 241, 0);
border-width: 6px;
margin-left: -6px;
}
.apexcharts-xaxistooltip:before {
border-color: rgba(144, 164, 174, 0);
border-width: 7px;
margin-left: -7px;
}
.apexcharts-xaxistooltip-bottom:after,
.apexcharts-xaxistooltip-bottom:before {
bottom: 100%;
}
.apexcharts-xaxistooltip-top:after,
.apexcharts-xaxistooltip-top:before {
top: 100%;
}
.apexcharts-xaxistooltip-bottom:after {
border-bottom-color: #ECEFF1;
}
.apexcharts-xaxistooltip-bottom:before {
border-bottom-color: #90A4AE;
}
.apexcharts-xaxistooltip-bottom.apexcharts-theme-dark:after {
border-bottom-color: rgba(0, 0, 0, 0.5);
}
.apexcharts-xaxistooltip-bottom.apexcharts-theme-dark:before {
border-bottom-color: rgba(0, 0, 0, 0.5);
}
.apexcharts-xaxistooltip-top:after {
border-top-color: #ECEFF1;
}
.apexcharts-xaxistooltip-top:before {
border-top-color: #90A4AE;
}
.apexcharts-xaxistooltip-top.apexcharts-theme-dark:after {
border-top-color: rgba(0, 0, 0, 0.5);
}
.apexcharts-xaxistooltip-top.apexcharts-theme-dark:before {
border-top-color: rgba(0, 0, 0, 0.5);
}
.apexcharts-xaxistooltip.apexcharts-active {
opacity: 1;
transition: 0.15s ease all;
}
.apexcharts-yaxistooltip {
opacity: 0;
padding: 4px 10px;
pointer-events: none;
color: #373d3f;
font-size: 13px;
text-align: center;
border-radius: 2px;
position: absolute;
z-index: 10;
background: #ECEFF1;
border: 1px solid #90A4AE;
}
.apexcharts-yaxistooltip.apexcharts-theme-dark {
background: rgba(0, 0, 0, 0.7);
border: 1px solid rgba(0, 0, 0, 0.5);
color: #fff;
}
.apexcharts-yaxistooltip:after,
.apexcharts-yaxistooltip:before {
top: 50%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.apexcharts-yaxistooltip:after {
border-color: rgba(236, 239, 241, 0);
border-width: 6px;
margin-top: -6px;
}
.apexcharts-yaxistooltip:before {
border-color: rgba(144, 164, 174, 0);
border-width: 7px;
margin-top: -7px;
}
.apexcharts-yaxistooltip-left:after,
.apexcharts-yaxistooltip-left:before {
left: 100%;
}
.apexcharts-yaxistooltip-right:after,
.apexcharts-yaxistooltip-right:before {
right: 100%;
}
.apexcharts-yaxistooltip-left:after {
border-left-color: #ECEFF1;
}
.apexcharts-yaxistooltip-left:before {
border-left-color: #90A4AE;
}
.apexcharts-yaxistooltip-left.apexcharts-theme-dark:after {
border-left-color: rgba(0, 0, 0, 0.5);
}
.apexcharts-yaxistooltip-left.apexcharts-theme-dark:before {
border-left-color: rgba(0, 0, 0, 0.5);
}
.apexcharts-yaxistooltip-right:after {
border-right-color: #ECEFF1;
}
.apexcharts-yaxistooltip-right:before {
border-right-color: #90A4AE;
}
.apexcharts-yaxistooltip-right.apexcharts-theme-dark:after {
border-right-color: rgba(0, 0, 0, 0.5);
}
.apexcharts-yaxistooltip-right.apexcharts-theme-dark:before {
border-right-color: rgba(0, 0, 0, 0.5);
}
.apexcharts-yaxistooltip.apexcharts-active {
opacity: 1;
}
.apexcharts-yaxistooltip-hidden {
display: none;
}
.apexcharts-xcrosshairs,
.apexcharts-ycrosshairs {
pointer-events: none;
opacity: 0;
transition: 0.15s ease all;
}
.apexcharts-xcrosshairs.apexcharts-active,
.apexcharts-ycrosshairs.apexcharts-active {
opacity: 1;
transition: 0.15s ease all;
}
.apexcharts-ycrosshairs-hidden {
opacity: 0;
}
.apexcharts-selection-rect {
cursor: move;
}
.svg_select_boundingRect, .svg_select_points_rot {
pointer-events: none;
opacity: 0;
visibility: hidden;
}
.apexcharts-selection-rect + g .svg_select_boundingRect,
.apexcharts-selection-rect + g .svg_select_points_rot {
opacity: 0;
visibility: hidden;
}
.apexcharts-selection-rect + g .svg_select_points_l,
.apexcharts-selection-rect + g .svg_select_points_r {
cursor: ew-resize;
opacity: 1;
visibility: visible;
}
.svg_select_points {
fill: #efefef;
stroke: #333;
rx: 2;
}
.apexcharts-svg.apexcharts-zoomable.hovering-zoom {
cursor: crosshair;
}
.apexcharts-svg.apexcharts-zoomable.hovering-pan {
cursor: move;
}
.apexcharts-zoom-icon,
.apexcharts-zoomin-icon,
.apexcharts-zoomout-icon,
.apexcharts-reset-icon,
.apexcharts-pan-icon,
.apexcharts-selection-icon,
.apexcharts-menu-icon,
.apexcharts-toolbar-custom-icon {
cursor: pointer;
width: 20px;
height: 20px;
line-height: 24px;
color: #6E8192;
text-align: center;
}
.apexcharts-zoom-icon svg,
.apexcharts-zoomin-icon svg,
.apexcharts-zoomout-icon svg,
.apexcharts-reset-icon svg,
.apexcharts-menu-icon svg {
fill: #6E8192;
}
.apexcharts-selection-icon svg {
fill: #444;
transform: scale(0.76);
}
.apexcharts-theme-dark .apexcharts-zoom-icon svg,
.apexcharts-theme-dark .apexcharts-zoomin-icon svg,
.apexcharts-theme-dark .apexcharts-zoomout-icon svg,
.apexcharts-theme-dark .apexcharts-reset-icon svg,
.apexcharts-theme-dark .apexcharts-pan-icon svg,
.apexcharts-theme-dark .apexcharts-selection-icon svg,
.apexcharts-theme-dark .apexcharts-menu-icon svg,
.apexcharts-theme-dark .apexcharts-toolbar-custom-icon svg {
fill: #f3f4f5;
}
.apexcharts-canvas .apexcharts-zoom-icon.apexcharts-selected svg,
.apexcharts-canvas .apexcharts-selection-icon.apexcharts-selected svg,
.apexcharts-canvas .apexcharts-reset-zoom-icon.apexcharts-selected svg {
fill: #008FFB;
}
.apexcharts-theme-light .apexcharts-selection-icon:not(.apexcharts-selected):hover svg,
.apexcharts-theme-light .apexcharts-zoom-icon:not(.apexcharts-selected):hover svg,
.apexcharts-theme-light .apexcharts-zoomin-icon:hover svg,
.apexcharts-theme-light .apexcharts-zoomout-icon:hover svg,
.apexcharts-theme-light .apexcharts-reset-icon:hover svg,
.apexcharts-theme-light .apexcharts-menu-icon:hover svg {
fill: #333;
}
.apexcharts-selection-icon,
.apexcharts-menu-icon {
position: relative;
}
.apexcharts-reset-icon {
margin-left: 5px;
}
.apexcharts-zoom-icon,
.apexcharts-reset-icon,
.apexcharts-menu-icon {
transform: scale(0.85);
}
.apexcharts-zoomin-icon,
.apexcharts-zoomout-icon {
transform: scale(0.7);
}
.apexcharts-zoomout-icon {
margin-right: 3px;
}
.apexcharts-pan-icon {
transform: scale(0.62);
position: relative;
left: 1px;
top: 0px;
}
.apexcharts-pan-icon svg {
fill: #fff;
stroke: #6E8192;
stroke-width: 2;
}
.apexcharts-pan-icon.apexcharts-selected svg {
stroke: #008FFB;
}
.apexcharts-pan-icon:not(.apexcharts-selected):hover svg {
stroke: #333;
}
.apexcharts-toolbar {
position: absolute;
z-index: 11;
max-width: 176px;
text-align: right;
border-radius: 3px;
padding: 0px 6px 2px 6px;
display: flex;
justify-content: space-between;
align-items: center;
}
.apexcharts-menu {
background: #fff;
position: absolute;
top: 100%;
border: 1px solid #ddd;
border-radius: 3px;
padding: 3px;
right: 10px;
opacity: 0;
min-width: 110px;
transition: 0.15s ease all;
pointer-events: none;
}
.apexcharts-menu.apexcharts-menu-open {
opacity: 1;
pointer-events: all;
transition: 0.15s ease all;
}
.apexcharts-menu-item {
padding: 6px 7px;
font-size: 12px;
cursor: pointer;
}
.apexcharts-theme-light .apexcharts-menu-item:hover {
background: #eee;
}
.apexcharts-theme-dark .apexcharts-menu {
background: rgba(0, 0, 0, 0.7);
color: #fff;
}
@media screen and (min-width: 768px) {
.apexcharts-canvas:hover .apexcharts-toolbar {
opacity: 1;
}
}
.apexcharts-datalabel.apexcharts-element-hidden {
opacity: 0;
}
.apexcharts-pie-label,
.apexcharts-datalabels,
.apexcharts-datalabel,
.apexcharts-datalabel-label,
.apexcharts-datalabel-value {
cursor: default;
pointer-events: none;
}
.apexcharts-pie-label-delay {
opacity: 0;
animation-name: opaque;
animation-duration: 0.3s;
animation-fill-mode: forwards;
animation-timing-function: ease;
}
.apexcharts-canvas .apexcharts-element-hidden {
opacity: 0;
}
.apexcharts-hide .apexcharts-series-points {
opacity: 0;
}
.apexcharts-gridline,
.apexcharts-annotation-rect,
.apexcharts-tooltip .apexcharts-marker,
.apexcharts-area-series .apexcharts-area,
.apexcharts-line,
.apexcharts-zoom-rect,
.apexcharts-toolbar svg,
.apexcharts-area-series .apexcharts-series-markers .apexcharts-marker.no-pointer-events,
.apexcharts-line-series .apexcharts-series-markers .apexcharts-marker.no-pointer-events,
.apexcharts-radar-series path,
.apexcharts-radar-series polygon {
pointer-events: none;
}
/* markers */
.apexcharts-marker {
transition: 0.15s ease all;
}
@keyframes opaque {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
/* Resize generated styles */
@keyframes resizeanim {
from {
opacity: 0;
}
to {
opacity: 0;
}
}
.resize-triggers {
animation: 1ms resizeanim;
visibility: hidden;
opacity: 0;
}
.resize-triggers,
.resize-triggers > div,
.contract-trigger:before {
content: " ";
display: block;
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
overflow: hidden;
}
.resize-triggers > div {
background: #eee;
overflow: auto;
}
.contract-trigger:before {
width: 200%;
height: 200%;
}
.light-style .apexcharts-canvas .apexcharts-tooltip {
background: #fff;
border-color: #d9dee3;
box-shadow: 0 0.25rem 1rem rgba(161, 172, 184, 0.45);
}
.light-style .apexcharts-canvas .apexcharts-tooltip .apexcharts-tooltip-title {
background: #fff;
border-color: #d9dee3;
font-family: var(--bs-font-sans-serif) !important;
font-weight: 600;
}
.light-style .apexcharts-canvas .apexcharts-xaxistooltip,
.light-style .apexcharts-canvas .apexcharts-yaxistooltip {
background: #f5f5f9;
border-color: #d9dee3;
}
.light-style .apexcharts-canvas .apexcharts-xaxistooltip.apexcharts-xaxistooltip-bottom:after, .light-style .apexcharts-canvas .apexcharts-xaxistooltip.apexcharts-yaxistooltip-bottom:after,
.light-style .apexcharts-canvas .apexcharts-yaxistooltip.apexcharts-xaxistooltip-bottom:after,
.light-style .apexcharts-canvas .apexcharts-yaxistooltip.apexcharts-yaxistooltip-bottom:after {
border-bottom-color: #f5f5f9;
}
.light-style .apexcharts-canvas .apexcharts-xaxistooltip.apexcharts-xaxistooltip-bottom:before, .light-style .apexcharts-canvas .apexcharts-xaxistooltip.apexcharts-yaxistooltip-bottom:before,
.light-style .apexcharts-canvas .apexcharts-yaxistooltip.apexcharts-xaxistooltip-bottom:before,
.light-style .apexcharts-canvas .apexcharts-yaxistooltip.apexcharts-yaxistooltip-bottom:before {
border-bottom-color: #d9dee3;
}
.light-style .apexcharts-canvas .apexcharts-xaxistooltip.apexcharts-xaxistooltip-left:after, .light-style .apexcharts-canvas .apexcharts-xaxistooltip.apexcharts-yaxistooltip-left:after,
.light-style .apexcharts-canvas .apexcharts-yaxistooltip.apexcharts-xaxistooltip-left:after,
.light-style .apexcharts-canvas .apexcharts-yaxistooltip.apexcharts-yaxistooltip-left:after {
border-left-color: #f5f5f9;
}
.light-style .apexcharts-canvas .apexcharts-xaxistooltip.apexcharts-xaxistooltip-left:before, .light-style .apexcharts-canvas .apexcharts-xaxistooltip.apexcharts-yaxistooltip-left:before,
.light-style .apexcharts-canvas .apexcharts-yaxistooltip.apexcharts-xaxistooltip-left:before,
.light-style .apexcharts-canvas .apexcharts-yaxistooltip.apexcharts-yaxistooltip-left:before {
border-left-color: #d9dee3;
}
.light-style .apexcharts-canvas .apexcharts-xaxistooltip.apexcharts-xaxistooltip-right:after, .light-style .apexcharts-canvas .apexcharts-xaxistooltip.apexcharts-yaxistooltip-right:after,
.light-style .apexcharts-canvas .apexcharts-yaxistooltip.apexcharts-xaxistooltip-right:after,
.light-style .apexcharts-canvas .apexcharts-yaxistooltip.apexcharts-yaxistooltip-right:after {
border-right-color: #f5f5f9;
}
.light-style .apexcharts-canvas .apexcharts-xaxistooltip.apexcharts-xaxistooltip-right:before, .light-style .apexcharts-canvas .apexcharts-xaxistooltip.apexcharts-yaxistooltip-right:before,
.light-style .apexcharts-canvas .apexcharts-yaxistooltip.apexcharts-xaxistooltip-right:before,
.light-style .apexcharts-canvas .apexcharts-yaxistooltip.apexcharts-yaxistooltip-right:before {
border-right-color: #d9dee3;
}
.light-style .apexcharts-canvas .apexcharts-xaxistooltip.apexcharts-xaxistooltip-top:after, .light-style .apexcharts-canvas .apexcharts-xaxistooltip.apexcharts-yaxistooltip-top:after,
.light-style .apexcharts-canvas .apexcharts-yaxistooltip.apexcharts-xaxistooltip-top:after,
.light-style .apexcharts-canvas .apexcharts-yaxistooltip.apexcharts-yaxistooltip-top:after {
border-top-color: #f5f5f9;
}
.light-style .apexcharts-canvas .apexcharts-xaxistooltip.apexcharts-xaxistooltip-top:before, .light-style .apexcharts-canvas .apexcharts-xaxistooltip.apexcharts-yaxistooltip-top:before,
.light-style .apexcharts-canvas .apexcharts-yaxistooltip.apexcharts-xaxistooltip-top:before,
.light-style .apexcharts-canvas .apexcharts-yaxistooltip.apexcharts-yaxistooltip-top:before {
border-top-color: #d9dee3;
}
.light-style .apexcharts-canvas .apexcharts-tooltip-text {
font-family: var(--bs-font-sans-serif) !important;
filter: none;
}
.light-style .apexcharts-canvas .apexcharts-marker {
filter: drop-shadow(0 2px 4px #a1acb866);
}

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
@import '../../node_modules/highlight.js/styles/github.css';

@ -0,0 +1,95 @@
/*
Atom One Light by Daniel Gamage
Original One Light Syntax theme from https://github.com/atom/one-light-syntax
base: #fafafa
mono-1: #383a42
mono-2: #686b77
mono-3: #a0a1a7
hue-1: #0184bb
hue-2: #4078f2
hue-3: #a626a4
hue-4: #50a14f
hue-5: #e45649
hue-5-2: #c91243
hue-6: #986801
hue-6-2: #c18401
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
color: #383a42;
background: #fafafa;
}
.hljs-comment,
.hljs-quote {
color: #a0a1a7;
font-style: italic;
}
.hljs-doctag,
.hljs-keyword,
.hljs-formula {
color: #a626a4;
}
.hljs-section,
.hljs-name,
.hljs-selector-tag,
.hljs-deletion,
.hljs-subst {
color: #e45649;
}
.hljs-literal {
color: #0184bb;
}
.hljs-string,
.hljs-regexp,
.hljs-addition,
.hljs-attribute,
.hljs-meta-string {
color: #50a14f;
}
.hljs-built_in,
.hljs-class .hljs-title {
color: #c18401;
}
.hljs-attr,
.hljs-variable,
.hljs-template-variable,
.hljs-type,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-number {
color: #986801;
}
.hljs-symbol,
.hljs-bullet,
.hljs-link,
.hljs-meta,
.hljs-selector-id,
.hljs-title {
color: #4078f2;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}
.hljs-link {
text-decoration: underline;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,211 @@
/*
* Container style
*/
.ps {
overflow: hidden !important;
overflow-anchor: none;
-ms-overflow-style: none;
touch-action: auto;
-ms-touch-action: auto;
}
/*
* Scrollbar rail styles
*/
.ps__rail-x {
display: none;
opacity: 0;
transition: background-color 0.2s linear, opacity 0.2s linear;
-webkit-transition: background-color 0.2s linear, opacity 0.2s linear;
height: 15px;
/* there must be 'bottom' or 'top' for ps__rail-x */
bottom: 0px;
/* please don't change 'position' */
position: absolute;
}
.ps__rail-y {
display: none;
opacity: 0;
transition: background-color 0.2s linear, opacity 0.2s linear;
-webkit-transition: background-color 0.2s linear, opacity 0.2s linear;
width: 15px;
/* there must be 'right' or 'left' for ps__rail-y */
right: 0;
/* please don't change 'position' */
position: absolute;
}
.ps--active-x > .ps__rail-x,
.ps--active-y > .ps__rail-y {
display: block;
background-color: transparent;
}
.ps:hover > .ps__rail-x,
.ps:hover > .ps__rail-y,
.ps--focus > .ps__rail-x,
.ps--focus > .ps__rail-y,
.ps--scrolling-x > .ps__rail-x,
.ps--scrolling-y > .ps__rail-y {
opacity: 0.6;
}
.ps .ps__rail-x:hover,
.ps .ps__rail-y:hover,
.ps .ps__rail-x:focus,
.ps .ps__rail-y:focus,
.ps .ps__rail-x.ps--clicking,
.ps .ps__rail-y.ps--clicking {
background-color: #eee;
opacity: 0.9;
}
/*
* Scrollbar thumb styles
*/
.ps__thumb-x {
background-color: #aaa;
border-radius: 6px;
transition: background-color 0.2s linear, height 0.2s ease-in-out;
-webkit-transition: background-color 0.2s linear, height 0.2s ease-in-out;
height: 6px;
/* there must be 'bottom' for ps__thumb-x */
bottom: 2px;
/* please don't change 'position' */
position: absolute;
}
.ps__thumb-y {
background-color: #aaa;
border-radius: 6px;
transition: background-color 0.2s linear, width 0.2s ease-in-out;
-webkit-transition: background-color 0.2s linear, width 0.2s ease-in-out;
width: 6px;
/* there must be 'right' for ps__thumb-y */
right: 2px;
/* please don't change 'position' */
position: absolute;
}
.ps__rail-x:hover > .ps__thumb-x,
.ps__rail-x:focus > .ps__thumb-x,
.ps__rail-x.ps--clicking .ps__thumb-x {
background-color: #999;
height: 11px;
}
.ps__rail-y:hover > .ps__thumb-y,
.ps__rail-y:focus > .ps__thumb-y,
.ps__rail-y.ps--clicking .ps__thumb-y {
background-color: #999;
width: 11px;
}
/* MS supports */
@supports (-ms-overflow-style: none) {
.ps {
overflow: auto !important;
}
}
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
.ps {
overflow: auto !important;
}
}
.ps {
position: relative;
}
.ps__rail-x {
height: 0.25rem;
}
.ps__rail-y {
width: 0.25rem;
}
.ps__rail-x,
.ps__rail-y,
.ps__thumb-x,
.ps__thumb-y {
border-radius: 10rem;
}
.ps__rail-x:hover,
.ps__rail-x:focus,
.ps__rail-x.ps--clicking,
.ps__rail-x:hover > .ps__thumb-x,
.ps__rail-x:focus > .ps__thumb-x,
.ps__rail-x.ps--clicking > .ps__thumb-x {
height: 0.375rem;
}
.ps__rail-y:hover,
.ps__rail-y:focus,
.ps__rail-y.ps--clicking,
.ps__rail-y:hover > .ps__thumb-y,
.ps__rail-y:focus > .ps__thumb-y,
.ps__rail-y.ps--clicking > .ps__thumb-y {
width: 0.375rem;
}
.ps__thumb-x {
height: 0.25rem;
bottom: 0;
}
.ps__thumb-y {
width: 0.25rem;
right: 0;
}
.light-style .ps__thumb-x,
.light-style .ps__thumb-y {
background-color: rgba(67, 89, 113, 0.4);
}
.light-style .ps__rail-x:hover,
.light-style .ps__rail-y:hover,
.light-style .ps__rail-x:focus,
.light-style .ps__rail-y:focus,
.light-style .ps__rail-x.ps--clicking,
.light-style .ps__rail-y.ps--clicking {
background-color: rgba(67, 89, 113, 0.2);
}
.light-style .ps__rail-x:hover > .ps__thumb-x,
.light-style .ps__rail-y:hover > .ps__thumb-y,
.light-style .ps__rail-x:focus > .ps__thumb-x,
.light-style .ps__rail-y:focus > .ps__thumb-y,
.light-style .ps__rail-x.ps--clicking > .ps__thumb-x,
.light-style .ps__rail-y.ps--clicking > .ps__thumb-y {
background-color: rgba(67, 89, 113, 0.7);
}
.light-style .ps-inverted .ps__rail-x:hover,
.light-style .ps-inverted .ps__rail-y:hover,
.light-style .ps-inverted .ps__rail-x:focus,
.light-style .ps-inverted .ps__rail-y:focus,
.light-style .ps-inverted .ps__rail-x.ps--clicking,
.light-style .ps-inverted .ps__rail-y.ps--clicking {
background-color: rgba(255, 255, 255, 0.5);
}
.light-style .ps-inverted .ps__thumb-x,
.light-style .ps-inverted .ps__thumb-y {
background-color: rgba(255, 255, 255, 0.7);
}
.light-style .ps-inverted .ps__rail-x:hover > .ps__thumb-x,
.light-style .ps-inverted .ps__rail-y:hover > .ps__thumb-y,
.light-style .ps-inverted .ps__rail-x:focus > .ps__thumb-x,
.light-style .ps-inverted .ps__rail-y:focus > .ps__thumb-y,
.light-style .ps-inverted .ps__rail-x.ps--clicking > .ps__thumb-x,
.light-style .ps-inverted .ps__rail-y.ps--clicking > .ps__thumb-y {
background-color: #fff;
}
@supports (-moz-appearance: none) {
#both-scrollbars-example {
max-width: 1080px;
margin: 0 auto;
padding-left: 0;
padding-right: 0;
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,74 @@
{
"name": "end2end",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "end2end",
"version": "1.0.0",
"license": "ISC",
"devDependencies": {
"@playwright/test": "^1.28.0"
}
},
"node_modules/@playwright/test": {
"version": "1.28.0",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.28.0.tgz",
"integrity": "sha512-vrHs5DFTPwYox5SGKq/7TDn/S4q6RA1zArd7uhO6EyP9hj3XgZBBM12ktMbnDQNxh/fL1IUKsTNLxihmsU38lQ==",
"dev": true,
"dependencies": {
"@types/node": "*",
"playwright-core": "1.28.0"
},
"bin": {
"playwright": "cli.js"
},
"engines": {
"node": ">=14"
}
},
"node_modules/@types/node": {
"version": "18.11.9",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz",
"integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==",
"dev": true
},
"node_modules/playwright-core": {
"version": "1.28.0",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.28.0.tgz",
"integrity": "sha512-nJLknd28kPBiCNTbqpu6Wmkrh63OEqJSFw9xOfL9qxfNwody7h6/L3O2dZoWQ6Oxcm0VOHjWmGiCUGkc0X3VZA==",
"dev": true,
"bin": {
"playwright": "cli.js"
},
"engines": {
"node": ">=14"
}
}
},
"dependencies": {
"@playwright/test": {
"version": "1.28.0",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.28.0.tgz",
"integrity": "sha512-vrHs5DFTPwYox5SGKq/7TDn/S4q6RA1zArd7uhO6EyP9hj3XgZBBM12ktMbnDQNxh/fL1IUKsTNLxihmsU38lQ==",
"dev": true,
"requires": {
"@types/node": "*",
"playwright-core": "1.28.0"
}
},
"@types/node": {
"version": "18.11.9",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz",
"integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==",
"dev": true
},
"playwright-core": {
"version": "1.28.0",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.28.0.tgz",
"integrity": "sha512-nJLknd28kPBiCNTbqpu6Wmkrh63OEqJSFw9xOfL9qxfNwody7h6/L3O2dZoWQ6Oxcm0VOHjWmGiCUGkc0X3VZA==",
"dev": true
}
}
}

@ -0,0 +1,13 @@
{
"name": "end2end",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@playwright/test": "^1.28.0"
}
}

@ -0,0 +1,107 @@
import type { PlaywrightTestConfig } from "@playwright/test";
import { devices } from "@playwright/test";
/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
// require('dotenv').config();
/**
* See https://playwright.dev/docs/test-configuration.
*/
const config: PlaywrightTestConfig = {
testDir: "./tests",
/* Maximum time one test can run for. */
timeout: 30 * 1000,
expect: {
/**
* Maximum time expect() should wait for the condition to be met.
* For example in `await expect(locator).toHaveText();`
*/
timeout: 5000,
},
/* Run tests in files in parallel */
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: "html",
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
actionTimeout: 0,
/* Base URL to use in actions like `await page.goto('/')`. */
// baseURL: 'http://localhost:3000',
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: "on-first-retry",
},
/* Configure projects for major browsers */
projects: [
{
name: "chromium",
use: {
...devices["Desktop Chrome"],
},
},
{
name: "firefox",
use: {
...devices["Desktop Firefox"],
},
},
{
name: "webkit",
use: {
...devices["Desktop Safari"],
},
},
/* Test against mobile viewports. */
// {
// name: 'Mobile Chrome',
// use: {
// ...devices['Pixel 5'],
// },
// },
// {
// name: 'Mobile Safari',
// use: {
// ...devices['iPhone 12'],
// },
// },
/* Test against branded browsers. */
// {
// name: 'Microsoft Edge',
// use: {
// channel: 'msedge',
// },
// },
// {
// name: 'Google Chrome',
// use: {
// channel: 'chrome',
// },
// },
],
/* Folder for test artifacts such as screenshots, videos, traces, etc. */
// outputDir: 'test-results/',
/* Run your local dev server before starting the tests */
// webServer: {
// command: 'npm run start',
// port: 3000,
// },
};
export default config;

@ -0,0 +1,9 @@
import { test, expect } from "@playwright/test";
test("homepage has title and links to intro page", async ({ page }) => {
await page.goto("http://localhost:3000/");
await expect(page).toHaveTitle("Welcome to Leptos");
await expect(page.locator("h1")).toHaveText("Welcome to Leptos!");
});

@ -0,0 +1,3 @@
[toolchain]
channel = "stable"

@ -0,0 +1,228 @@
use leptos::*;
use leptos_meta::*;
use leptos_router::*;
use crate::home_page::HomePage;
use crate::locales::trl;
#[component]
pub fn App(cx: Scope) -> impl IntoView {
// Provides context that manages stylesheets, titles, meta tags, etc.
provide_meta_context(cx);
//provide_context(cx, DialogOpener::new(cx));
view! {
cx,
<Html
lang="cz"
dir="ltr"
attributes=AdditionalAttributes::from(vec![
("data-theme", "theme-default"),
("class", "light-style layout-menu-fixed"),
("data-template", "vertical-menu-template-free"),
("data-assets-path", "/")])
/>
<Meta charset="utf-8"/>
<Meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"/>
//<!-- Fonts -->
<Link rel="preconnect" href="https://fonts.googleapis.com" />
<Link rel="preconnect" href="https://fonts.gstatic.com" />
<Link
href="https://fonts.googleapis.com/css2?family=Public+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600;1,700&display=swap"
rel="stylesheet"
/>
//<!-- Icons. Uncomment required icon fonts -->
<Link rel="stylesheet" href="/vendor/fonts/boxicons.css" />
//<!-- Core CSS -->
<Link rel="stylesheet" href="/vendor/css/core.css" />
<Link rel="stylesheet" href="/vendor/css/theme-default.css" />
<Link rel="stylesheet" href="/css/demo.css" />
//<!-- Vendors CSS -->
<Link rel="stylesheet" href="/vendor/libs/perfect-scrollbar/perfect-scrollbar.css" />
<Body class="testik"/>
<div class="layout-wrapper layout-content-navbar">
<div class="layout-container">
//<!-- Menu -->
<aside id="layout-menu" class="layout-menu menu-vertical menu bg-menu-theme">
<div class="app-brand demo">
<a href="javascript:void(0);" class="layout-menu-toggle menu-link text-large ms-auto d-block d-xl-none">
<i class="bx bx-chevron-left bx-sm align-middle"></i>
</a>
</div>
<div class="menu-inner-shadow"></div>
<ul class="menu-inner py-1">
//<!-- Dashboard -->
<li class="menu-item">
<a href="/" class="menu-link">
<i class="menu-icon tf-icons bx bx-home-circle"></i>
<div data-i18n="Analytics">{trl(cx, "Dashboard")}</div>
</a>
</li>
<li class="menu-item">
<a href="/" class="menu-link">
<i class="menu-icon tf-icons bx bx-time"></i>
<div data-i18n="Analytics">"Opening hours"</div>
</a>
</li>
<li class="menu-item">
<a href="/" class="menu-link">
<i class="menu-icon tf-icons bx bx-layer"></i>
<div data-i18n="Analytics">"Places"</div>
</a>
</li>
<li class="menu-item">
<a href="/" class="menu-link">
<i class="menu-icon tf-icons bx bx-info-circle"></i>
<div data-i18n="Analytics">"About"</div>
</a>
</li>
</ul>
</aside>
//<!-- Layout container -->
<div class="layout-page">
//<!-- Navbar -->
<nav
class="layout-navbar container-xxl navbar navbar-expand-xl navbar-detached align-items-center bg-navbar-theme"
id="layout-navbar">
<div class="layout-menu-toggle navbar-nav align-items-xl-center me-3 me-xl-0 d-xl-none">
<a class="nav-item nav-link px-0 me-xl-4" href="javascript:void(0)">
<i class="bx bx-menu bx-sm"></i>
</a>
</div>
<div class="navbar-nav-right d-flex align-items-center" id="navbar-collapse">
//<!-- Search -->
<div class="navbar-nav align-items-center">
<div class="nav-item d-flex align-items-center">
<i class="bx bx-search fs-4 lh-0"></i>
<input
type="text"
class="form-control border-0 shadow-none"
placeholder={trl(cx, "Search...")}
aria-label={trl(cx, "Search...")}
/>
</div>
</div>
//<!-- /Search -->
<ul class="navbar-nav flex-row align-items-center ms-auto">
<li class="nav-item navbar-dropdown dropdown-user dropdown">
<a class="nav-link dropdown-toggle hide-arrow" href="#" data-bs-toggle="dropdown">
<i class="bx bx-cog fs-3 lh-0"></i>
</a>
</li>
//<!-- User -->
<li class="nav-item navbar-dropdown dropdown-user dropdown">
<a class="nav-link dropdown-toggle hide-arrow" href="#" data-bs-toggle="dropdown">
//<div class="avatar avatar-online">
// <img src="/img/avatars/1.png" alt class="w-px-40 h-auto rounded-circle" />
//</div>
<i class="bx bx-user fs-3 lh-0"></i>
</a>
<ul class="dropdown-menu dropdown-menu-end">
<li>
<a class="dropdown-item" href="#">
<div class="d-flex">
<div class="flex-shrink-0 me-3">
<div class="avatar avatar-online">
<img src="/img/avatars/1.png" alt class="w-px-40 h-auto rounded-circle" />
</div>
</div>
<div class="flex-grow-1">
<span class="fw-semibold d-block">"John Doe"</span>
<small class="text-muted">"Admin"</small>
</div>
</div>
</a>
</li>
<li>
<div class="dropdown-divider"></div>
</li>
<li>
<a class="dropdown-item" href="#">
<i class="bx bx-user me-2"></i>
<span class="align-middle">"My Profile"</span>
</a>
</li>
<li>
<a class="dropdown-item" href="#">
<i class="bx bx-cog me-2"></i>
<span class="align-middle">"Settings"</span>
</a>
</li>
<li>
<div class="dropdown-divider"></div>
</li>
<li>
<a class="dropdown-item" href="auth-login-basic.html">
<i class="bx bx-power-off me-2"></i>
<span class="align-middle">"Log Out"</span>
</a>
</li>
</ul>
</li>
//<!--/ User -->
</ul>
</div>
</nav>
//<!-- Content wrapper -->
<div class="content-wrapper">
//<!-- Content -->
<div class="container-xxl flex-grow-1 container-p-y">
<Router>
<main>
<Routes>
<Route path="" view=|cx| view! { cx, <HomePage/> }/>
</Routes>
</main>
</Router>
</div>
</div>
</div>
</div>
</div>
/*<Html lang="cz"/>
// injects a stylesheet into the document <head>
// id=leptos means cargo-leptos will hot-reload this stylesheet
<Stylesheet id="leptos" href="/pkg/leptos_start.css"/>
<Stylesheet href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"/>
// sets the document title
<Title text="Welcome to Leptos"/>
<div class="topbar">
<img src="/logo.png" width=40 height=40/><h1>"Rezervator admin"</h1>
</div>
<div class="main">
<div class="sidebar">
<p></p>
<a class="active" href="#home">"Dashboard"</a>
<a href="#news">"Opening hours"</a>
<a href="#contact">"Places"</a>
<a href="#about">"About"</a>
</div>
// content for this welcome page
<div class="content">
<Router>
<main>
<Routes>
<Route path="" view=|cx| view! { cx, <HomePage/> }/>
</Routes>
</main>
</Router>
</div>
</div>*/
}
}

@ -0,0 +1,80 @@
use leptos::*;
use crate::modal_box::{DialogOpener, ModalDialog, ModalBody, ModalFooter};
use crate::server_fn::*;
use crate::locales::trl;
/// Renders the home page of your application.
#[component]
pub fn HomePage(cx: Scope) -> impl IntoView {
// Creates a reactive value to update the button
let (count, set_count) = create_signal(cx, 0);
let on_click = move |_| set_count.update(|count| *count += 1);
let dialog = DialogOpener::new(cx);
//let (dialog, set_dialog) = create_signal(cx, false);
//let on_dialog = move |_| dialog.set_visible.update(|dialog| {*dialog = true});
//let pok = use_context::<Request>(cx);
//log!("{:?}", pok);
view! { cx,
<ModalDialog opener={dialog} title="Titulek".to_string()>
<ModalBody>
<div class="row">
<div class="col mb-3">
<label for="nameWithTitle" class="form-label">"Name"</label>
<input
type="text"
id="nameWithTitle"
class="form-control"
placeholder="Enter Name"
/>
</div>
</div>
<div class="row g-2">
<div class="col mb-0">
<label for="emailWithTitle" class="form-label">"Email"</label>
<input
type="text"
id="emailWithTitle"
class="form-control"
placeholder="xxxx@xxx.xx"
/>
</div>
<div class="col mb-0">
<label for="dobWithTitle" class="form-label">"DOB"</label>
<input
type="text"
id="dobWithTitle"
class="form-control"
placeholder="DD / MM / YY"
/>
</div>
</div>
</ModalBody>
<ModalFooter>
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal" on:click=move |_| dialog.hide()>
"Close"
</button>
<button type="button" class="btn btn-primary">"Save changes"</button>
</ModalFooter>
</ModalDialog>
<h1>"Welcome to Leptos!"</h1>
<button on:click=on_click>"Click Me: " {count}</button>
<button on:click=move |_| dialog.show()>"Dialog"</button>
<button on:click=move |_| {
spawn_local(async move {
set_session(cx).await;
});
}>"Session"</button>
<button on:click=move |_| {
spawn_local(async move {
get_session(cx).await;
});
}>"Session get"</button>
<p>{trl(cx, "testik!")}</p>
}
}

@ -0,0 +1,26 @@
pub mod app;
pub mod modal_box;
pub mod home_page;
pub mod server_fn;
pub mod locales;
use cfg_if::cfg_if;
cfg_if! {
if #[cfg(feature = "hydrate")] {
use wasm_bindgen::prelude::wasm_bindgen;
#[wasm_bindgen]
pub fn hydrate() {
use app::*;
use leptos::*;
console_error_panic_hook::set_once();
leptos::mount_to_body(move |cx| {
view! { cx, <App/> }
});
}
}
}

@ -0,0 +1,52 @@
use std::collections::HashMap;
use lazy_static::lazy_static;
use leptos::*;
lazy_static! {
static ref LANGUAGES: HashMap<&'static str, HashMap<&'static str, &'static str>> = {
let m = HashMap::from([
("cs", HashMap::from( [
("Dashboard", "Přehled"),
("Settings", "Nastavení"),
("Search...", "Najít...")
])),
("sk", HashMap::from( [
("Dashboard", "Prehlad"),
("Settings", "Nastavenie"),
("Search...", "Najsť...")
]))
]);
m
};
}
fn get_locales(cx: Scope) -> Vec<Option<String>> {
let (loc, set_loc) = create_signal(cx, Vec::new());
create_effect(cx, move |_| {
let js_locales = window().navigator().languages();
set_loc.update(|l| *l = js_locales.into_iter().map(|val| val.as_string()).collect::<Vec<_>>());
});
loc.get_untracked()
}
pub fn get_dictionary(cx: Scope) -> Option<&'static HashMap<&'static str, &'static str>> {
let locs = get_locales(cx);
for loc in locs {
if let Some(key) = loc {
if let Some(k) = key.split("-").collect::<Vec<_>>().get(0) {
if *k == "en" {
return None;
}
if !LANGUAGES.contains_key(*k) {
continue;
}
return LANGUAGES.get(*k);
}
}
}
None
}

@ -0,0 +1,15 @@
use leptos::*;
use crate::locales::catalogues::get_dictionary;
mod catalogues;
pub fn trl(cx: Scope, phrase: &'static str) -> impl Fn() -> &'static str {
let mut translated = phrase;
if let Some(dict) = get_dictionary(cx) {
if let Some(p) = dict.get(phrase) {
translated = *p;
}
}
|| { translated }
}

@ -0,0 +1,70 @@
#[cfg(feature = "ssr")]
#[actix_web::main]
async fn main() -> std::io::Result<()> {
use actix_files::Files;
use actix_web::*;
use leptos::*;
use leptos_actix::{generate_route_list, LeptosRoutes};
use rezervator::app::*;
//use rezervator::server_fn::*;
use actix_session::storage::CookieSessionStore;
use actix_session::SessionMiddleware;
use actix_web::cookie::Key;
let conf = get_configuration(None).await.unwrap();
let addr = conf.leptos_options.site_addr;
// Generate the list of routes in your Leptos App
let routes = generate_route_list(|cx| view! { cx, <App/> });
let key = Key::generate();
//SetSession::register();
//GetSession::register();
HttpServer::new(move || {
let leptos_options = &conf.leptos_options;
let site_root = &leptos_options.site_root;
App::new()
.wrap(SessionMiddleware::new(
CookieSessionStore::default(),
key.clone()
))
.route("/api/{tail:.*}", leptos_actix::handle_server_fns())
.leptos_routes(
leptos_options.to_owned(),
routes.to_owned(),
|cx| view! { cx, <App/> },
)
.service(Files::new("/", site_root))
//.wrap(middleware::Compress::default())
})
.bind(&addr)?
.run()
.await
}
#[cfg(not(any(feature = "ssr", feature = "csr")))]
pub fn main() {
// no client-side main function
// unless we want this to work with e.g., Trunk for pure client-side testing
// see lib.rs for hydration function instead
// see optional feature `ssg` instead
}
#[cfg(all(not(feature = "ssr"), feature = "csr"))]
pub fn main() {
// a client-side main function is required for using `trunk serve`
// prefer using `cargo leptos serve` instead
// to run: `trunk serve --open --features ssg`
use leptos::*;
use leptos_start::app::*;
use wasm_bindgen::prelude::wasm_bindgen;
console_error_panic_hook::set_once();
leptos::mount_to_body(move |cx| {
// note: for testing it may be preferrable to replace this with a
// more specific component, although leptos_router should still work
view! {cx, <App/> }
});
}

@ -0,0 +1,78 @@
use std::rc::Rc;
use leptos::*;
#[derive(Copy, Clone)]
pub struct DialogOpener {
visible: ReadSignal<bool>,
set_visible: WriteSignal<bool>,
}
impl DialogOpener {
pub fn new(cx: Scope) -> Self {
let (visible, set_visible) = create_signal(cx, false);
DialogOpener {
visible,
set_visible,
}
}
pub fn visible(&self) -> bool {
self.visible.get()
}
pub fn show(&self) {
self.set_visible.update(|state| { *state = true});
}
pub fn hide(&self) {
self.set_visible.update(|state| { *state = false});
}
}
#[component]
pub fn ModalDialog(
cx: Scope,
opener: DialogOpener,
title: String,
children: Children,
) -> impl IntoView {
view! {cx,
<div class={ move || if opener.visible() {"modal fade show"} else {"modal fade"}}
style={ move || if opener.visible() {"display: block;"} else {""}}
id="modalCenter" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalCenterTitle">{title}</h5>
<button
type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
on:click=move |_| opener.hide()/>
</div>
{children(cx)}
</div>
</div>
</div>
}
}
#[component]
pub fn ModalBody(cx: Scope, children: Children) -> impl IntoView {
view! {cx,
<div class="modal-body">
{children(cx)}
</div>
}
}
#[component]
pub fn ModalFooter(cx: Scope, children: Children) -> impl IntoView {
view! {cx,
<div class="modal-footer">
{children(cx)}
</div>
}
}

@ -0,0 +1,29 @@
use leptos::*;
#[server(SetSession, "/api", "Url", "set_session")]
pub async fn set_session(cx: Scope) -> Result<(), ServerFnError> {
use leptos_actix::extract;
use actix_session::*;
extract(cx, |session: Session| async move {
leptos::log!("extract");
let pok = session.insert("user", "uzivatel");
log!("{pok:?}");
}).await
//Ok(())
}
#[server(GetSession, "/api")]
pub async fn get_session(cx: Scope) -> Result<(), ServerFnError> {
use leptos_actix::extract;
use actix_session::*;
extract(cx, |session: Session| async move {
leptos::log!("extract");
let pok = session.get::<String>("user");
log!("{pok:?}");
}).await
//Ok(())
}

@ -0,0 +1,118 @@
body {
font-family: sans-serif;
/*text-align: center;*/
}
/* The side navigation menu */
.sidebar {
margin: 0;
padding: 0;
width: 200px;
background-color: #fdc476;
position: fixed;
height: 100%;
overflow: auto;
}
/* Sidebar links */
.sidebar a {
display: block;
color: black;
padding: 16px;
text-decoration: none;
}
/* Active/current link */
.sidebar a.active {
background-color: #04AA6D;
color: white;
}
/* Links on mouse-over */
.sidebar a:hover:not(.active) {
background-color: #555;
color: white;
}
/* Page content. The value of the margin-left property should match the value of the sidebar's width property */
div.content {
margin-left: 200px;
padding: 1px 16px;
/*height: 1000px;*/
}
/* On screens that are less than 700px wide, make the sidebar into a topbar */
@media screen and (max-width: 700px) {
.sidebar {
width: 100%;
height: auto;
position: relative;
}
.sidebar a {float: left;}
div.content {margin-left: 0;}
}
/* On screens that are less than 400px, display the bar vertically, instead of horizontally */
@media screen and (max-width: 400px) {
.sidebar a {
text-align: center;
float: none;
}
}
.topbar {
overflow: hidden;
background-color: #fdc476;
position: fixed; /* Set the navbar to fixed position */
top: 0; /* Position the navbar at the top of the page */
width: 100%; /* Full width */
text-align: center;
}
.main {
margin-top: 60px; /* Add a top margin to avoid content overlay */
}
/* modal */
.modal {
display: block;
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
padding-top: 100px; /* Location of the box */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}
.modal-hidden {
display: none; /* Hidden by default */
}
/* Modal Content */
.modal-content {
background-color: #fefefe;
margin: auto;
padding: 20px;
border: 1px solid #888;
width: 70%;
}
/* The Close Button */
.close {
color: #aaaaaa;
float: right;
font-size: 25px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}
Loading…
Cancel
Save