feat: UI improvements and responsive design enhancements

- Fix dark mode overscroll areas with proper background colors
- Add mobile responsiveness for project logos in header
- Improve viewport handling with interactive-widget support
- Update app title to proper case 'AdsPreview'
- Add mobile-friendly padding adjustments for tabs and headers
- Update .gitignore to exclude .code-workspace files
- Enhance CSS with anticon color overrides and mobile breakpoints
This commit is contained in:
Johannes
2025-09-09 18:45:39 +02:00
parent df746eae6a
commit 501dc92119
8 changed files with 78 additions and 10 deletions

1
.gitignore vendored
View File

@@ -39,3 +39,4 @@ area/
# Deployment
.env.upload
.code-workspace

View File

@@ -0,0 +1,7 @@
{
"folders": [
{
"path": "."
}
]
}

View File

@@ -2,8 +2,8 @@
<html lang="de">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>adspreview</title>
<meta name="viewport" content="width=device-width, initial-scale=1, interactive-widget=resizes-content" />
<title>AdsPreview</title>
</head>
<body>
<div id="root"></div>

View File

@@ -19,6 +19,41 @@ function App() {
return stored === 'true';
});
// Set initial background colors immediately on component mount
useEffect(() => {
const htmlElement = document.documentElement;
const bodyElement = document.body;
// Set initial colors based on current darkMode state
const bgColor = darkMode ? '#181818' : '#f5f5f5';
htmlElement.style.backgroundColor = bgColor;
bodyElement.style.backgroundColor = bgColor;
if (darkMode) {
htmlElement.classList.add('dark-mode');
} else {
htmlElement.classList.remove('dark-mode');
}
}, []); // Run only once on mount
// Update HTML class and background color when darkMode changes
useEffect(() => {
const htmlElement = document.documentElement;
const bodyElement = document.body;
if (darkMode) {
htmlElement.classList.add('dark-mode');
// Set dark mode background colors to prevent white overscroll areas
htmlElement.style.backgroundColor = '#181818';
bodyElement.style.backgroundColor = '#181818';
} else {
htmlElement.classList.remove('dark-mode');
// Set light mode background colors
htmlElement.style.backgroundColor = '#ebebeb';
bodyElement.style.backgroundColor = '#f5f5f5';
}
}, [darkMode]);
useEffect(() => {
const token = localStorage.getItem('jwt');
@@ -99,8 +134,7 @@ function App() {
>
<AntApp>
<Router>
<Layout style={{ minHeight: '100vh' }}>
{/* Kein globaler Header mehr, Header wird ggf. in einzelnen Seiten eingebunden */}
<Layout style={{ minHeight: '100dvh' }}>
<Layout.Content style={{ padding: 0 }}>
<Routes>
{user.role === 'admin' ? (

View File

@@ -11,7 +11,29 @@
margin-bottom: 0px;
}
.ant-layout-header.overview-header {
padding: 0 32px;
}
.ant-tabs-content {
padding: 0px 32px;
overflow: auto;
}
/* Adjust tab navigation padding on mobile */
@media (max-width: 768px) {
.ant-tabs > .ant-tabs-nav {
padding: 9px 16px; /* Reduced padding on mobile */
}
.ant-layout-header.overview-header {
padding: 0 16px;
}
.ant-tabs-content {
padding: 0px 16px; /* Reduced padding on mobile */
}
}
/* Global anticon color override */
.anticon {
color: rgb(0, 31, 30) !important;
}

View File

@@ -198,7 +198,7 @@ export default function ClientProjects({ user, darkMode, onLogout, onToggleDarkM
cursor: ${sortMode ? 'grabbing' : 'default'};
}
`}</style>
<Layout.Header style={{
<Layout.Header className='overview-header' style={{
position: 'sticky',
top: 0,
zIndex: 100,
@@ -206,8 +206,7 @@ export default function ClientProjects({ user, darkMode, onLogout, onToggleDarkM
justifyContent: 'space-between',
alignItems: 'center',
background: darkMode ? '#001f1e' : '#001f1e',
color: darkMode ? '#fff' : '#fff',
padding: '0 32px'
color: darkMode ? '#fff' : '#fff'
}}>
<div style={{ fontWeight: 700, fontSize: 20, color: darkMode ? '#fff' : undefined }}>Übersicht</div>
<div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>

View File

@@ -40,7 +40,7 @@ export default function LoginPage({ onLogin }) {
return (
<div
style={{
minHeight: '100vh',
minHeight: '100dvh',
width: '100vw',
background: darkMode ? '#181818' : '#f5f5f5',
transition: 'background 0.2s',

View File

@@ -1,12 +1,13 @@
import React, { useEffect, useState } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { Tabs, Button, Spin, Skeleton, Result } from 'antd';
import { Tabs, Button, Spin, Skeleton, Result, Grid } from 'antd';
import { ArrowLeftOutlined, LoadingOutlined, LockOutlined } from '@ant-design/icons';
import UserMenu from '../components/UserMenu';
import FilePreview, { formatFileSize, formatDuration } from '../components/FilePreview';
import debugLogger from '../utils/debugLogger';
const backendUrl = process.env.REACT_APP_BACKEND || '';
const { useBreakpoint } = Grid;
function ProjectDetail({ user, darkMode, onLogout, onToggleDarkMode, overrideParams, ...props }) {
// URL-Parameter holen, mit Override-Support für Smart Resolution
@@ -16,6 +17,10 @@ function ProjectDetail({ user, darkMode, onLogout, onToggleDarkMode, overridePar
const client = user.role === 'admin' ? routeClient : user.client;
const navigate = useNavigate();
// Responsive breakpoints
const screens = useBreakpoint();
const isMobile = !screens.md; // md breakpoint ist 768px
debugLogger.routing('ProjectDetail - Received params:', {
routeParams,
overrideParams,
@@ -264,7 +269,7 @@ function ProjectDetail({ user, darkMode, onLogout, onToggleDarkMode, overridePar
onClick={() => navigate('/')}
style={{ marginRight: projectLogo ? 12 : 0 }}
/>
{projectLogo && (
{projectLogo && !isMobile && (
<img
src={projectLogo}
alt="Logo"