Improve business profile branding uploads and super-admin link menus.
Show separate light/dark logo and favicon croppers in a compact grid, support favicon saves, and keep super-admin overflow dashboard links in English. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
5e799eddf9
commit
468bb87fcf
@@ -172,3 +172,45 @@
|
||||
.changeBtn:hover {
|
||||
background: rgba(var(--primary-rgb) / 0.08);
|
||||
}
|
||||
|
||||
.compact .preview,
|
||||
.compact .uploadZone,
|
||||
.compact .cropArea {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.compact .cropPanel {
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
margin-inline: 0;
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
.compact .changeBtn {
|
||||
align-self: stretch;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.compact .uploadZone {
|
||||
gap: 4px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.compact .hint {
|
||||
font-size: 10px;
|
||||
text-align: center;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.compact .changeBtn {
|
||||
display: flex;
|
||||
padding: 6px 10px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.compact .removeBtn {
|
||||
top: 4px;
|
||||
right: 4px;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ interface ImageCropperProps {
|
||||
uploadLabel?: string
|
||||
hint?: string
|
||||
changeLabel?: string
|
||||
/** Smaller upload/preview frame for narrow grid columns. */
|
||||
compact?: boolean
|
||||
}
|
||||
|
||||
export function ImageCropper({
|
||||
@@ -26,6 +28,7 @@ export function ImageCropper({
|
||||
uploadLabel,
|
||||
hint,
|
||||
changeLabel,
|
||||
compact = false,
|
||||
}: ImageCropperProps) {
|
||||
const t = useT()
|
||||
const resolvedUploadLabel = uploadLabel ?? t('products.form.thumbnailUpload')
|
||||
@@ -81,18 +84,25 @@ export function ImageCropper({
|
||||
|
||||
const isPortrait = aspect < 1
|
||||
const maxHeight = isPortrait ? 'min(360px, 42vh)' : 'min(280px, 36vh)'
|
||||
const frameStyle: React.CSSProperties = {
|
||||
aspectRatio: String(aspect),
|
||||
width: `min(100%, calc(${maxHeight} * ${aspect}))`,
|
||||
height: 'auto',
|
||||
maxHeight,
|
||||
minHeight: 0,
|
||||
marginInline: 'auto',
|
||||
alignSelf: 'center',
|
||||
}
|
||||
const frameStyle: React.CSSProperties = compact
|
||||
? {
|
||||
aspectRatio: String(aspect),
|
||||
width: '100%',
|
||||
height: 'auto',
|
||||
minHeight: 0,
|
||||
}
|
||||
: {
|
||||
aspectRatio: String(aspect),
|
||||
width: `min(100%, calc(${maxHeight} * ${aspect}))`,
|
||||
height: 'auto',
|
||||
maxHeight,
|
||||
minHeight: 0,
|
||||
marginInline: 'auto',
|
||||
alignSelf: 'center',
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
<div className={`${styles.wrapper} ${compact ? styles.compact : ''}`}>
|
||||
{value && !imageSrc && (
|
||||
<div className={styles.preview} style={frameStyle}>
|
||||
<img src={value} alt={resolvedUploadLabel} className={styles.previewImg} />
|
||||
@@ -109,7 +119,7 @@ export function ImageCropper({
|
||||
|
||||
{!value && !imageSrc && (
|
||||
<label className={styles.uploadZone} style={frameStyle}>
|
||||
<ImagePlus size={28} />
|
||||
<ImagePlus size={compact ? 20 : 28} />
|
||||
<span>{resolvedUploadLabel}</span>
|
||||
<span className={styles.hint}>{resolvedHint}</span>
|
||||
<input type="file" accept={accept} onChange={handleFile} hidden />
|
||||
|
||||
Reference in New Issue
Block a user