Skip to content

Commit fa2736a

Browse files
author
Creator
committed
Fix UI bugs: safe zone layout, watermark alignment, a11y overlap, and offline tooltip mobile interaction
1 parent 801b77e commit fa2736a

5 files changed

Lines changed: 48 additions & 15 deletions

File tree

src/App.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export default function App() {
4343

4444
const [currentPath, setCurrentPath] = useState(getLogicalPath);
4545
const [deferredPrompt, setDeferredPrompt] = useState<any>(null);
46+
const [showOfflineTooltip, setShowOfflineTooltip] = useState(false);
4647

4748
useEffect(() => {
4849
const handlePopState = () => {
@@ -277,14 +278,14 @@ export default function App() {
277278
</button>
278279
)}
279280

280-
<div className="group relative">
281-
<div className="flex items-center gap-2 bg-[#18181b]/95 backdrop-blur-md border border-emerald-500/30 px-3 py-2 rounded-full shadow-[0_4_20px_rgba(16,185,129,0.15)] group-hover:bg-[#27272a] group-hover:border-emerald-500/50 transition-all cursor-default">
281+
<div className="group relative" onClick={() => setShowOfflineTooltip(!showOfflineTooltip)} onMouseLeave={() => setShowOfflineTooltip(false)}>
282+
<div className="flex items-center gap-2 bg-[#18181b]/95 backdrop-blur-md border border-emerald-500/30 px-3 py-2 rounded-full shadow-[0_4_20px_rgba(16,185,129,0.15)] group-hover:bg-[#27272a] group-hover:border-emerald-500/50 transition-all cursor-pointer">
282283
<div className="w-2 h-2 rounded-full bg-emerald-500 shadow-[0_0_8px_rgba(16,185,129,0.8)] animate-pulse"></div>
283284
<span className="text-[10px] font-bold text-emerald-400 uppercase tracking-widest hidden sm:inline-block pr-1">Works Offline</span>
284285
</div>
285286

286287
{/* Hover Tooltip Details */}
287-
<div className="absolute bottom-full right-0 mb-3 w-64 p-3 bg-[#18181b] border border-zinc-800 rounded-xl shadow-2xl opacity-0 translate-y-2 pointer-events-none group-hover:opacity-100 group-hover:translate-y-0 transition-all duration-300 origin-bottom-right">
288+
<div className={`absolute bottom-full right-0 mb-3 w-64 p-3 bg-[#18181b] border border-zinc-800 rounded-xl shadow-2xl transition-all duration-300 origin-bottom-right ${showOfflineTooltip ? 'opacity-100 translate-y-0 pointer-events-auto' : 'opacity-0 translate-y-2 pointer-events-none group-hover:opacity-100 group-hover:translate-y-0'}`}>
288289
<p className="text-xs text-zinc-400 leading-relaxed">
289290
<strong className="text-emerald-400 block mb-1">100% Client-Side Privacy</strong>
290291
All tools in the hub operate entirely within your browser memory. Even if you disconnect from the internet, your files are processed locally and never uploaded to any cloud server.

src/components/A11yScorecard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ export default function A11yScorecard() {
249249
{ label: 'Normal Text (AAA)', req: 7.0 },
250250
{ label: 'Large Text (AAA)', req: 4.5 },
251251
].map((tier, i) => (
252-
<div key={i} className="flex flex-col items-center p-3 rounded-xl bg-zinc-950 border border-zinc-800/50 w-32">
252+
<div key={i} className="flex flex-col items-center p-3 rounded-xl bg-zinc-950 border border-zinc-800/50 w-full">
253253
<div className="text-xs text-zinc-500 font-semibold mb-2 text-center h-8">{tier.label}</div>
254254
{contrast >= tier.req ? (
255255
<div className="bg-green-500/10 text-green-400 px-3 py-1 rounded-full text-xs font-bold border border-green-500/20 flex items-center gap-1">

src/components/Footer.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import React from 'react';
2+
import { useRouter } from '../App';
23

34
export const Footer = () => {
5+
const { navigate } = useRouter();
46
return (
57
<footer className="w-full bg-[#09090b] border-t border-zinc-800/50 py-8 mt-12">
68
<div className="max-w-7xl mx-auto px-4 md:px-8">
@@ -15,10 +17,10 @@ export const Footer = () => {
1517
</div>
1618

1719
<div className="flex flex-wrap items-center justify-center md:justify-end gap-x-6 gap-y-2 text-sm font-medium text-zinc-400">
18-
<a href="/about-us" className="hover:text-zinc-200 transition-colors">About</a>
19-
<a href="/privacy-policy" className="hover:text-zinc-200 transition-colors">Privacy Policy</a>
20-
<a href="/terms-of-service" className="hover:text-zinc-200 transition-colors">Terms of Service</a>
21-
<a href="/contact-us" className="hover:text-zinc-200 transition-colors">Contact</a>
20+
<a href="/about-us" onClick={(e) => { e.preventDefault(); navigate('/about-us'); }} className="hover:text-zinc-200 transition-colors">About</a>
21+
<a href="/privacy-policy" onClick={(e) => { e.preventDefault(); navigate('/privacy-policy'); }} className="hover:text-zinc-200 transition-colors">Privacy Policy</a>
22+
<a href="/terms-of-service" onClick={(e) => { e.preventDefault(); navigate('/terms-of-service'); }} className="hover:text-zinc-200 transition-colors">Terms of Service</a>
23+
<a href="/contact-us" onClick={(e) => { e.preventDefault(); navigate('/contact-us'); }} className="hover:text-zinc-200 transition-colors">Contact</a>
2224
<button
2325
className="google-privacy-options hover:text-zinc-200 transition-colors text-xs opacity-80 border-t border-zinc-800 md:border-none pt-2 md:pt-0 w-full md:w-auto text-center md:text-left mt-2 md:mt-0"
2426
onClick={(e) => {

src/components/WatermarkPdf.tsx

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export default function WatermarkPdf() {
1515
const [opacity, setOpacity] = useState('0.3');
1616
const [fontSize, setFontSize] = useState('60');
1717
const [color, setColor] = useState('#6b7280');
18+
const [align, setAlign] = useState('center');
1819

1920
const fileInputRef = useRef<HTMLInputElement>(null);
2021

@@ -79,9 +80,19 @@ export default function WatermarkPdf() {
7980
const textWidth = helveticaFont.widthOfTextAtSize(watermarkText, size);
8081
const textHeight = helveticaFont.heightAtSize(size);
8182

83+
const padding = 50;
84+
let x = width / 2 - textWidth / 2;
85+
let y = height / 2 - textHeight / 2;
86+
87+
if (align.includes('left')) x = padding;
88+
else if (align.includes('right')) x = width - textWidth - padding;
89+
90+
if (align.includes('top')) y = height - textHeight - padding;
91+
else if (align.includes('bottom')) y = padding;
92+
8293
page.drawText(watermarkText, {
83-
x: width / 2 - textWidth / 2,
84-
y: height / 2 - textHeight / 2,
94+
x,
95+
y,
8596
size,
8697
font: helveticaFont,
8798
color: textColor,
@@ -220,6 +231,25 @@ export default function WatermarkPdf() {
220231
</div>
221232
</div>
222233

234+
<div>
235+
<label className="block text-sm font-medium text-zinc-400 mb-2">Placement</label>
236+
<div className="grid grid-cols-3 gap-1.5 p-2 bg-zinc-800/50 rounded-xl border border-zinc-700 w-32 aspect-square mb-6">
237+
{[
238+
'top-left', 'top-center', 'top-right',
239+
'middle-left', 'center', 'middle-right',
240+
'bottom-left', 'bottom-center', 'bottom-right'
241+
].map(p => (
242+
<button
243+
key={p}
244+
onClick={() => setAlign(p)}
245+
disabled={!file}
246+
className={`w-full h-full rounded border transition-colors ${align === p ? 'bg-orange-500 border-orange-500 shadow-md shadow-orange-500/30' : 'bg-zinc-700/50 border-zinc-600 hover:bg-zinc-600'} disabled:opacity-50`}
247+
title={p.replace('-', ' ')}
248+
/>
249+
))}
250+
</div>
251+
</div>
252+
223253
<div>
224254
<div className="flex justify-between items-center mb-2">
225255
<label className="text-sm font-medium text-zinc-400">Opacity: {parseFloat(opacity) * 100}%</label>

src/pages/SafeZoneTool.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -260,11 +260,11 @@ export default function SafeZoneTool({ onBack }: { onBack: () => void }) {
260260

261261

262262
return (
263-
<div className="flex flex-col min-h-screen bg-[#09090b] text-white font-sans selection:bg-blue-500/30 overflow-x-hidden overflow-y-auto pb-12">
264-
<div className="flex flex-col-reverse md:flex-row h-[100dvh] w-full flex-shrink-0">
263+
<div className="flex flex-col min-h-screen bg-[#09090b] text-white font-sans selection:bg-blue-500/30 overflow-x-hidden pb-12">
264+
<div className="flex flex-col md:flex-row min-h-[100dvh] w-full">
265265

266266
{/* Left Sidebar - Controls */}
267-
<aside className="w-full md:w-80 flex-shrink-0 border-t md:border-t-0 md:border-r border-[#27272a] bg-[#18181b] flex flex-col h-[65dvh] md:h-full z-20 shadow-2xl relative">
267+
<aside className="w-full md:w-80 flex-shrink-0 border-t md:border-t-0 md:border-r border-[#27272a] bg-[#18181b] flex flex-col z-20 shadow-2xl relative order-2 md:order-1">
268268
<div className="p-3 md:p-5 border-b border-[#27272a]">
269269
<div className="flex items-center justify-between mb-2 md:mb-4">
270270
<button onClick={onBack} className="text-xs font-semibold text-zinc-400 hover:text-zinc-200 uppercase tracking-wider flex items-center gap-1.5 transition-colors bg-zinc-800/50 hover:bg-zinc-700 px-3 py-1.5 rounded-full border border-zinc-700">
@@ -457,8 +457,8 @@ export default function SafeZoneTool({ onBack }: { onBack: () => void }) {
457457
</div>
458458
</aside>
459459

460-
<main className="flex-1 relative flex flex-col bg-zinc-950 overflow-hidden border-b border-zinc-800 md:border-none md:h-full">
461-
<div className="absolute top-0 left-0 right-0 p-3 md:p-4 flex justify-between items-center z-10 pointer-events-none">
460+
<main className="flex-1 relative flex flex-col bg-zinc-950 overflow-hidden border-b border-zinc-800 md:border-none h-[50dvh] md:h-auto min-h-[400px] order-1 md:order-2">
461+
<div className="absolute top-0 left-0 right-0 p-3 md:p-4 flex justify-between items-center z-50 pointer-events-none">
462462
<div className="pointer-events-auto bg-zinc-900/80 backdrop-blur-md border border-[#27272a] rounded-full px-3 py-1.5 md:px-4 md:py-2 flex items-center gap-2 md:gap-3 shadow-xl transform scale-90 md:scale-100 origin-top-left">
463463
<div className="w-2 h-2 rounded-full bg-emerald-500 shadow-[0_0_10px_rgba(16,185,129,0.8)] animate-pulse"></div>
464464
<span className="text-xs font-medium text-zinc-300 uppercase tracking-wider">Live Preview</span>

0 commit comments

Comments
 (0)