mirror of
				https://github.com/9technologygroup/patchmon.net.git
				synced 2025-11-03 21:43:33 +00:00 
			
		
		
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			renovate/m
			...
			renovate/v
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					a1f506ae9d | 
@@ -48,7 +48,7 @@ WORKDIR /app/backend
 | 
			
		||||
 | 
			
		||||
RUN npm cache clean --force &&\
 | 
			
		||||
    rm -rf node_modules ~/.npm /root/.npm &&\
 | 
			
		||||
    npm ci --ignore-scripts --legacy-peer-deps --no-audit --prefer-online --fetch-retries=3 --fetch-retry-mintimeout=20000 --fetch-retry-maxtimeout=120000 &&\
 | 
			
		||||
    npm ci --ignore-scripts --legacy-peer-deps --no-audit --prefer-online --fetch-retries=0 &&\
 | 
			
		||||
    PRISMA_CLI_BINARY_TYPE=binary npm run db:generate &&\
 | 
			
		||||
    npm prune --omit=dev &&\
 | 
			
		||||
    npm cache clean --force
 | 
			
		||||
 
 | 
			
		||||
@@ -21,13 +21,9 @@ WORKDIR /app/frontend
 | 
			
		||||
 | 
			
		||||
COPY frontend/package*.json ./
 | 
			
		||||
 | 
			
		||||
RUN echo "=== Starting npm install ===" &&\
 | 
			
		||||
    npm cache clean --force &&\
 | 
			
		||||
RUN npm cache clean --force &&\
 | 
			
		||||
    rm -rf node_modules ~/.npm /root/.npm &&\
 | 
			
		||||
    echo "=== npm install ===" &&\
 | 
			
		||||
    npm install --ignore-scripts --legacy-peer-deps --no-audit --prefer-online --fetch-retries=3 --fetch-retry-mintimeout=20000 --fetch-retry-maxtimeout=120000 &&\
 | 
			
		||||
    echo "=== npm install completed ===" &&\
 | 
			
		||||
    npm cache clean --force
 | 
			
		||||
    npm install --ignore-scripts --legacy-peer-deps --no-audit --prefer-online --fetch-retries=0
 | 
			
		||||
 | 
			
		||||
COPY frontend/ ./
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -27,15 +27,16 @@
 | 
			
		||||
		"react-chartjs-2": "^5.2.0",
 | 
			
		||||
		"react-dom": "^18.3.1",
 | 
			
		||||
		"react-icons": "^5.5.0",
 | 
			
		||||
		"react-router-dom": "^6.30.1"
 | 
			
		||||
		"react-router-dom": "^6.30.1",
 | 
			
		||||
		"trianglify": "^4.1.1"
 | 
			
		||||
	},
 | 
			
		||||
	"devDependencies": {
 | 
			
		||||
		"@types/react": "^18.3.14",
 | 
			
		||||
		"@types/react-dom": "^18.3.1",
 | 
			
		||||
		"@vitejs/plugin-react": "^4.3.4",
 | 
			
		||||
		"@vitejs/plugin-react": "^5.0.0",
 | 
			
		||||
		"autoprefixer": "^10.4.20",
 | 
			
		||||
		"postcss": "^8.5.6",
 | 
			
		||||
		"tailwindcss": "^4.0.0",
 | 
			
		||||
		"tailwindcss": "^3.4.17",
 | 
			
		||||
		"vite": "^7.1.5"
 | 
			
		||||
	},
 | 
			
		||||
	"overrides": {
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,7 @@ import {
 | 
			
		||||
import { useCallback, useEffect, useRef, useState } from "react";
 | 
			
		||||
import { FaReddit, FaYoutube } from "react-icons/fa";
 | 
			
		||||
import { Link, useLocation, useNavigate } from "react-router-dom";
 | 
			
		||||
import trianglify from "trianglify";
 | 
			
		||||
import { useAuth } from "../contexts/AuthContext";
 | 
			
		||||
import { useColorTheme } from "../contexts/ColorThemeContext";
 | 
			
		||||
import { useUpdateNotification } from "../contexts/UpdateNotificationContext";
 | 
			
		||||
@@ -236,93 +237,31 @@ const Layout = ({ children }) => {
 | 
			
		||||
		navigate("/hosts?action=add");
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	// Generate clean radial gradient background with subtle triangular accents for dark mode
 | 
			
		||||
	// Generate Trianglify background for dark mode
 | 
			
		||||
	useEffect(() => {
 | 
			
		||||
		const generateBackground = () => {
 | 
			
		||||
			if (
 | 
			
		||||
				!bgCanvasRef.current ||
 | 
			
		||||
				!themeConfig?.login ||
 | 
			
		||||
				!document.documentElement.classList.contains("dark")
 | 
			
		||||
				bgCanvasRef.current &&
 | 
			
		||||
				themeConfig?.login &&
 | 
			
		||||
				document.documentElement.classList.contains("dark")
 | 
			
		||||
			) {
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
				// Get current date as seed for daily variation
 | 
			
		||||
				const today = new Date();
 | 
			
		||||
				const dateSeed = `${today.getFullYear()}-${today.getMonth()}-${today.getDate()}`;
 | 
			
		||||
 | 
			
		||||
			const canvas = bgCanvasRef.current;
 | 
			
		||||
			canvas.width = window.innerWidth;
 | 
			
		||||
			canvas.height = window.innerHeight;
 | 
			
		||||
			const ctx = canvas.getContext("2d");
 | 
			
		||||
				// Generate pattern with selected theme configuration
 | 
			
		||||
				const pattern = trianglify({
 | 
			
		||||
					width: window.innerWidth,
 | 
			
		||||
					height: window.innerHeight,
 | 
			
		||||
					cellSize: themeConfig.login.cellSize,
 | 
			
		||||
					variance: themeConfig.login.variance,
 | 
			
		||||
					seed: dateSeed,
 | 
			
		||||
					xColors: themeConfig.login.xColors,
 | 
			
		||||
					yColors: themeConfig.login.yColors,
 | 
			
		||||
				});
 | 
			
		||||
 | 
			
		||||
			// Get theme colors - pick first color from each palette
 | 
			
		||||
			const xColors = themeConfig.login.xColors || [
 | 
			
		||||
				"#667eea",
 | 
			
		||||
				"#764ba2",
 | 
			
		||||
				"#f093fb",
 | 
			
		||||
				"#4facfe",
 | 
			
		||||
			];
 | 
			
		||||
			const yColors = themeConfig.login.yColors || [
 | 
			
		||||
				"#667eea",
 | 
			
		||||
				"#764ba2",
 | 
			
		||||
				"#f093fb",
 | 
			
		||||
				"#4facfe",
 | 
			
		||||
			];
 | 
			
		||||
 | 
			
		||||
			// Use date for daily color rotation
 | 
			
		||||
			const today = new Date();
 | 
			
		||||
			const seed =
 | 
			
		||||
				today.getFullYear() * 10000 + today.getMonth() * 100 + today.getDate();
 | 
			
		||||
			const random = (s) => {
 | 
			
		||||
				const x = Math.sin(s) * 10000;
 | 
			
		||||
				return x - Math.floor(x);
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			const color1 = xColors[Math.floor(random(seed) * xColors.length)];
 | 
			
		||||
			const color2 = yColors[Math.floor(random(seed + 1000) * yColors.length)];
 | 
			
		||||
 | 
			
		||||
			// Create clean radial gradient from center to bottom-right corner
 | 
			
		||||
			const gradient = ctx.createRadialGradient(
 | 
			
		||||
				canvas.width * 0.3, // Center slightly left
 | 
			
		||||
				canvas.height * 0.3, // Center slightly up
 | 
			
		||||
				0,
 | 
			
		||||
				canvas.width * 0.5, // Expand to cover screen
 | 
			
		||||
				canvas.height * 0.5,
 | 
			
		||||
				Math.max(canvas.width, canvas.height) * 1.2,
 | 
			
		||||
			);
 | 
			
		||||
 | 
			
		||||
			// Subtle gradient with darker corners
 | 
			
		||||
			gradient.addColorStop(0, color1);
 | 
			
		||||
			gradient.addColorStop(0.6, color2);
 | 
			
		||||
			gradient.addColorStop(1, "#0a0a0a"); // Very dark edges
 | 
			
		||||
 | 
			
		||||
			ctx.fillStyle = gradient;
 | 
			
		||||
			ctx.fillRect(0, 0, canvas.width, canvas.height);
 | 
			
		||||
 | 
			
		||||
			// Add subtle triangular shapes as accents across entire background
 | 
			
		||||
			const cellSize = 180;
 | 
			
		||||
			const cols = Math.ceil(canvas.width / cellSize) + 1;
 | 
			
		||||
			const rows = Math.ceil(canvas.height / cellSize) + 1;
 | 
			
		||||
 | 
			
		||||
			for (let y = 0; y < rows; y++) {
 | 
			
		||||
				for (let x = 0; x < cols; x++) {
 | 
			
		||||
					const idx = y * cols + x;
 | 
			
		||||
					// Draw more triangles (less sparse)
 | 
			
		||||
					if (random(seed + idx + 5000) > 0.4) {
 | 
			
		||||
						const baseX =
 | 
			
		||||
							x * cellSize + random(seed + idx * 3) * cellSize * 0.8;
 | 
			
		||||
						const baseY =
 | 
			
		||||
							y * cellSize + random(seed + idx * 3 + 100) * cellSize * 0.8;
 | 
			
		||||
						const size = 50 + random(seed + idx * 4) * 100;
 | 
			
		||||
 | 
			
		||||
						ctx.beginPath();
 | 
			
		||||
						ctx.moveTo(baseX, baseY);
 | 
			
		||||
						ctx.lineTo(baseX + size, baseY);
 | 
			
		||||
						ctx.lineTo(baseX + size / 2, baseY - size * 0.866);
 | 
			
		||||
						ctx.closePath();
 | 
			
		||||
 | 
			
		||||
						// More visible white with slightly higher opacity
 | 
			
		||||
						ctx.fillStyle = `rgba(255, 255, 255, ${0.05 + random(seed + idx * 5) * 0.08})`;
 | 
			
		||||
						ctx.fill();
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				// Render to canvas
 | 
			
		||||
				pattern.toCanvas(bgCanvasRef.current);
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,7 @@ import { useEffect, useId, useRef, useState } from "react";
 | 
			
		||||
import { FaReddit, FaYoutube } from "react-icons/fa";
 | 
			
		||||
 | 
			
		||||
import { useNavigate } from "react-router-dom";
 | 
			
		||||
import trianglify from "trianglify";
 | 
			
		||||
import DiscordIcon from "../components/DiscordIcon";
 | 
			
		||||
import { useAuth } from "../contexts/AuthContext";
 | 
			
		||||
import { useColorTheme } from "../contexts/ColorThemeContext";
 | 
			
		||||
@@ -56,87 +57,27 @@ const Login = () => {
 | 
			
		||||
 | 
			
		||||
	const navigate = useNavigate();
 | 
			
		||||
 | 
			
		||||
	// Generate clean radial gradient background with subtle triangular accents
 | 
			
		||||
	// Generate Trianglify background based on selected theme
 | 
			
		||||
	useEffect(() => {
 | 
			
		||||
		const generateBackground = () => {
 | 
			
		||||
			if (!canvasRef.current || !themeConfig?.login) return;
 | 
			
		||||
			if (canvasRef.current && themeConfig?.login) {
 | 
			
		||||
				// Get current date as seed for daily variation
 | 
			
		||||
				const today = new Date();
 | 
			
		||||
				const dateSeed = `${today.getFullYear()}-${today.getMonth()}-${today.getDate()}`;
 | 
			
		||||
 | 
			
		||||
			const canvas = canvasRef.current;
 | 
			
		||||
			canvas.width = canvas.offsetWidth;
 | 
			
		||||
			canvas.height = canvas.offsetHeight;
 | 
			
		||||
			const ctx = canvas.getContext("2d");
 | 
			
		||||
				// Generate pattern with selected theme configuration
 | 
			
		||||
				const pattern = trianglify({
 | 
			
		||||
					width: canvasRef.current.offsetWidth,
 | 
			
		||||
					height: canvasRef.current.offsetHeight,
 | 
			
		||||
					cellSize: themeConfig.login.cellSize,
 | 
			
		||||
					variance: themeConfig.login.variance,
 | 
			
		||||
					seed: dateSeed,
 | 
			
		||||
					xColors: themeConfig.login.xColors,
 | 
			
		||||
					yColors: themeConfig.login.yColors,
 | 
			
		||||
				});
 | 
			
		||||
 | 
			
		||||
			// Get theme colors - pick first color from each palette
 | 
			
		||||
			const xColors = themeConfig.login.xColors || [
 | 
			
		||||
				"#667eea",
 | 
			
		||||
				"#764ba2",
 | 
			
		||||
				"#f093fb",
 | 
			
		||||
				"#4facfe",
 | 
			
		||||
			];
 | 
			
		||||
			const yColors = themeConfig.login.yColors || [
 | 
			
		||||
				"#667eea",
 | 
			
		||||
				"#764ba2",
 | 
			
		||||
				"#f093fb",
 | 
			
		||||
				"#4facfe",
 | 
			
		||||
			];
 | 
			
		||||
 | 
			
		||||
			// Use date for daily color rotation
 | 
			
		||||
			const today = new Date();
 | 
			
		||||
			const seed =
 | 
			
		||||
				today.getFullYear() * 10000 + today.getMonth() * 100 + today.getDate();
 | 
			
		||||
			const random = (s) => {
 | 
			
		||||
				const x = Math.sin(s) * 10000;
 | 
			
		||||
				return x - Math.floor(x);
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			const color1 = xColors[Math.floor(random(seed) * xColors.length)];
 | 
			
		||||
			const color2 = yColors[Math.floor(random(seed + 1000) * yColors.length)];
 | 
			
		||||
 | 
			
		||||
			// Create clean radial gradient from center to bottom-right corner
 | 
			
		||||
			const gradient = ctx.createRadialGradient(
 | 
			
		||||
				canvas.width * 0.3, // Center slightly left
 | 
			
		||||
				canvas.height * 0.3, // Center slightly up
 | 
			
		||||
				0,
 | 
			
		||||
				canvas.width * 0.5, // Expand to cover screen
 | 
			
		||||
				canvas.height * 0.5,
 | 
			
		||||
				Math.max(canvas.width, canvas.height) * 1.2,
 | 
			
		||||
			);
 | 
			
		||||
 | 
			
		||||
			// Subtle gradient with darker corners
 | 
			
		||||
			gradient.addColorStop(0, color1);
 | 
			
		||||
			gradient.addColorStop(0.6, color2);
 | 
			
		||||
			gradient.addColorStop(1, "#0a0a0a"); // Very dark edges
 | 
			
		||||
 | 
			
		||||
			ctx.fillStyle = gradient;
 | 
			
		||||
			ctx.fillRect(0, 0, canvas.width, canvas.height);
 | 
			
		||||
 | 
			
		||||
			// Add subtle triangular shapes as accents across entire background
 | 
			
		||||
			const cellSize = 180;
 | 
			
		||||
			const cols = Math.ceil(canvas.width / cellSize) + 1;
 | 
			
		||||
			const rows = Math.ceil(canvas.height / cellSize) + 1;
 | 
			
		||||
 | 
			
		||||
			for (let y = 0; y < rows; y++) {
 | 
			
		||||
				for (let x = 0; x < cols; x++) {
 | 
			
		||||
					const idx = y * cols + x;
 | 
			
		||||
					// Draw more triangles (less sparse)
 | 
			
		||||
					if (random(seed + idx + 5000) > 0.4) {
 | 
			
		||||
						const baseX =
 | 
			
		||||
							x * cellSize + random(seed + idx * 3) * cellSize * 0.8;
 | 
			
		||||
						const baseY =
 | 
			
		||||
							y * cellSize + random(seed + idx * 3 + 100) * cellSize * 0.8;
 | 
			
		||||
						const size = 50 + random(seed + idx * 4) * 100;
 | 
			
		||||
 | 
			
		||||
						ctx.beginPath();
 | 
			
		||||
						ctx.moveTo(baseX, baseY);
 | 
			
		||||
						ctx.lineTo(baseX + size, baseY);
 | 
			
		||||
						ctx.lineTo(baseX + size / 2, baseY - size * 0.866);
 | 
			
		||||
						ctx.closePath();
 | 
			
		||||
 | 
			
		||||
						// More visible white with slightly higher opacity
 | 
			
		||||
						ctx.fillStyle = `rgba(255, 255, 255, ${0.05 + random(seed + idx * 5) * 0.08})`;
 | 
			
		||||
						ctx.fill();
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				// Render to canvas
 | 
			
		||||
				pattern.toCanvas(canvasRef.current);
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
@@ -149,7 +90,7 @@ const Login = () => {
 | 
			
		||||
 | 
			
		||||
		window.addEventListener("resize", handleResize);
 | 
			
		||||
		return () => window.removeEventListener("resize", handleResize);
 | 
			
		||||
	}, [themeConfig]);
 | 
			
		||||
	}, [themeConfig]); // Regenerate when theme changes
 | 
			
		||||
 | 
			
		||||
	// Check if signup is enabled
 | 
			
		||||
	useEffect(() => {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1273
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1273
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2
									
								
								setup.sh
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								setup.sh
									
									
									
									
									
								
							@@ -2931,8 +2931,6 @@ update_installation() {
 | 
			
		||||
    
 | 
			
		||||
    # Load existing .env to get database credentials
 | 
			
		||||
    if [ -f "$instance_dir/backend/.env" ]; then
 | 
			
		||||
        # Unset color variables before sourcing to prevent ANSI escape sequences from leaking into .env
 | 
			
		||||
        unset RED GREEN YELLOW BLUE NC
 | 
			
		||||
        source "$instance_dir/backend/.env"
 | 
			
		||||
        print_status "Loaded existing configuration"
 | 
			
		||||
        
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user