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:
Alireza Hassani
2026-08-26 00:51:12 +03:30
co-authored by Cursor
parent 5e799eddf9
commit 468bb87fcf
8 changed files with 163 additions and 79 deletions
@@ -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;
}
+21 -11
View File
@@ -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 />