mirror of
https://github.com/9technologygroup/patchmon.net.git
synced 2025-11-03 13:33:30 +00:00
Compare commits
21 Commits
renovate/v
...
renovate/m
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9335f821f7 | ||
|
|
8361caabe8 | ||
|
|
f6d23e45b2 | ||
|
|
aba0f5cb6b | ||
|
|
2ec2b3992c | ||
|
|
f85721b292 | ||
|
|
1d2c003830 | ||
|
|
2975da0f69 | ||
|
|
93760d03e1 | ||
|
|
43fb54a683 | ||
|
|
e9368d1a95 | ||
|
|
3ce8c02a31 | ||
|
|
ac420901a6 | ||
|
|
eb0218bdcb | ||
|
|
1f6f58360f | ||
|
|
746451c296 | ||
|
|
285e4c59ee | ||
|
|
9050595b7c | ||
|
|
cc46940b0c | ||
|
|
203a065479 | ||
|
|
8864de6c15 |
@@ -48,7 +48,7 @@ WORKDIR /app/backend
|
|||||||
|
|
||||||
RUN npm cache clean --force &&\
|
RUN npm cache clean --force &&\
|
||||||
rm -rf node_modules ~/.npm /root/.npm &&\
|
rm -rf node_modules ~/.npm /root/.npm &&\
|
||||||
npm ci --ignore-scripts --legacy-peer-deps --no-audit --prefer-online --fetch-retries=0 &&\
|
npm ci --ignore-scripts --legacy-peer-deps --no-audit --prefer-online --fetch-retries=3 --fetch-retry-mintimeout=20000 --fetch-retry-maxtimeout=120000 &&\
|
||||||
PRISMA_CLI_BINARY_TYPE=binary npm run db:generate &&\
|
PRISMA_CLI_BINARY_TYPE=binary npm run db:generate &&\
|
||||||
npm prune --omit=dev &&\
|
npm prune --omit=dev &&\
|
||||||
npm cache clean --force
|
npm cache clean --force
|
||||||
|
|||||||
@@ -21,9 +21,13 @@ WORKDIR /app/frontend
|
|||||||
|
|
||||||
COPY frontend/package*.json ./
|
COPY frontend/package*.json ./
|
||||||
|
|
||||||
RUN npm cache clean --force &&\
|
RUN echo "=== Starting npm install ===" &&\
|
||||||
|
npm cache clean --force &&\
|
||||||
rm -rf node_modules ~/.npm /root/.npm &&\
|
rm -rf node_modules ~/.npm /root/.npm &&\
|
||||||
npm install --ignore-scripts --legacy-peer-deps --no-audit --prefer-online --fetch-retries=0
|
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
|
||||||
|
|
||||||
COPY frontend/ ./
|
COPY frontend/ ./
|
||||||
|
|
||||||
|
|||||||
@@ -27,8 +27,7 @@
|
|||||||
"react-chartjs-2": "^5.2.0",
|
"react-chartjs-2": "^5.2.0",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-icons": "^5.5.0",
|
"react-icons": "^5.5.0",
|
||||||
"react-router-dom": "^6.30.1",
|
"react-router-dom": "^6.30.1"
|
||||||
"trianglify": "^4.1.1"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "^18.3.14",
|
"@types/react": "^18.3.14",
|
||||||
@@ -36,7 +35,7 @@
|
|||||||
"@vitejs/plugin-react": "^4.3.4",
|
"@vitejs/plugin-react": "^4.3.4",
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.20",
|
||||||
"postcss": "^8.5.6",
|
"postcss": "^8.5.6",
|
||||||
"tailwindcss": "^3.4.17",
|
"tailwindcss": "^4.0.0",
|
||||||
"vite": "^7.1.5"
|
"vite": "^7.1.5"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import {
|
|||||||
import { useCallback, useEffect, useRef, useState } from "react";
|
import { useCallback, useEffect, useRef, useState } from "react";
|
||||||
import { FaReddit, FaYoutube } from "react-icons/fa";
|
import { FaReddit, FaYoutube } from "react-icons/fa";
|
||||||
import { Link, useLocation, useNavigate } from "react-router-dom";
|
import { Link, useLocation, useNavigate } from "react-router-dom";
|
||||||
import trianglify from "trianglify";
|
|
||||||
import { useAuth } from "../contexts/AuthContext";
|
import { useAuth } from "../contexts/AuthContext";
|
||||||
import { useColorTheme } from "../contexts/ColorThemeContext";
|
import { useColorTheme } from "../contexts/ColorThemeContext";
|
||||||
import { useUpdateNotification } from "../contexts/UpdateNotificationContext";
|
import { useUpdateNotification } from "../contexts/UpdateNotificationContext";
|
||||||
@@ -237,31 +236,93 @@ const Layout = ({ children }) => {
|
|||||||
navigate("/hosts?action=add");
|
navigate("/hosts?action=add");
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generate Trianglify background for dark mode
|
// Generate clean radial gradient background with subtle triangular accents for dark mode
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const generateBackground = () => {
|
const generateBackground = () => {
|
||||||
if (
|
if (
|
||||||
bgCanvasRef.current &&
|
!bgCanvasRef.current ||
|
||||||
themeConfig?.login &&
|
!themeConfig?.login ||
|
||||||
document.documentElement.classList.contains("dark")
|
!document.documentElement.classList.contains("dark")
|
||||||
) {
|
) {
|
||||||
// Get current date as seed for daily variation
|
return;
|
||||||
const today = new Date();
|
}
|
||||||
const dateSeed = `${today.getFullYear()}-${today.getMonth()}-${today.getDate()}`;
|
|
||||||
|
|
||||||
// Generate pattern with selected theme configuration
|
const canvas = bgCanvasRef.current;
|
||||||
const pattern = trianglify({
|
canvas.width = window.innerWidth;
|
||||||
width: window.innerWidth,
|
canvas.height = window.innerHeight;
|
||||||
height: window.innerHeight,
|
const ctx = canvas.getContext("2d");
|
||||||
cellSize: themeConfig.login.cellSize,
|
|
||||||
variance: themeConfig.login.variance,
|
|
||||||
seed: dateSeed,
|
|
||||||
xColors: themeConfig.login.xColors,
|
|
||||||
yColors: themeConfig.login.yColors,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Render to canvas
|
// Get theme colors - pick first color from each palette
|
||||||
pattern.toCanvas(bgCanvasRef.current);
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import { useEffect, useId, useRef, useState } from "react";
|
|||||||
import { FaReddit, FaYoutube } from "react-icons/fa";
|
import { FaReddit, FaYoutube } from "react-icons/fa";
|
||||||
|
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import trianglify from "trianglify";
|
|
||||||
import DiscordIcon from "../components/DiscordIcon";
|
import DiscordIcon from "../components/DiscordIcon";
|
||||||
import { useAuth } from "../contexts/AuthContext";
|
import { useAuth } from "../contexts/AuthContext";
|
||||||
import { useColorTheme } from "../contexts/ColorThemeContext";
|
import { useColorTheme } from "../contexts/ColorThemeContext";
|
||||||
@@ -57,27 +56,87 @@ const Login = () => {
|
|||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
// Generate Trianglify background based on selected theme
|
// Generate clean radial gradient background with subtle triangular accents
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const generateBackground = () => {
|
const generateBackground = () => {
|
||||||
if (canvasRef.current && themeConfig?.login) {
|
if (!canvasRef.current || !themeConfig?.login) return;
|
||||||
// Get current date as seed for daily variation
|
|
||||||
const today = new Date();
|
|
||||||
const dateSeed = `${today.getFullYear()}-${today.getMonth()}-${today.getDate()}`;
|
|
||||||
|
|
||||||
// Generate pattern with selected theme configuration
|
const canvas = canvasRef.current;
|
||||||
const pattern = trianglify({
|
canvas.width = canvas.offsetWidth;
|
||||||
width: canvasRef.current.offsetWidth,
|
canvas.height = canvas.offsetHeight;
|
||||||
height: canvasRef.current.offsetHeight,
|
const ctx = canvas.getContext("2d");
|
||||||
cellSize: themeConfig.login.cellSize,
|
|
||||||
variance: themeConfig.login.variance,
|
|
||||||
seed: dateSeed,
|
|
||||||
xColors: themeConfig.login.xColors,
|
|
||||||
yColors: themeConfig.login.yColors,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Render to canvas
|
// Get theme colors - pick first color from each palette
|
||||||
pattern.toCanvas(canvasRef.current);
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -90,7 +149,7 @@ const Login = () => {
|
|||||||
|
|
||||||
window.addEventListener("resize", handleResize);
|
window.addEventListener("resize", handleResize);
|
||||||
return () => window.removeEventListener("resize", handleResize);
|
return () => window.removeEventListener("resize", handleResize);
|
||||||
}, [themeConfig]); // Regenerate when theme changes
|
}, [themeConfig]);
|
||||||
|
|
||||||
// Check if signup is enabled
|
// Check if signup is enabled
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
1498
package-lock.json
generated
1498
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
2
setup.sh
2
setup.sh
@@ -2931,6 +2931,8 @@ update_installation() {
|
|||||||
|
|
||||||
# Load existing .env to get database credentials
|
# Load existing .env to get database credentials
|
||||||
if [ -f "$instance_dir/backend/.env" ]; then
|
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"
|
source "$instance_dir/backend/.env"
|
||||||
print_status "Loaded existing configuration"
|
print_status "Loaded existing configuration"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user