Improve podcast avatar display and info banner

- Avatar images now use full available width (max 280px, responsive)
- Auto-collapse info banner after 8 seconds
- Add 'Show tips' link to expand collapsed info
- Fix image sizing to use contain instead of cover for better visibility
This commit is contained in:
ajaysi
2026-03-31 20:13:24 +05:30
parent f737b24b49
commit d06ab77e60
2 changed files with 67 additions and 37 deletions

View File

@@ -160,17 +160,18 @@ export const AvatarSelector: React.FC<AvatarSelectorProps> = ({
{loadingBrandAvatar ? ( {loadingBrandAvatar ? (
<CircularProgress size={32} /> <CircularProgress size={32} />
) : avatarPreview && avatarPreview === brandAvatarFromDb ? ( ) : avatarPreview && avatarPreview === brandAvatarFromDb ? (
<Stack spacing={2} alignItems="center"> <Stack spacing={2} alignItems="center" sx={{ width: "100%", maxWidth: 280 }}>
<Box sx={{ position: "relative" }}> <Box sx={{ position: "relative", width: "100%" }}>
<Box <Box
component="img" component="img"
src={avatarPreviewBlobUrl || ""} src={avatarPreviewBlobUrl || ""}
alt="Selected Brand Avatar" alt="Selected Brand Avatar"
sx={{ sx={{
width: 160, width: "100%",
height: 160, height: "auto",
objectFit: "cover", maxHeight: 200,
borderRadius: 2.5, objectFit: "contain",
borderRadius: 2,
border: "2px solid #667eea", border: "2px solid #667eea",
boxShadow: "0 4px 12px rgba(102, 126, 234, 0.25)", boxShadow: "0 4px 12px rgba(102, 126, 234, 0.25)",
}} }}
@@ -203,16 +204,17 @@ export const AvatarSelector: React.FC<AvatarSelectorProps> = ({
</Stack> </Stack>
</Stack> </Stack>
) : brandAvatarFromDb ? ( ) : brandAvatarFromDb ? (
<Stack spacing={2} alignItems="center"> <Stack spacing={2} alignItems="center" sx={{ width: "100%", maxWidth: 280 }}>
<Box <Box
component="img" component="img"
src={brandAvatarBlobUrl || ""} src={brandAvatarBlobUrl || ""}
alt="Available Brand Avatar" alt="Available Brand Avatar"
sx={{ sx={{
width: 160, width: "100%",
height: 160, height: "auto",
objectFit: "cover", maxHeight: 200,
borderRadius: 2.5, objectFit: "contain",
borderRadius: 2,
border: "1.5px solid #e2e8f0", border: "1.5px solid #e2e8f0",
opacity: 0.8, opacity: 0.8,
filter: "grayscale(0.3)", filter: "grayscale(0.3)",
@@ -317,16 +319,17 @@ export const AvatarSelector: React.FC<AvatarSelectorProps> = ({
<Box> <Box>
{avatarFile && avatarPreview ? ( {avatarFile && avatarPreview ? (
<Stack spacing={2} alignItems="center" sx={{ bgcolor: "#f8fafc", borderRadius: 2, p: 2 }}> <Stack spacing={2} alignItems="center" sx={{ bgcolor: "#f8fafc", borderRadius: 2, p: 2 }}>
<Box sx={{ position: "relative", display: "inline-block" }}> <Box sx={{ position: "relative", display: "inline-block", width: "100%", maxWidth: 280 }}>
<Box <Box
component="img" component="img"
src={avatarPreviewBlobUrl || (avatarPreview.startsWith("data:") ? avatarPreview : "")} src={avatarPreviewBlobUrl || (avatarPreview.startsWith("data:") ? avatarPreview : "")}
alt="Selfie preview" alt="Selfie preview"
sx={{ sx={{
width: 160, width: "100%",
height: 160, height: "auto",
objectFit: "cover", maxHeight: 200,
borderRadius: 2.5, objectFit: "contain",
borderRadius: 2,
border: "2px solid #e2e8f0", border: "2px solid #e2e8f0",
boxShadow: "0 2px 8px rgba(15, 23, 42, 0.08)", boxShadow: "0 2px 8px rgba(15, 23, 42, 0.08)",
}} }}

View File

@@ -1,9 +1,11 @@
import React from "react"; import React, { useState, useEffect } from "react";
import { Stack, Alert, Typography, alpha } from "@mui/material"; import { Stack, Alert, Typography, alpha, IconButton, Collapse } from "@mui/material";
import { import {
Info as InfoIcon, Info as InfoIcon,
Refresh as RefreshIcon, Refresh as RefreshIcon,
AutoAwesome as AutoAwesomeIcon, AutoAwesome as AutoAwesomeIcon,
ExpandMore as ExpandMoreIcon,
ExpandLess as ExpandLessIcon,
} from "@mui/icons-material"; } from "@mui/icons-material";
import { PrimaryButton, SecondaryButton } from "../ui"; import { PrimaryButton, SecondaryButton } from "../ui";
@@ -20,26 +22,51 @@ export const CreateActions: React.FC<CreateActionsProps> = ({
canSubmit, canSubmit,
isSubmitting, isSubmitting,
}) => { }) => {
const [showInfo, setShowInfo] = useState(true);
useEffect(() => {
const timer = setTimeout(() => {
setShowInfo(false);
}, 8000);
return () => clearTimeout(timer);
}, []);
return ( return (
<Stack spacing={3.5}> <Stack spacing={2}>
{/* Info Banner */} {/* Collapsible Info Banner */}
<Alert <Collapse in={showInfo}>
severity="info" <Alert
icon={<InfoIcon sx={{ color: "#6366f1", fontSize: "1.125rem" }} />} severity="info"
sx={{ icon={<InfoIcon sx={{ color: "#6366f1", fontSize: "1.125rem" }} />}
background: alpha("#f0f4ff", 0.6), onClose={() => setShowInfo(false)}
border: "1px solid rgba(99, 102, 241, 0.15)", sx={{
borderRadius: 2, background: alpha("#f0f4ff", 0.6),
boxShadow: "0 1px 3px rgba(99, 102, 241, 0.08)", border: "1px solid rgba(99, 102, 241, 0.15)",
"& .MuiAlert-message": { borderRadius: 2,
width: "100%", boxShadow: "0 1px 3px rgba(99, 102, 241, 0.08)",
}, "& .MuiAlert-message": {
}} width: "100%",
> },
<Typography variant="body2" sx={{ fontSize: "0.875rem", color: "#475569", lineHeight: 1.6, fontWeight: 400 }}> }}
Podcast avatar Image is required, brand avatar is Default, you can choose existing images from asset library Or Upload your Picture. If not, AI Avatar will be generated automatically. >
</Typography> <Typography variant="body2" sx={{ fontSize: "0.875rem", color: "#475569", lineHeight: 1.6, fontWeight: 400 }}>
</Alert> Podcast avatar Image is required. Brand avatar is default. You can choose from asset library or upload your picture. If not, AI Avatar will be generated automatically.
</Typography>
</Alert>
</Collapse>
{!showInfo && (
<Stack direction="row" alignItems="center" spacing={1}>
<InfoIcon sx={{ fontSize: 16, color: "#6366f1" }} />
<Typography
variant="caption"
sx={{ color: "#6366f1", cursor: "pointer", "&:hover": { textDecoration: "underline" } }}
onClick={() => setShowInfo(true)}
>
Show tips
</Typography>
</Stack>
)}
<Stack direction="row" justifyContent="flex-end" spacing={1}> <Stack direction="row" justifyContent="flex-end" spacing={1}>
<SecondaryButton onClick={reset} startIcon={<RefreshIcon />}> <SecondaryButton onClick={reset} startIcon={<RefreshIcon />}>