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
@@ -14,7 +14,6 @@ import { PageTitle } from '../components/PageTitle'
|
||||
import { ImageCropper } from '../components/ImageCropper'
|
||||
import { MultiSelectDropdown } from '../components/MultiSelectDropdown'
|
||||
import { RichTextEditor } from '../components/RichTextEditor'
|
||||
import { Switch } from '../components/Switch'
|
||||
import { useToast } from '../context/ToastContext'
|
||||
import { useT } from '../i18n/useT'
|
||||
import { ApiError } from '../lib/api'
|
||||
@@ -83,7 +82,8 @@ export function BusinessProfilePage() {
|
||||
const [logoMediaId, setLogoMediaId] = useState<string | null>(null)
|
||||
const [logoDark, setLogoDark] = useState<string | null>(null)
|
||||
const [logoDarkMediaId, setLogoDarkMediaId] = useState<string | null>(null)
|
||||
const [logoModeDark, setLogoModeDark] = useState(false)
|
||||
const [favicon, setFavicon] = useState<string | null>(null)
|
||||
const [faviconMediaId, setFaviconMediaId] = useState<string | null>(null)
|
||||
const [addresses, setAddresses] = useState<AddressDraft[]>([createEmptyAddressItem()])
|
||||
const [phoneNumbers, setPhoneNumbers] = useState<BusinessPhoneNumber[]>([
|
||||
createEmptyPhone(),
|
||||
@@ -159,6 +159,10 @@ export function BusinessProfilePage() {
|
||||
setLogoMediaId(profileData.profile.logoMediaId)
|
||||
setLogoDark(profileData.profile.logoDarkUrl)
|
||||
setLogoDarkMediaId(profileData.profile.logoDarkMediaId)
|
||||
setFavicon(
|
||||
profileData.profile.faviconMediaId ? profileData.profile.faviconUrl : null,
|
||||
)
|
||||
setFaviconMediaId(profileData.profile.faviconMediaId)
|
||||
|
||||
const nextAddresses =
|
||||
profileData.addresses.length > 0
|
||||
@@ -284,6 +288,11 @@ export function BusinessProfilePage() {
|
||||
'business-logo-dark.png',
|
||||
logoDarkMediaId,
|
||||
)
|
||||
const nextFaviconMediaId = await resolveDataUrlToMediaId(
|
||||
favicon,
|
||||
'business-favicon.png',
|
||||
faviconMediaId,
|
||||
)
|
||||
|
||||
const payloadAddresses = addresses
|
||||
.filter(
|
||||
@@ -321,6 +330,7 @@ export function BusinessProfilePage() {
|
||||
socialMedia,
|
||||
logoMediaId: nextLogoMediaId,
|
||||
logoDarkMediaId: nextLogoDarkMediaId,
|
||||
faviconMediaId: nextFaviconMediaId,
|
||||
categoryIds,
|
||||
addresses: payloadAddresses,
|
||||
})
|
||||
@@ -368,29 +378,12 @@ export function BusinessProfilePage() {
|
||||
<section className={styles.section}>
|
||||
<h3 className={styles.sectionTitle}>{t('bizProfile.section.basic')}</h3>
|
||||
<div className={formStyles.formGrid}>
|
||||
<div className={`${formStyles.field} ${styles.logoCol}`}>
|
||||
<label>{t('bizProfile.logo')}</label>
|
||||
<div className={styles.logoModeRow}>
|
||||
<span
|
||||
className={`${styles.logoModeLabel} ${!logoModeDark ? styles.logoModeLabelActive : ''}`}
|
||||
>
|
||||
{t('bizProfile.logo.light')}
|
||||
</span>
|
||||
<Switch
|
||||
checked={logoModeDark}
|
||||
onChange={setLogoModeDark}
|
||||
aria-label={t('bizProfile.logo.modeSwitch')}
|
||||
/>
|
||||
<span
|
||||
className={`${styles.logoModeLabel} ${logoModeDark ? styles.logoModeLabelActive : ''}`}
|
||||
>
|
||||
{t('bizProfile.logo.dark')}
|
||||
</span>
|
||||
</div>
|
||||
<div className={`${formStyles.field} ${styles.logoLightCol}`}>
|
||||
<label className={styles.mediaFieldLabel}>{t('bizProfile.logo.lightTheme')}</label>
|
||||
<ImageCropper
|
||||
key={logoModeDark ? 'logo-dark' : 'logo-light'}
|
||||
value={logoModeDark ? logoDark : logo}
|
||||
onChange={logoModeDark ? setLogoDark : setLogo}
|
||||
compact
|
||||
value={logo}
|
||||
onChange={setLogo}
|
||||
outputFormat="png"
|
||||
accept="image/png"
|
||||
uploadLabel={t('bizProfile.logo.upload')}
|
||||
@@ -399,6 +392,34 @@ export function BusinessProfilePage() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={`${formStyles.field} ${styles.logoDarkCol}`}>
|
||||
<label className={styles.mediaFieldLabel}>{t('bizProfile.logo.darkTheme')}</label>
|
||||
<ImageCropper
|
||||
compact
|
||||
value={logoDark}
|
||||
onChange={setLogoDark}
|
||||
outputFormat="png"
|
||||
accept="image/png"
|
||||
uploadLabel={t('bizProfile.logo.upload')}
|
||||
hint={t('bizProfile.logo.hint')}
|
||||
changeLabel={t('bizProfile.logo.change')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={`${formStyles.field} ${styles.faviconCol}`}>
|
||||
<label className={styles.mediaFieldLabel}>{t('bizProfile.favicon')}</label>
|
||||
<ImageCropper
|
||||
compact
|
||||
value={favicon}
|
||||
onChange={setFavicon}
|
||||
outputFormat="png"
|
||||
accept="image/png"
|
||||
uploadLabel={t('bizProfile.favicon.upload')}
|
||||
hint={t('bizProfile.favicon.hint')}
|
||||
changeLabel={t('bizProfile.favicon.change')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles.basicAside}>
|
||||
<div className={`${formStyles.field} ${styles.fullRow}`}>
|
||||
<label htmlFor="activity-categories">{t('bizProfile.categories')}</label>
|
||||
|
||||
Reference in New Issue
Block a user