diff --git a/.gitignore b/.gitignore
index 212ee0c..5f09bf8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -262,5 +262,5 @@ __pycache__/
*.pyc
-**/*docker_compose/LetsEncryptServer/acme
-**/*docker_compose/LetsEncryptServer/cache
\ No newline at end of file
+**/*docker-compose/LetsEncryptServer/acme
+**/*docker-compose/LetsEncryptServer/cache
\ No newline at end of file
diff --git a/src/ClientApp/ApiRoutes.tsx b/src/ClientApp/ApiRoutes.tsx
new file mode 100644
index 0000000..2324ad8
--- /dev/null
+++ b/src/ClientApp/ApiRoutes.tsx
@@ -0,0 +1,15 @@
+enum ApiRoutes {
+
+ CACHE_GET_ACCOUNTS = `/api/Cache/GetAccounts`,
+ CACHE_GET_CONTACTS = `/api/Cache/GetContacts/{accountId}`,
+ CACHE_SET_CONTACTS = `/api/Cache/SetContacts/{accountId}`,
+
+ CERTS_FLOW_CONFIGURE_CLIENT = `/api/CertsFlow/ConfigureClient`,
+ CERTS_FLOW_TERMS_OF_SERVICE = `/api/CertsFlow/TermsOfService/{sessionId}`,
+ CERTS_FLOW_INIT = `/api/CertsFlow/Init/{sessionId}/{accountId}`,
+ CERTS_FLOW_NEW_ORDER = `/api/CertsFlow/NewOrder/{sessionId}`,
+ CERTS_FLOW_GET_ORDER = `/api/CertsFlow/GetOrder/{sessionId}`,
+ CERTS_FLOW_GET_CERTIFICATES = `/api/CertsFlow/GetCertificates/{sessionId}`,
+ CERTS_FLOW_APPLY_CERTIFICATES = `/api/CertsFlow/ApplyCertificates/{sessionId}`,
+ CERTS_FLOW_HOSRS_WITH_UPCOMING_SSL_EXPIRY = `/api/CertsFlow/HostsWithUpcomingSslExpiry/{sessionId}`
+}
\ No newline at end of file
diff --git a/src/ClientApp/app/layout.tsx b/src/ClientApp/app/layout.tsx
index c6ee797..c5d6b42 100644
--- a/src/ClientApp/app/layout.tsx
+++ b/src/ClientApp/app/layout.tsx
@@ -1,11 +1,12 @@
"use client"; // Add this line
-import React, { FC, useState } from 'react';
+import React, { FC, useState, useEffect, useRef } from 'react';
import './globals.css';
import { SideMenu } from '../components/sidemenu';
import { TopMenu } from '../components/topmenu';
import { Footer } from '../components/footer';
import { OffCanvas } from '../components/offcanvas';
+import Loader from '../components/loader'; // Import the Loader component
import { Metadata } from 'next';
const metadata: Metadata = {
@@ -13,32 +14,71 @@ const metadata: Metadata = {
description: "Generated by create next app",
};
-const Layout = ({ children }: Readonly<{
- children: React.ReactNode;
-}>) => {
+const Layout: FC<{ children: React.ReactNode }> = ({ children }) => {
const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(false);
- const [isOffCanvasOpen, setIsOffCanvasOpen] = useState(false);
+ const [isManuallyCollapsed, setManuallyCollapsed] = useState(false);
+ const [isLoading, setIsLoading] = useState(true); // State to control the loader visibility
+
+ const init = useRef(false);
const toggleSidebar = () => {
- setIsSidebarCollapsed(!isSidebarCollapsed);
+ setIsSidebarCollapsed((prev) => !prev);
};
+ const manuallyToggleSidebar = () => {
+ setManuallyCollapsed((prev) => !prev);
+ toggleSidebar();
+ };
+
+ const handleResize = () => {
+ if (!isManuallyCollapsed) {
+ if (window.innerWidth <= 768) {
+ if (!isSidebarCollapsed) setIsSidebarCollapsed(true);
+ } else {
+ if (isSidebarCollapsed) setIsSidebarCollapsed(false);
+ }
+ } else {
+ if (isManuallyCollapsed) return;
+
+ // Reset manualCollapse if the window is resized to a state that should automatically collapse/expand the sidebar
+ if (window.innerWidth > 768 && isSidebarCollapsed) {
+ setIsSidebarCollapsed(false);
+ } else if (window.innerWidth <= 768 && !isSidebarCollapsed) {
+ setIsSidebarCollapsed(true);
+ }
+ }
+ };
+
+ useEffect(() => {
+ if (!init.current) {
+ handleResize(); // Set the initial state based on the current window width
+ init.current = true;
+ }
+
+ window.addEventListener('resize', handleResize);
+ setTimeout(() => setIsLoading(false), 2000); // Simulate loading for 2 seconds
+ return () => {
+ window.removeEventListener('resize', handleResize);
+ };
+ }, [isSidebarCollapsed, isManuallyCollapsed]);
+
+ const [isOffCanvasOpen, setIsOffCanvasOpen] = useState(false);
+
const toggleOffCanvas = () => {
- setIsOffCanvasOpen(!isOffCanvasOpen);
+ setIsOffCanvasOpen((prev) => !prev);
};
return (
- {/*
-
-
- */}
+
+ {isLoading && } {/* Show loader if isLoading is true */}
+
-
+
-
+
{children}
diff --git a/src/ClientApp/components/footer.tsx b/src/ClientApp/components/footer.tsx
index 25e9535..23ac5f1 100644
--- a/src/ClientApp/components/footer.tsx
+++ b/src/ClientApp/components/footer.tsx
@@ -3,7 +3,7 @@ import React from 'react';
const Footer = () => {
return (
);
};
diff --git a/src/ClientApp/components/loader/index.tsx b/src/ClientApp/components/loader/index.tsx
new file mode 100644
index 0000000..b55cd74
--- /dev/null
+++ b/src/ClientApp/components/loader/index.tsx
@@ -0,0 +1,13 @@
+import React from 'react';
+import './loader.css'; // Add your loader styles here
+
+const Loader: React.FC = () => {
+ return (
+
+ );
+};
+
+export default Loader;
diff --git a/src/ClientApp/components/loader/loader.css b/src/ClientApp/components/loader/loader.css
new file mode 100644
index 0000000..77fb78f
--- /dev/null
+++ b/src/ClientApp/components/loader/loader.css
@@ -0,0 +1,34 @@
+.loader-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: rgba(0, 0, 0, 0.1); /* 10% transparent background */
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 9999;
+ flex-direction: column;
+ }
+
+ .spinner {
+ border: 8px solid rgba(255, 255, 255, 0.3);
+ border-top: 8px solid #3498db;
+ border-radius: 50%;
+ width: 80px;
+ height: 80px;
+ animation: spin 1s linear infinite;
+ }
+
+ .loading-text {
+ margin-top: 20px;
+ font-size: 1.2em;
+ color: #3498db;
+ }
+
+ @keyframes spin {
+ 0% { transform: rotate(0deg); }
+ 100% { transform: rotate(360deg); }
+ }
+
\ No newline at end of file
diff --git a/src/ClientApp/components/sidemenu.tsx b/src/ClientApp/components/sidemenu.tsx
index 3c5f053..981a6af 100644
--- a/src/ClientApp/components/sidemenu.tsx
+++ b/src/ClientApp/components/sidemenu.tsx
@@ -1,4 +1,4 @@
-import React, { FC } from 'react';
+import React, { FC, useEffect, useRef } from 'react';
import { FaHome, FaUser, FaCog, FaBars } from 'react-icons/fa';
interface SideMenuProps {
@@ -7,12 +7,13 @@ interface SideMenuProps {
}
const SideMenu: FC = ({ isCollapsed, toggleSidebar }) => {
+
return (
- {/*
Logo