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:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -39,3 +39,4 @@ area/
|
||||
|
||||
# Deployment
|
||||
.env.upload
|
||||
.code-workspace
|
||||
7
adspreview_react.code-workspace
Normal file
7
adspreview_react.code-workspace
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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' ? (
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 }}>
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user