Import source: src/components/RightPanel/LogoSection
Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
@@ -0,0 +1,62 @@
|
|||||||
|
import { useRef } from 'react';
|
||||||
|
import { useQR } from '../../context/QRContext';
|
||||||
|
|
||||||
|
export function LogoSection() {
|
||||||
|
const { state, dispatch } = useQR();
|
||||||
|
const fileRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
|
const handleFile = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const file = e.target.files?.[0];
|
||||||
|
if (!file) return;
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = ev => dispatch({ type: 'SET_LOGO', payload: ev.target?.result as string });
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col gap-3">
|
||||||
|
<h3 className="text-[14px] font-semibold" style={{ color: 'var(--text-secondary)' }}>Logo</h3>
|
||||||
|
<input ref={fileRef} type="file" accept="image/*" onChange={handleFile} className="hidden" />
|
||||||
|
|
||||||
|
{state.logoDataUrl ? (
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<div className="w-12 h-12 rounded-[10px] overflow-hidden flex-shrink-0 border" style={{ borderColor: 'var(--border-sub)' }}>
|
||||||
|
<img src={state.logoDataUrl} alt="logo" className="w-full h-full object-contain" style={{ background: 'var(--bg-input)' }} />
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col gap-1.5 flex-1">
|
||||||
|
<button onClick={() => fileRef.current?.click()}
|
||||||
|
className="h-9 rounded-[9px] text-[13px] font-medium transition-colors"
|
||||||
|
style={{ background: 'var(--bg-elevated)', border: '1px solid var(--border-sub)', color: 'var(--text-secondary)', cursor: 'pointer' }}>
|
||||||
|
Change
|
||||||
|
</button>
|
||||||
|
<button onClick={() => dispatch({ type: 'SET_LOGO', payload: null })}
|
||||||
|
className="h-9 rounded-[9px] text-[13px] font-medium transition-colors"
|
||||||
|
style={{ background: 'rgba(239,68,68,0.08)', border: '1px solid rgba(239,68,68,0.2)', color: '#ef4444', cursor: 'pointer' }}>
|
||||||
|
Remove
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<button onClick={() => fileRef.current?.click()}
|
||||||
|
className="h-20 rounded-[12px] flex flex-col items-center justify-center gap-1.5 transition-all cursor-pointer group"
|
||||||
|
style={{ border: '2px dashed var(--border-sub)', background: 'var(--bg-card)' }}
|
||||||
|
onMouseEnter={e => (e.currentTarget.style.borderColor = '#7C6FE0')}
|
||||||
|
onMouseLeave={e => (e.currentTarget.style.borderColor = 'var(--border-sub)')}
|
||||||
|
>
|
||||||
|
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" style={{ color: 'var(--text-muted)' }}>
|
||||||
|
<rect x="1" y="1" width="20" height="20" rx="4" stroke="currentColor" strokeWidth="1.5"/>
|
||||||
|
<circle cx="7.5" cy="7.5" r="2" stroke="currentColor" strokeWidth="1.5"/>
|
||||||
|
<path d="M1 14l5-4 4 4 4-3 7 5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
<span className="text-[12px] font-medium" style={{ color: 'var(--text-muted)' }}>Upload logo image</span>
|
||||||
|
<span className="text-[11px]" style={{ color: 'var(--text-dim)' }}>PNG, SVG, WebP</span>
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
{state.logoDataUrl && (
|
||||||
|
<p className="text-[11px]" style={{ color: 'var(--text-dim)' }}>
|
||||||
|
Error correction raised to High (H) automatically.
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user