mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-09-30 15:23:12 +00:00
Replace all hardcoded credentials with configuration-injected values:
- SQL Server connection strings -> ${CONNECTION_STRING} env-var placeholders (4 appsettings files)
- SendGrid API keys -> ${SENDGRID_API_KEY} (incl. commented copies in SendMessage.cs)
- JWT signing secret -> ${JWT_SECRET} (3 appsettings files)
- AWS access key pair in UploadFileHp.cs -> DI-injected IAmazonS3 (SDK default credential chain)
- Google Maps API keys in App.razor / Home.razor -> IConfiguration lookup
- Legacy SMTP credentials in SendMessage.cs comments -> placeholders
Add .env.example documenting required environment variables and a
Configuration & Secrets section in BACKEND_ARCHITECTURE.md.
All exposed credentials were rotated 2026-06-05 prior to this scrub.
Source: github-audit-report.md Criticals 1-2 (Agent A4).
Verified: dotnet build 0 errors; secret-pattern grep clean.
847 lines
35 KiB
Text
847 lines
35 KiB
Text
@inject IConfiguration Configuration
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<base href="/" />
|
|
<link rel="apple-touch-icon" sizes="76x76" href="/assets/img/Fav Icon.svg">
|
|
<title>Sea Haven Industries</title>
|
|
<link rel="icon" type="image/png" href="/assets/img/Fav Icon.svg">
|
|
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700,900|Roboto+Slab:400,700" />
|
|
<!-- Nucleo Icons -->
|
|
<link href="/assets/css/nucleo-icons.css" rel="stylesheet" />
|
|
<link href="/assets/css/nucleo-svg.css" rel="stylesheet" />
|
|
|
|
<!-- Font Awesome Icons -->
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css" integrity="sha512-Kc323vGBEqzTmouAECnVceyQqyqdsSiqLQISBL29aUW4U/M7pSPA/gEUZQqv1cwx4OnYxTxve5UMg5GT6L4JJg==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
|
<!-- Material Icons -->
|
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons+Round" rel="stylesheet">
|
|
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=@Configuration["GoogleMaps:ApiKey"]&v=3&libraries=places"></script>
|
|
|
|
<link rel="stylesheet" href="_content/Radzen.Blazor/css/default-base.css">
|
|
<!-- JS File -->
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
|
<link rel="stylesheet" href="/css/site.css" />
|
|
<!-- CSS Files -->
|
|
@* <link href="/assets/css/custom.css" rel="stylesheet" /> *@
|
|
<link id="pagestyle" href="/assets/css/material-dashboard.css?v=3.0.5" rel="stylesheet" />
|
|
|
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@48,400,0,0" />
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
|
<HeadOutlet @rendermode="RenderModeForPage" />
|
|
|
|
</head>
|
|
|
|
<body id="body" class="g-sidenav-show g-sidenav-pinned">
|
|
<Routes @rendermode="RenderModeForPage" />
|
|
<script src="/assets/js/core/popper.min.js"></script>
|
|
<script src="/assets/js/core/bootstrap.min.js"></script>
|
|
<script src="/assets/js/plugins/perfect-scrollbar.min.js"></script>
|
|
<script src="/assets/js/plugins/smooth-scrollbar.min.js"></script>
|
|
<script src="/assets/js/plugins/datatables.js"></script>
|
|
<script src="/assets/js/plugins/chartjs.min.js"></script>
|
|
<script src="/assets/js/plugins/sweetalert.min.js"></script>
|
|
<!-- Kanban scripts -->
|
|
<script src="/assets/js/plugins/dragula/dragula.min.js"></script>
|
|
<script src="/assets/js/plugins/jkanban/jkanban.js"></script>
|
|
<script src="https://unpkg.com/signature_pad"></script>
|
|
|
|
|
|
<script>
|
|
function setValue(value, active) {
|
|
console.log("setValue called with:", value, active);
|
|
|
|
document.querySelectorAll("round-slider").forEach(function (el) {
|
|
if (el.value === undefined) return;
|
|
el.value = value;
|
|
});
|
|
const span = document.querySelector("#value");
|
|
span.innerHTML = value;
|
|
if (active)
|
|
span.style.color = 'red';
|
|
else
|
|
span.style.color = 'black';
|
|
}
|
|
//Home page charts
|
|
|
|
function CircleGraph(val, per) {
|
|
if (document.getElementById("chart-circle")) {
|
|
var ctx12 = document.getElementById("chart-circle").getContext("2d");
|
|
|
|
// Use a solid color instead of gradient
|
|
var backgroundColor = '#FFAB00';
|
|
|
|
new Chart(ctx12, {
|
|
type: "doughnut",
|
|
data: {
|
|
labels: ['On Hold'], // Only one label
|
|
datasets: [{
|
|
label: "Consumption",
|
|
weight: 9,
|
|
cutout: per + '%', // Adjust to control the size of the inner circle
|
|
borderWidth: 2, // Thicker outer line/border
|
|
backgroundColor: [backgroundColor], // Use solid color for the doughnut
|
|
borderColor: ['#325D7F'], // Outer border (can match the image background color)
|
|
data: [val], // Only one value representing 100%
|
|
fill: false
|
|
}],
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
plugins: {
|
|
legend: {
|
|
display: false, // Hide legend
|
|
},
|
|
tooltip: {
|
|
enabled: false, // Disable tooltip
|
|
},
|
|
},
|
|
interaction: {
|
|
intersect: false,
|
|
mode: 'index',
|
|
},
|
|
cutoutPercentage: 0, // Adjust the percentage to match the desired hollow area
|
|
scales: {
|
|
y: {
|
|
display: false, // Hide y-axis
|
|
},
|
|
x: {
|
|
display: false, // Hide x-axis
|
|
},
|
|
},
|
|
},
|
|
});
|
|
}
|
|
}
|
|
function CircleGraph2(val, per) {
|
|
if (document.getElementById("chart-circle2")) {
|
|
var ctx12 = document.getElementById("chart-circle2").getContext("2d");
|
|
|
|
// Use a solid color instead of gradient
|
|
var backgroundColor = '#FFAB00';
|
|
|
|
new Chart(ctx12, {
|
|
type: "doughnut",
|
|
data: {
|
|
labels: ['On Hold'], // Only one label
|
|
datasets: [{
|
|
label: "Consumption",
|
|
weight: 9,
|
|
cutout: 100 + '%', // Adjust to control the size of the inner circle
|
|
borderWidth: 5, // Thicker outer line/border
|
|
backgroundColor: [backgroundColor], // Use solid color for the doughnut
|
|
borderColor: ['#325D7F'], // Outer border (can match the image background color)
|
|
data: [per], // Only one value representing 100%
|
|
fill: false
|
|
}],
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
plugins: {
|
|
legend: {
|
|
display: false, // Hide legend
|
|
},
|
|
tooltip: {
|
|
enabled: false, // Disable tooltip
|
|
},
|
|
},
|
|
interaction: {
|
|
intersect: false,
|
|
mode: 'index',
|
|
},
|
|
cutoutPercentage: 55, // Adjust the percentage to match the desired hollow area
|
|
scales: {
|
|
y: {
|
|
display: false, // Hide y-axis
|
|
},
|
|
x: {
|
|
display: false, // Hide x-axis
|
|
},
|
|
},
|
|
},
|
|
});
|
|
}
|
|
}
|
|
function CircleGraph3(val, per) {
|
|
if (document.getElementById("chart-circle3")) {
|
|
var ctx12 = document.getElementById("chart-circle3").getContext("2d");
|
|
|
|
// Use a solid color instead of gradient
|
|
var backgroundColor = '#FFAB00';
|
|
|
|
new Chart(ctx12, {
|
|
type: "doughnut",
|
|
data: {
|
|
labels: ['On Hold'], // Only one label
|
|
datasets: [{
|
|
label: "Consumption",
|
|
weight: 9,
|
|
cutout: per + '%', // Adjust to control the size of the inner circle
|
|
borderWidth: 2, // Thicker outer line/border
|
|
backgroundColor: [backgroundColor], // Use solid color for the doughnut
|
|
borderColor: ['#325D7F'], // Outer border (can match the image background color)
|
|
data: [val], // Only one value representing 100%
|
|
fill: false
|
|
}],
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
plugins: {
|
|
legend: {
|
|
display: false, // Hide legend
|
|
},
|
|
tooltip: {
|
|
enabled: false, // Disable tooltip
|
|
},
|
|
},
|
|
interaction: {
|
|
intersect: false,
|
|
mode: 'index',
|
|
},
|
|
cutoutPercentage: 55, // Adjust the percentage to match the desired hollow area
|
|
scales: {
|
|
y: {
|
|
display: false, // Hide y-axis
|
|
},
|
|
x: {
|
|
display: false, // Hide x-axis
|
|
},
|
|
},
|
|
},
|
|
});
|
|
}
|
|
}
|
|
function CircleGraph4(val, per) {
|
|
if (document.getElementById("chart-circle4")) {
|
|
var ctx12 = document.getElementById("chart-circle4").getContext("2d");
|
|
|
|
// Use a solid color instead of gradient
|
|
var backgroundColor = '#FFAB00';
|
|
|
|
new Chart(ctx12, {
|
|
type: "doughnut",
|
|
data: {
|
|
labels: ['On Hold'], // Only one label
|
|
datasets: [{
|
|
label: "Consumption",
|
|
weight: 9,
|
|
cutout: per + '%', // Adjust to control the size of the inner circle
|
|
borderWidth: 2, // Thicker outer line/border
|
|
backgroundColor: [backgroundColor], // Use solid color for the doughnut
|
|
borderColor: ['#325D7F'], // Outer border (can match the image background color)
|
|
data: [val], // Only one value representing 100%
|
|
fill: false
|
|
}],
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
plugins: {
|
|
legend: {
|
|
display: false, // Hide legend
|
|
},
|
|
tooltip: {
|
|
enabled: false, // Disable tooltip
|
|
},
|
|
},
|
|
interaction: {
|
|
intersect: false,
|
|
mode: 'index',
|
|
},
|
|
cutoutPercentage: 55, // Adjust the percentage to match the desired hollow area
|
|
scales: {
|
|
y: {
|
|
display: false, // Hide y-axis
|
|
},
|
|
x: {
|
|
display: false, // Hide x-axis
|
|
},
|
|
},
|
|
},
|
|
});
|
|
}
|
|
}
|
|
function CircleGraph5(val, per) {
|
|
if (document.getElementById("chart-circle5")) {
|
|
var ctx12 = document.getElementById("chart-circle5").getContext("2d");
|
|
|
|
// Use a solid color instead of gradient
|
|
var backgroundColor = '#FFAB00';
|
|
|
|
new Chart(ctx12, {
|
|
type: "doughnut",
|
|
data: {
|
|
labels: ['On Hold'], // Only one label
|
|
datasets: [{
|
|
label: "Consumption",
|
|
weight: 9,
|
|
cutout: per + '%', // Adjust to control the size of the inner circle
|
|
borderWidth: 2, // Thicker outer line/border
|
|
backgroundColor: [backgroundColor], // Use solid color for the doughnut
|
|
borderColor: ['#325D7F'], // Outer border (can match the image background color)
|
|
data: [val], // Only one value representing 100%
|
|
fill: false
|
|
}],
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
plugins: {
|
|
legend: {
|
|
display: false, // Hide legend
|
|
},
|
|
tooltip: {
|
|
enabled: false, // Disable tooltip
|
|
},
|
|
},
|
|
interaction: {
|
|
intersect: false,
|
|
mode: 'index',
|
|
},
|
|
cutoutPercentage: 55, // Adjust the percentage to match the desired hollow area
|
|
scales: {
|
|
y: {
|
|
display: false, // Hide y-axis
|
|
},
|
|
x: {
|
|
display: false, // Hide x-axis
|
|
},
|
|
},
|
|
},
|
|
});
|
|
}
|
|
}
|
|
|
|
function ConsumptionGraph(data) {
|
|
if (document.getElementById("chart-consumption")) {
|
|
var ctx1 = document.getElementById("chart-consumption").getContext("2d");
|
|
|
|
new Chart(ctx1, {
|
|
type: "doughnut",
|
|
data: {
|
|
labels: ['Open', 'On Hold', 'In Progress', 'Done'], // Section names
|
|
datasets: [{
|
|
label: "Consumption",
|
|
data: data, // Segment values #FF5630
|
|
backgroundColor: ['#27aae1', '#FF5630', '#344767', '#fb8c00'],
|
|
borderColor: ['#27aae1', '#FF5630', '#344767', '#fb8c00'],
|
|
borderWidth: 0,
|
|
hoverBorderWidth: 1,
|
|
/* borderColor: '#1f2937', */ // Outer circle border color
|
|
cutout: '80%', // Inner circle hollow size
|
|
}],
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
plugins: {
|
|
tooltip: {
|
|
enabled: true, // Show legend on hover
|
|
},
|
|
legend: {
|
|
display: false, // Hide legend under chart
|
|
}
|
|
},
|
|
interaction: {
|
|
intersect: false,
|
|
mode: 'index',
|
|
},
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function PerformanceChartHome(data) {
|
|
const canvas = document.getElementById('pChart');
|
|
|
|
// Check if canvas exists and ctx is valid
|
|
if (!canvas) return;
|
|
const ctx = canvas.getContext('2d');
|
|
if (!ctx) return; // Exit if ctx is null
|
|
|
|
const gradient = ctx.createLinearGradient(0, 0, 0, 200); // Adjust the height as needed
|
|
gradient.addColorStop(0, 'rgba(53, 162, 235, 0.5)'); // Start color
|
|
gradient.addColorStop(1, 'rgba(53, 162, 235, 0)');
|
|
|
|
const pChart = new Chart(ctx, {
|
|
type: 'line',
|
|
data: {
|
|
labels: ['Open', 'Done', 'On Hold', 'In Progress'],
|
|
datasets: [{
|
|
data: data,
|
|
borderColor: 'rgba(53, 162, 235, 1)',
|
|
backgroundColor: gradient,
|
|
borderWidth: 2,
|
|
fill: true,
|
|
tension: 0.4, // Smooth curve
|
|
pointRadius: 0, // Remove the dots on the line
|
|
pointHoverRadius: 0 // Remove the hover effect on the dots
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false, // Allow custom height
|
|
scales: {
|
|
y: {
|
|
beginAtZero: true,
|
|
ticks: {
|
|
//color: 'rgba(255, 255, 255, 0.6)',
|
|
},
|
|
grid: {
|
|
color: 'rgba(255, 255, 255, 0.1)', // Horizontal grid lines
|
|
drawBorder: false, // Optionally remove the border line
|
|
drawOnChartArea: true, // Draw lines only on the chart area
|
|
drawTicks: false
|
|
}
|
|
},
|
|
x: {
|
|
ticks: {
|
|
//color: 'rgba(255, 255, 255, 0.6)',
|
|
},
|
|
grid: {
|
|
display: false
|
|
}
|
|
}
|
|
},
|
|
plugins: {
|
|
legend: {
|
|
display: false // Remove the label
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
//Home page charts End
|
|
|
|
// Report charts
|
|
function LineChartMUI() {
|
|
const canvas = document.getElementById('lineChart1');
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
// Define the points for the line chart
|
|
const dataPoints = [30, 45, 40, 60, 50, 70, 60, 80];
|
|
const canvasWidth = canvas.width;
|
|
const canvasHeight = canvas.height;
|
|
const padding = 20;
|
|
const maxDataPoint = Math.max(...dataPoints);
|
|
|
|
// Clear the canvas before drawing
|
|
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
|
|
|
|
// Draw the chart line
|
|
ctx.beginPath();
|
|
ctx.moveTo(padding, canvasHeight - dataPoints[0] / maxDataPoint * (canvasHeight - padding));
|
|
|
|
dataPoints.forEach((point, index) => {
|
|
const x = padding + (canvasWidth - padding * 2) * (index / (dataPoints.length - 1));
|
|
const y = canvasHeight - point / maxDataPoint * (canvasHeight - padding);
|
|
ctx.lineTo(x, y);
|
|
});
|
|
|
|
// Set line properties
|
|
ctx.strokeStyle = '#4ade80'; // Light green color
|
|
ctx.lineWidth = 2;
|
|
ctx.stroke();
|
|
|
|
// Add gradient below the line
|
|
const gradient = ctx.createLinearGradient(0, 0, 0, canvasHeight);
|
|
gradient.addColorStop(0, 'rgba(74, 222, 128, 0.3)'); // Green with opacity
|
|
gradient.addColorStop(1, 'rgba(74, 222, 128, 0)'); // Transparent at the bottom
|
|
|
|
ctx.lineTo(canvasWidth - padding, canvasHeight - padding);
|
|
ctx.lineTo(padding, canvasHeight - padding);
|
|
ctx.closePath();
|
|
ctx.fillStyle = gradient;
|
|
ctx.fill();
|
|
}
|
|
|
|
function LineChartMUI2() {
|
|
const canvas = document.getElementById('lineChart2');
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
// Define the points for the line chart
|
|
const dataPoints = [30, 45, 40, 60, 50, 70, 60, 80];
|
|
const canvasWidth = canvas.width;
|
|
const canvasHeight = canvas.height;
|
|
const padding = 20;
|
|
const maxDataPoint = Math.max(...dataPoints);
|
|
|
|
// Clear the canvas before drawing
|
|
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
|
|
|
|
// Draw the chart line
|
|
ctx.beginPath();
|
|
ctx.moveTo(padding, canvasHeight - dataPoints[0] / maxDataPoint * (canvasHeight - padding));
|
|
|
|
dataPoints.forEach((point, index) => {
|
|
const x = padding + (canvasWidth - padding * 2) * (index / (dataPoints.length - 1));
|
|
const y = canvasHeight - point / maxDataPoint * (canvasHeight - padding);
|
|
ctx.lineTo(x, y);
|
|
});
|
|
|
|
// Set line properties
|
|
ctx.strokeStyle = '#f97316'; // orange green color
|
|
ctx.lineWidth = 2;
|
|
ctx.stroke();
|
|
|
|
// Add gradient below the line
|
|
const gradient = ctx.createLinearGradient(0, 0, 0, canvasHeight);
|
|
gradient.addColorStop(0, 'rgba(249, 115, 22, 0.3)'); // Orange with opacity
|
|
gradient.addColorStop(1, 'rgba(249, 115, 22, 0)'); // Transparent at the bottom
|
|
|
|
ctx.lineTo(canvasWidth - padding, canvasHeight - padding);
|
|
ctx.lineTo(padding, canvasHeight - padding);
|
|
ctx.closePath();
|
|
ctx.fillStyle = gradient;
|
|
ctx.fill();
|
|
}
|
|
// Line chart with gradient
|
|
function LineChart() {
|
|
var ctx2 = document.getElementById("line-chart-gradient").getContext("2d");
|
|
|
|
new Chart(ctx2, {
|
|
type: "line",
|
|
data: {
|
|
labels: ["Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
|
|
datasets: [{
|
|
label: "Mobile apps",
|
|
tension: 0.4,
|
|
borderWidth: 0,
|
|
pointRadius: 0,
|
|
borderColor: "#e91e63",
|
|
borderWidth: 3,
|
|
backgroundColor: "transparent",
|
|
fill: true,
|
|
data: [50, 40, 300, 220, 500, 250, 400, 230, 500],
|
|
maxBarThickness: 6
|
|
}],
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
plugins: {
|
|
legend: {
|
|
display: false,
|
|
}
|
|
},
|
|
interaction: {
|
|
intersect: false,
|
|
mode: 'index',
|
|
},
|
|
scales: {
|
|
y: {
|
|
grid: {
|
|
drawBorder: false,
|
|
display: true,
|
|
drawOnChartArea: true,
|
|
drawTicks: false,
|
|
borderDash: [5, 5],
|
|
color: '#c1c4ce5c'
|
|
},
|
|
ticks: {
|
|
display: true,
|
|
padding: 10,
|
|
color: '#b2b9bf',
|
|
font: {
|
|
size: 14,
|
|
weight: 300,
|
|
family: "Roboto",
|
|
style: 'normal',
|
|
lineHeight: 2
|
|
},
|
|
}
|
|
},
|
|
x: {
|
|
grid: {
|
|
drawBorder: false,
|
|
display: false,
|
|
drawOnChartArea: false,
|
|
drawTicks: false,
|
|
borderDash: [5, 5],
|
|
color: '#c1c4ce5c'
|
|
},
|
|
ticks: {
|
|
display: true,
|
|
color: '#b2b9bf',
|
|
padding: 10,
|
|
font: {
|
|
size: 14,
|
|
weight: 300,
|
|
family: "Roboto",
|
|
style: 'normal',
|
|
lineHeight: 2
|
|
},
|
|
}
|
|
},
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
function performanceLineGraph() {
|
|
const ctx = document.getElementById('performanceChart').getContext('2d');
|
|
const gradient = ctx.createLinearGradient(0, 0, 0, 400);
|
|
gradient.addColorStop(0, 'rgba(54, 162, 235, 0.4)'); // Light blue
|
|
gradient.addColorStop(1, 'rgba(54, 162, 235, 0)'); // Fully transparent
|
|
|
|
const performanceChart = new Chart(ctx, {
|
|
type: 'line',
|
|
data: {
|
|
labels: ['1 PM', '2 PM', '3 PM', '4 PM', '5 PM', '6 PM', '7 PM', '8 PM', '9 PM', '10 PM', '11 PM', '12 PM'],
|
|
datasets: [{
|
|
label: 'Total Expenses',
|
|
data: [80, 60, 150, 100, 80, 90, 50, 40, 80, 110, 120, 130],
|
|
backgroundColor: gradient, // Gradient fill below the line
|
|
borderColor: '#36A2EB', // Blue line color
|
|
borderWidth: 2,
|
|
pointRadius: 0, // No data point circles
|
|
fill: true, // Enable the gradient fill
|
|
tension: 0.4 // Smooth curve
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
plugins: {
|
|
legend: {
|
|
display: false,
|
|
labels: {
|
|
color: 'white'
|
|
}
|
|
}
|
|
},
|
|
scales: {
|
|
x: {
|
|
ticks: {
|
|
color: '#637381'
|
|
}
|
|
},
|
|
y: {
|
|
ticks: {
|
|
color: '#637381'
|
|
},
|
|
beginAtZero: true
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
//end of charts
|
|
</script>
|
|
<script>
|
|
function toggleSidebar() {
|
|
var element = document.getElementById("body");
|
|
if (element.classList.contains('g-sidenav-pinned')) {
|
|
element.classList.remove('g-sidenav-pinned');
|
|
element.classList.add('g-sidenav-hidden');
|
|
} else {
|
|
element.classList.remove('g-sidenav-hidden');
|
|
element.classList.add('g-sidenav-pinned');
|
|
}
|
|
}
|
|
|
|
function initializedsignature() {
|
|
console.log("call");
|
|
var canvas = document.getElementById('signatureCanvas');
|
|
console.log(canvas);
|
|
|
|
var signaturePad = new SignaturePad(canvas);
|
|
console.log(signaturePad);
|
|
// Add an event listener to update the display in real-time
|
|
signaturePad.on('change', function () {
|
|
var signatureData = signaturePad.toDataURL();
|
|
document.getElementById('signaturePreview').src = signatureData;
|
|
});
|
|
}
|
|
|
|
function initializedsignature1() {
|
|
var canvas = document.getElementById('signatureCanvas1');
|
|
var signaturePad = new SignaturePad(canvas);
|
|
// Add an event listener to update the display in real-time
|
|
signaturePad.on('change', function () {
|
|
var signatureData = signaturePad.toDataURL();
|
|
document.getElementById('signaturePreview1').src = signatureData;
|
|
});
|
|
}
|
|
function uploadfile(elementid) {
|
|
$("#" + elementid).click();
|
|
}
|
|
|
|
function sidbarscriptinitilizer() {
|
|
$(".sidenav-toggler").on("click", function () {
|
|
if ($("#body").hasClass("g-sidenav-hidden")) {
|
|
$("#body").removeClass("g-sidenav-hidden").addClass("g-sidenav-pinned");
|
|
} else {
|
|
$("#body").removeClass("g-sidenav-pinned").addClass("g-sidenav-hidden");
|
|
}
|
|
});
|
|
|
|
$(".sidenav-toggler-inner").on("click", function () {
|
|
if ($("#body").hasClass("g-sidenav-hidden")) {
|
|
$("#body").removeClass("g-sidenav-hidden").addClass("g-sidenav-pinned");
|
|
} else {
|
|
$("#body").removeClass("g-sidenav-pinned").addClass("g-sidenav-hidden");
|
|
}
|
|
});
|
|
}
|
|
|
|
//Checkbox selecting all list items
|
|
window.selectAllQuotes = () => {
|
|
let checkboxes = document.querySelectorAll('input[type="checkbox"]');
|
|
let selectAllCheckbox = document.getElementById('selectAllCheckbox');
|
|
|
|
checkboxes.forEach(checkbox => {
|
|
checkbox.checked = selectAllCheckbox.checked;
|
|
});
|
|
};
|
|
window.SelectContacts = () => {
|
|
let checkboxes = document.querySelectorAll('input[type="checkbox"]');
|
|
let selectAllCheckbox = document.getElementById('selectAllContactCheckbox');
|
|
|
|
checkboxes.forEach(checkbox => {
|
|
checkbox.checked = selectAllCheckbox.checked;
|
|
});
|
|
};
|
|
window.SelectAddressBook = () => {
|
|
let checkboxes = document.querySelectorAll('input[type="checkbox"]');
|
|
let selectAllCheckbox = document.getElementById('selectBook');
|
|
|
|
checkboxes.forEach(checkbox => {
|
|
checkbox.checked = selectAllCheckbox.checked;
|
|
});
|
|
};
|
|
//end of checkbox
|
|
function initScripts() {
|
|
if (document.getElementById('products-list')) {
|
|
const dataTableSearch = new simpleDatatables.DataTable("#products-list", {
|
|
searchable: true,
|
|
fixedHeight: false,
|
|
perPage: 7
|
|
});
|
|
|
|
document.querySelectorAll(".export").forEach(function (el) {
|
|
el.addEventListener("click", function (e) {
|
|
var type = el.dataset.type;
|
|
|
|
var data = {
|
|
type: type,
|
|
filename: "material-" + type,
|
|
};
|
|
|
|
if (type === "csv") {
|
|
data.columnDelimiter = "|";
|
|
}
|
|
|
|
dataTableSearch.export(data);
|
|
});
|
|
});
|
|
};
|
|
}
|
|
function closemodal() {
|
|
$("#mymodal").modal("hide");
|
|
$(".modal").modal("hide");
|
|
}
|
|
|
|
function showmodal() {
|
|
$("#mymodal").modal("show");
|
|
}
|
|
|
|
function closemodal2() {
|
|
$("#mymodal2").modal("hide");
|
|
}
|
|
|
|
function showmodal2() {
|
|
$("#mymodal2").modal("show");
|
|
}
|
|
|
|
var win = navigator.platform.indexOf('Win') > -1;
|
|
if (win && document.querySelector('#sidenav-scrollbar')) {
|
|
var options = {
|
|
damping: '0.5'
|
|
}
|
|
Scrollbar.init(document.querySelector('#sidenav-scrollbar'), options);
|
|
}
|
|
</script>
|
|
<script>
|
|
window.downloadFileFromStream = async (fileName, contentStreamReference) => {
|
|
const arrayBuffer = await contentStreamReference.arrayBuffer();
|
|
const blob = new Blob([arrayBuffer]);
|
|
const url = URL.createObjectURL(blob);
|
|
const anchorElement = document.createElement('a');
|
|
anchorElement.href = url;
|
|
anchorElement.download = fileName ?? '';
|
|
anchorElement.click();
|
|
anchorElement.remove();
|
|
URL.revokeObjectURL(url);
|
|
}
|
|
</script>
|
|
<!-- Add this to your _Imports.razor or index.html -->
|
|
<script>
|
|
window.downloadFile = (base64String, fileName) => {
|
|
const byteCharacters = atob(base64String);
|
|
const byteArrays = [];
|
|
for (let offset = 0; offset < byteCharacters.length; offset += 512) {
|
|
const slice = byteCharacters.slice(offset, offset + 512);
|
|
const byteNumbers = new Array(slice.length);
|
|
for (let i = 0; i < slice.length; i++) {
|
|
byteNumbers[i] = slice.charCodeAt(i);
|
|
}
|
|
const byteArray = new Uint8Array(byteNumbers);
|
|
byteArrays.push(byteArray);
|
|
}
|
|
const blob = new Blob(byteArrays, { type: "application/pdf" });
|
|
const link = document.createElement('a');
|
|
link.href = URL.createObjectURL(blob);
|
|
link.download = fileName;
|
|
link.click();
|
|
};
|
|
</script>
|
|
<script>
|
|
window.initializeMaterialDashboardCSS = () => {
|
|
const linkElement = document.createElement('link');
|
|
linkElement.src = '/assets/js/material-dashboard.min.js';
|
|
|
|
document.head.appendChild(linkElement);
|
|
};
|
|
window.focusOnFirstInvalidInput = function () {
|
|
var invalidInput = document.querySelector('.input-validation-error');
|
|
if (invalidInput) {
|
|
invalidInput.focus();
|
|
}
|
|
};
|
|
</script>
|
|
<script>
|
|
window.initializeMaterialDashboardJS = () => {
|
|
const scriptElement = document.createElement('script');
|
|
scriptElement.src = '/assets/js/material-dashboard.min.js'; // Set the source of the script
|
|
|
|
document.body.appendChild(scriptElement); // Append the script to the body
|
|
};
|
|
</script>
|
|
<script>
|
|
window.getHtmlContent = (element) => {
|
|
console.log(element.innerHTML);
|
|
return element.innerHTML;
|
|
};
|
|
</script>
|
|
<script src="./assets/js/material-dashboard.js"></script>
|
|
<script src="_framework/blazor.server.js"></script>
|
|
<script src="_content/Radzen.Blazor/Radzen.Blazor.js"></script>
|
|
<script src="_content/BlazorGoogleMaps/js/objectManager.js"></script>
|
|
</body>
|
|
|
|
</html>
|
|
|
|
@code {
|
|
[CascadingParameter]
|
|
private HttpContext HttpContext { get; set; } = default!;
|
|
|
|
private IComponentRenderMode? RenderModeForPage => HttpContext.Request.Path.StartsWithSegments("/Account")
|
|
? null
|
|
: InteractiveServer;
|
|
}
|