Skip to content

2026 update#180

Open
juanArias8 wants to merge 28 commits intomainfrom
2026-update
Open

2026 update#180
juanArias8 wants to merge 28 commits intomainfrom
2026-update

Conversation

@juanArias8
Copy link
Contributor

@juanArias8 juanArias8 commented Mar 5, 2026

PR Type

Enhancement, Other


Description

  • Migrate SCSS/SASS to Tailwind CSS

  • Refactor ImagineMenu for better feature handling

  • Improve ImagineBase component structure

  • Normalize artwork titles from prompts

  • Simplify UI components and styling


Changes walkthrough 📝

Relevant files
Enhancement
8 files
ImagineMenu.tsx
Refactor feature rendering and improve UI handling             
+95/-178
UserCard.tsx
Improve avatar handling and convert to Tailwind                   
+19/-22 
[collectionId].tsx
Add error handling for images and convert to Tailwind       
+13/-12 
ImagineBase.tsx
Add topBar with ModelSelect and ImagineSettings                   
+15/-6   
ModelSelect.tsx
Improve model compatibility filtering and UI                         
+23/-18 
ArtworkForm.tsx
Add title normalization from prompt                                           
+12/-6   
ImagineInput.tsx
Move ImagineSettings to topBar and update styling               
+7/-8     
ArtworkCard.tsx
Move click handler to container div                                           
+3/-5     
Formatting
11 files
ImagineSettings.tsx
Convert SCSS styles to Tailwind classes                                   
+22/-23 
ImagineImageInput.tsx
Replace SCSS with Tailwind classes                                             
+16/-18 
about.tsx
Convert page styling to Tailwind classes                                 
+11/-12 
Navbar.tsx
Replace SCSS module with Tailwind classes                               
+8/-9     
HelpPrompt.tsx
Convert component styling to Tailwind                                       
+7/-9     
ArtworkDetails.tsx
Convert SCSS to Tailwind classes                                                 
+7/-8     
InputTextArea.tsx
Replace SCSS with Tailwind classes                                             
+6/-7     
UserProfile.tsx
Convert component styling to Tailwind                                       
+8/-9     
InputText.tsx
Replace SCSS with Tailwind classes                                             
+6/-9     
CollectionForm.tsx
Convert SCSS to Tailwind classes                                                 
+7/-8     
ImageGallery.tsx
Replace SCSS with Tailwind classes                                             
+6/-7     
Additional files
101 files
CLAUDE.md +171/-0 
docker-compose.yaml +5/-36   
Dockerfile +3/-13   
Brand.module.scss +0/-10   
Brand.tsx +1/-2     
Separator.module.scss +0/-19   
Separator.tsx +4/-5     
CircleLoader.module.scss +0/-37   
CircleLoader.tsx +3/-4     
Footer.module.scss +0/-54   
Footer.tsx +4/-5     
FullScreenLoader.module.scss +0/-11   
FullScreenLoader.tsx +1/-2     
AdminForm.module.scss +0/-22   
Auth.module.scss +0/-40   
Auth.tsx +3/-4     
LoginForm.module.scss +0/-28   
LoginForm.tsx +2/-3     
ResetForm.module.scss [link]   
ResetForm.tsx +3/-4     
ModelForm.module.scss +0/-22   
Navbar.module.scss +0/-133 
Navbar.tsx +4/-5     
MainLayout.module.scss +0/-17   
MainLayout.tsx +2/-3     
next.config.js +0/-4     
package.json +0/-1     
404.tsx +6/-7     
_app.tsx +1/-1     
_error.tsx +7/-7     
admins.tsx +1/-2     
models.tsx +1/-2     
_buttons.scss +0/-76   
_colors.scss +0/-62   
_media.scss +0/-77   
_variables.scss +0/-10   
_poppins.scss +0/-137 
_shared.scss +0/-93   
globals.css +199/-326
globals.css.map +0/-1     
globals.scss +0/-113 
Error.module.scss +0/-44   
Home.module.scss +0/-5     
tailwind.config.js +1/-0     
App.scss +0/-130 
Dockerfile +2/-12   
AppImage.module.scss +0/-48   
AppImage.tsx +3/-3     
ArtWorkList.module.scss +0/-32   
ArtWorkList.tsx +3/-4     
ArtworkActions.module.scss +0/-36   
ArtworkActions.tsx +3/-4     
ArtworkCard.module.scss +0/-43   
ArtworkCardDetails.module.scss +0/-53   
ArtworkCardDetails.tsx +3/-4     
ArtworkCreator.module.scss +0/-30   
ArtworkCreator.tsx +9/-9     
ArtworkDetails.module.scss +0/-95   
ArtworkForm.module.scss +0/-33   
ArtworkSelect.module.scss +0/-21   
ArtworkSelect.tsx +1/-2     
Auth.module.scss +0/-17   
Auth.tsx +3/-4     
LoginForm.module.scss +0/-28   
LoginForm.tsx +4/-5     
PrivateRoute.module.scss +0/-10   
PrivateRoute.tsx +1/-2     
RegisterForm.module.scss +0/-14   
RegisterForm.tsx +5/-5     
ResetForm.module.scss [link]   
ResetForm.tsx +3/-4     
Separator.module.scss +0/-19   
Separator.tsx +4/-5     
ToggleAuth.module.scss +0/-39   
ToggleAuth.tsx +4/-4     
CollectionArtWorks.module.scss +0/-30   
CollectionCard.module.scss +0/-60   
CollectionCard.tsx +12/-15 
CollectionForm.module.scss +0/-62   
CollectionSelect.module.scss +0/-7     
Collections.module.scss +0/-35   
Collections.tsx +4/-5     
ControlNetModelSelect.module.scss +0/-7     
CookiesConsent.module.scss +0/-68   
CookiesConsent.tsx +3/-4     
EditProfileForm.module.scss +0/-37   
EditProfileForm.tsx +5/-7     
Excalidraw.module.scss +0/-13   
Excalidraw.tsx +1/-2     
FAQ.module.scss +0/-61   
FAQ.tsx +5/-6     
Footer.module.scss +0/-53   
Footer.tsx +4/-5     
GalleryActions.module.scss +0/-5     
GalleryActions.tsx +1/-2     
HelpPrompt.module.scss +0/-27   
ImageGallery.module.scss +0/-50   
ImagePrompt.module.scss +0/-37   
ImagePrompt.tsx +2/-3     
ImagineBase.module.scss +0/-77   
Additional files not shown

Need help?
  • Type /help how to ... in the comments thread for any questions about PR-Agent usage.
  • Check out the documentation for more information.
  • juanArias8 and others added 19 commits March 5, 2026 01:33
    - add expiration parameter to generate_public_url method
    - replace static public URLs with presigned URLs in relevant methods
    - update logic to handle presigned URLs in filename parsing
    - modify S3 upload method to return file key instead of static URL
    - remove redundant onClick from AppImage component
    - add onClick to outer div for better event handling
    …issing
    
    - handle missing artwork title by normalizing prompt into a valid title
    - simplify null/undefined checks with optional chaining
    - replace ModelsAccordion with dynamic feature filtering and rendering
    - refactor mobile modal logic and active feature label
    - improve feature item rendering and icon styling with React.cloneElement
    - remove unused Model and features-related legacy code
    - move ImagineSettings and ModelSelect to topBar section
    - adjust ImagineMenu styles with margin-bottom addition
    - add topBar styles for alignment and spacing in ImagineBase
    - refactor ModelSelect initialization and enhance compatibility filtering
    - add triggerClassName support to InputSelect component
    …t and morpheus-admin
    
    Replace all SCSS module files with Tailwind inline classes, remove SASS
    dependencies and build configuration, and add typography color modifier
    classes to globals.css via @layer components. Fix visual regressions
    across auth forms, navbar, gallery, artwork cards, avatar fallbacks,
    and the about page to match original styling.
    
    Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
    …eus-server
    
    Eliminates the separate morpheus-data wheel package by moving all its
    code directly into morpheus-server. morpheus-worker was already independent.
    
    - Move models, schemas, repositories, registry, utils, and migrations
      into morpheus-server/app/ and morpheus-server/migrations/
    - Update all imports from morpheus_data.* to app.*
    - Flatten Settings inheritance into morpheus-server/app/config.py
    - Remove datalib service from docker-compose.yaml
    - Remove wheel build steps from both Dockerfiles
    - Add alembic.ini to morpheus-server; migrations now run via api service
    - Add diffusers to morpheus-server/requirements.txt (previously from wheel)
    - Update CLAUDE.md to reflect new structure
    
    Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
    …S3 uploads
    
    - Add @lru_cache to get_settings() to avoid re-reading env file on every call
    - Change default scheduler from DDPMScheduler to DPMSolverMultistepScheduler
      which converges at ~20 steps vs 50+, halving inference time
    - Reduce default num_inference_steps from 50 to 20
    - Parallelize S3 uploads with ThreadPoolExecutor so multi-image requests
      upload all results concurrently instead of sequentially
    
    Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
    …eloading
    
    Previously every request created a new ephemeral SD actor, which loaded the
    full model from disk on every generation (30-120s overhead per request).
    
    Now handlers call _get_or_create_generator() which looks up an actor by name
    in the 'morpheus' namespace. On the first request for a given model/pipeline
    combo the actor is created with lifetime='detached' so it persists. All
    subsequent requests reuse the warm actor and skip model loading entirely.
    
    Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
    …t startup
    
    Each SD actor now overrides _warmup() and runs a minimal 1-step pipeline
    inference with dummy inputs immediately after model load. This moves the
    CUDA JIT compilation overhead from the first real user request to actor
    startup, so the first actual generation is as fast as subsequent ones.
    
    Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
    …oyer pattern
    
    start.sh previously only ran 'ray start --block' without ever deploying Ray
    Serve, leaving port 8000 dead. A separate worker-ray-deployer container was
    supposed to fix this via 'ray job submit -- serve deploy models.yaml', but
    RAY_ADDRESS set in the deployer container is not forwarded into submitted
    Ray jobs, so serve deploy had no way to reach the Serve controller.
    
    Replace with: ray start (non-blocking) then serve run /opt/models.yaml which
    connects to the running cluster, deploys the app, and keeps the container
    alive. Also bump APIIngress to 2 replicas to handle concurrent requests.
    
    Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
    - delete `celery/config.py`, `mlmodels`, `utils`, and `tasks` modules
    - remove `daemon-set-workers-diffusion.yaml` and `daemon-set-workers-prompt.yaml` Helm templates
    - create main.css for defining Excalidraw-specific styles
    - add themes, color pickers, context menus, buttons, and dialog styles
    - optimize for dark and light themes, RTL support, and responsive design
    - add *-secrets.yaml and *secrets*.yaml to ignore patterns
    @pr-agent-monadical
    Copy link

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
    🧪 No relevant tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    Potential Feature Regression

    The refactored ImagineMenu component has removed feature descriptions that were previously shown in tooltips. This could impact user experience as new users may not understand what each feature does without these descriptions.

    const categoryConfigs = [
      {
        name: ModelCategory.Text2Image,
        title: "Text To Image",
        icon: <Text2ImgIcon height={"18px"} width={"18px"} />,
      },
      {
        name: ModelCategory.Image2Image,
        title: "Image to Image",
        icon: <Img2ImgIcon height={"18px"} width={"18px"} />,
      },
      {
        name: ModelCategory.Pix2Pix,
        title: "Pix2Pix",
        icon: <Pix2PixIcon height={"18px"} width={"18px"} />,
      },
      {
        name: ModelCategory.ControlNet,
        title: "ControlNet",
        icon: <ControlNetIcon height={"18px"} width={"18px"} />,
      },
      {
        name: ModelCategory.Inpainting,
        title: "In-painting",
        icon: <InpaintingIcon height={"18px"} width={"18px"} />,
      },
      {
        name: ModelCategory.Upscaling,
        title: "Upscaling",
        icon: <EnhanceIcon width={"18px"} height={"18px"} />,
      },
    ];

    Title Normalization
    The new title normalization logic strips special characters and truncates to 64 characters, which may result in unexpected title changes. Verify this behavior is intended and doesn't cause issues with existing artwork titles.

    Error Handling

    The new image error handling in UserImage component may cause recursive error events if the fallback image also fails to load. Consider adding a flag to prevent infinite error handling loops.

    <div className="w-10 min-w-[40px] max-w-[40px] h-10 min-h-[40px] max-h-[40px] cursor-pointer rounded-full flex justify-center items-center" style={getImageStyles()}>
      <img
        src={user.avatar || "/images/avatar.png"}
        alt="avatar"
        style={getImageStyles()}
        loading="lazy"
        className="w-full h-full rounded-full object-cover"
        onError={(e) => { (e.target as HTMLImageElement).src = "/images/avatar.png"; }}
      />

    Comment on lines 60 to 79
    useEffect(() => {
    if (!router.pathname.endsWith("paint")) {
    const currentModelSupportsFeature =
    selectedModel &&
    selectedModel.categories &&
    selectedModel.categories.some(
    (category) => category.name === imagineOptionPath
    );
    const currentModelSupportsFeature = selectedModel?.categories?.some(
    (c) => c.name === imagineOptionPath
    );

    if (currentModelSupportsFeature) {
    setActiveLink({
    model: selectedModel,
    feature: imagineOptionPath as ModelCategory,
    });
    } else {
    const compatibleModel = findValidModelForFeature(imagineOptionPath as ModelCategory);
    setActiveLink({
    model: findValidModelForFeature(imagineOptionPath as ModelCategory),
    model: compatibleModel,
    feature: imagineOptionPath as ModelCategory,
    });
    }
    }
    }, [imagineOptionPath]);

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Suggestion: The useEffect dependency array is missing several dependencies that are used within the effect: router.pathname, selectedModel, setActiveLink, and findValidModelForFeature. This can lead to stale closures and unexpected behavior when these dependencies change but the effect doesn't re-run. [possible issue, importance: 8]

    Suggested change
    useEffect(() => {
    if (!router.pathname.endsWith("paint")) {
    const currentModelSupportsFeature =
    selectedModel &&
    selectedModel.categories &&
    selectedModel.categories.some(
    (category) => category.name === imagineOptionPath
    );
    const currentModelSupportsFeature = selectedModel?.categories?.some(
    (c) => c.name === imagineOptionPath
    );
    if (currentModelSupportsFeature) {
    setActiveLink({
    model: selectedModel,
    feature: imagineOptionPath as ModelCategory,
    });
    } else {
    const compatibleModel = findValidModelForFeature(imagineOptionPath as ModelCategory);
    setActiveLink({
    model: findValidModelForFeature(imagineOptionPath as ModelCategory),
    model: compatibleModel,
    feature: imagineOptionPath as ModelCategory,
    });
    }
    }
    }, [imagineOptionPath]);
    useEffect(() => {
    if (!router.pathname.endsWith("paint")) {
    const currentModelSupportsFeature = selectedModel?.categories?.some(
    (c) => c.name === imagineOptionPath
    );
    if (currentModelSupportsFeature) {
    setActiveLink({
    model: selectedModel,
    feature: imagineOptionPath as ModelCategory,
    });
    } else {
    const compatibleModel = findValidModelForFeature(imagineOptionPath as ModelCategory);
    setActiveLink({
    model: compatibleModel,
    feature: imagineOptionPath as ModelCategory,
    });
    }
    }
    }, [imagineOptionPath, router.pathname, selectedModel, setActiveLink, findValidModelForFeature]);

    Comment on lines +25 to 34
    <div className="w-10 min-w-[40px] max-w-[40px] h-10 min-h-[40px] max-h-[40px] cursor-pointer rounded-full flex justify-center items-center" style={getImageStyles()}>
    <img
    src={user.avatar || "/images/avatar.png"}
    alt="avatar"
    style={getImageStyles()}
    loading="lazy"
    className="w-full h-full rounded-full object-cover"
    onError={(e) => { (e.target as HTMLImageElement).src = "/images/avatar.png"; }}
    />
    </div>

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Suggestion: The getImageStyles() function is called twice unnecessarily - once on the container div and once on the img element. Since the function is meant to style the image based on size, it should only be applied to the img element. [general, importance: 5]

    Suggested change
    <div className="w-10 min-w-[40px] max-w-[40px] h-10 min-h-[40px] max-h-[40px] cursor-pointer rounded-full flex justify-center items-center" style={getImageStyles()}>
    <img
    src={user.avatar || "/images/avatar.png"}
    alt="avatar"
    style={getImageStyles()}
    loading="lazy"
    className="w-full h-full rounded-full object-cover"
    onError={(e) => { (e.target as HTMLImageElement).src = "/images/avatar.png"; }}
    />
    </div>
    <div className="w-10 min-w-[40px] max-w-[40px] h-10 min-h-[40px] max-h-[40px] cursor-pointer rounded-full flex justify-center items-center">
    <img
    src={user.avatar || "/images/avatar.png"}
    alt="avatar"
    style={getImageStyles()}
    loading="lazy"
    className="w-full h-full rounded-full object-cover"
    onError={(e) => { (e.target as HTMLImageElement).src = "/images/avatar.png"; }}
    />
    </div>

    const [showModelsModal, setShowModelsModal] = useState(false);
    const [showMobileModal, setShowMobileModal] = useState(false);
    const { isMobile } = useWindowDimensions();
    const lastShownAlertRef = useRef<string | null>(null);

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Suggestion: The lastShownAlertRef is declared but never used in the component. This creates unnecessary code that could confuse other developers. If it's intended for future use, consider adding a comment or removing it until needed. [general, importance: 3]

    Suggested change
    const lastShownAlertRef = useRef<string | null>(null);
    // Remove the unused ref or add a comment explaining its future use
    // const lastShownAlertRef = useRef<string | null>(null);

    findValidModelForFeature,
    } = useModels();
    const { models, selectedModel, activeLink, setActiveLink, findValidModelForFeature } = useModels();
    const { showInfoAlert } = useToastContext();

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Suggestion: The showInfoAlert function is imported from the ToastContext but never used in the component. Unused imports can lead to code bloat and confusion. Remove it if it's not needed or add a comment explaining its intended future use. [general, importance: 3]

    Suggested change
    const { showInfoAlert } = useToastContext();
    // Remove the unused function or add a comment explaining its future use
    // const { showInfoAlert } = useToastContext();

    Comment on lines 28 to 43
    useEffect(() => {
    if (props.artwork && props.artwork.title) {
    if (props.artwork?.title) {
    setTitle({ value: props.artwork.title, validators: [] });
    } else if (props.artwork?.prompt?.prompt) {
    const normalized = props.artwork.prompt.prompt
    .replace(/[^a-zA-Z0-9 ]/g, " ")
    .replace(/\s+/g, " ")
    .trim()
    .slice(0, 64);
    setTitle({ value: normalized, validators: [] });
    }

    if (props.artwork && props.artwork.collection_id) {
    if (props.artwork?.collection_id) {
    setSelectedCollectionId(props.artwork.collection_id);
    }
    }, [props.artwork]);

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Suggestion: Add null/undefined checks for props.artwork before accessing its properties to prevent potential runtime errors. The current implementation only checks for specific properties but doesn't verify that the artwork object itself exists. [possible issue, importance: 7]

    Suggested change
    useEffect(() => {
    if (props.artwork && props.artwork.title) {
    if (props.artwork?.title) {
    setTitle({ value: props.artwork.title, validators: [] });
    } else if (props.artwork?.prompt?.prompt) {
    const normalized = props.artwork.prompt.prompt
    .replace(/[^a-zA-Z0-9 ]/g, " ")
    .replace(/\s+/g, " ")
    .trim()
    .slice(0, 64);
    setTitle({ value: normalized, validators: [] });
    }
    if (props.artwork && props.artwork.collection_id) {
    if (props.artwork?.collection_id) {
    setSelectedCollectionId(props.artwork.collection_id);
    }
    }, [props.artwork]);
    useEffect(() => {
    if (!props.artwork) return;
    if (props.artwork.title) {
    setTitle({ value: props.artwork.title, validators: [] });
    } else if (props.artwork?.prompt?.prompt) {
    const normalized = props.artwork.prompt.prompt
    .replace(/[^a-zA-Z0-9 ]/g, " ")
    .replace(/\s+/g, " ")
    .trim()
    .slice(0, 64);
    setTitle({ value: normalized, validators: [] });
    }
    if (props.artwork.collection_id) {
    setSelectedCollectionId(props.artwork.collection_id);
    }
    }, [props.artwork]);

    Comment on lines 25 to +31
    useEffect(() => {
    if (models && models.length > 0) {
    if (localSelectedModel && localSelectedModel !== selectedModel.name) {
    const selected = models.find(
    (m: Model) => m.name === localSelectedModel
    );
    setSelectedModel(selected as Model);
    }
    if (!localSelected || localSelected === selectedModel?.name) return;
    const model = models.find((m: Model) => m.name === localSelected);
    if (model) {
    setActiveLink({ model, feature: activeLink.feature });
    }
    }, [localSelectedModel]);
    }, [localSelected]);

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Suggestion: Add missing dependencies to the useEffect dependency array. The current implementation is missing models, selectedModel, activeLink, and setActiveLink which could lead to stale closures and unexpected behavior. [possible issue, importance: 8]

    Suggested change
    useEffect(() => {
    if (models && models.length > 0) {
    if (localSelectedModel && localSelectedModel !== selectedModel.name) {
    const selected = models.find(
    (m: Model) => m.name === localSelectedModel
    );
    setSelectedModel(selected as Model);
    }
    if (!localSelected || localSelected === selectedModel?.name) return;
    const model = models.find((m: Model) => m.name === localSelected);
    if (model) {
    setActiveLink({ model, feature: activeLink.feature });
    }
    }, [localSelectedModel]);
    }, [localSelected]);
    useEffect(() => {
    if (!localSelected || localSelected === selectedModel?.name) return;
    const model = models.find((m: Model) => m.name === localSelected);
    if (model) {
    setActiveLink({ model, feature: activeLink.feature });
    }
    }, [localSelected, models, selectedModel, activeLink, setActiveLink]);

    Comment on lines +40 to 45
    <div className="group overflow-hidden rounded-lg cursor-pointer relative hover:border hover:border-[#312E47]" style={initialStyles} onClick={handleClick}>
    {props.artwork?.image ? (
    <AppImage
    onClick={handleClick}
    src={props.artwork.image}
    alt={props.artwork.title}
    />

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Suggestion: The onClick handler has been removed from the AppImage component but not added to its parent div. This could cause click events to only work on the div's margins but not on the image itself. Add the onClick={handleClick} to the AppImage component to ensure clicks work properly. [possible issue, importance: 5]

    Suggested change
    <div className="group overflow-hidden rounded-lg cursor-pointer relative hover:border hover:border-[#312E47]" style={initialStyles} onClick={handleClick}>
    {props.artwork?.image ? (
    <AppImage
    onClick={handleClick}
    src={props.artwork.image}
    alt={props.artwork.title}
    />
    <div className="group overflow-hidden rounded-lg cursor-pointer relative hover:border hover:border-[#312E47]" style={initialStyles} onClick={handleClick}>
    {props.artwork?.image ? (
    <AppImage
    src={props.artwork.image}
    alt={props.artwork.title}
    onClick={handleClick}
    />

    Comment on lines 5 to 6
    const Page400 = () => {
    const router = useRouter();

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Suggestion: The component name Page400 doesn't match the HTTP status code for "Page Not Found" which should be 404. Rename the component to Page404 for consistency with the file name and HTTP status code. [general, importance: 8]

    Suggested change
    const Page400 = () => {
    const router = useRouter();

    Comment on lines +17 to +25
    <div className="w-[46%] h-[100px] flex flex-row border border-[#312E47] rounded-lg cursor-pointer max-md:w-full max-md:mb-3" onClick={handleCollectionClick}>
    <div className="w-[100px] h-[100px] object-cover rounded-2xl flex justify-center items-center">
    <img
    src={props.collection.image || "/images/avatar.png"}
    alt={"Collection Image"}
    loading="lazy"
    className="w-full h-full object-cover rounded-lg"
    onError={(e) => { (e.target as HTMLImageElement).src = "/images/avatar.png"; }}
    />

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Suggestion: There's a mismatch between the parent div's border radius (rounded-lg) and the image container's border radius (rounded-2xl). This creates an inconsistent UI where the image container has a different corner radius than its parent. Change the image container to use rounded-lg to match the parent. [general, importance: 6]

    Suggested change
    <div className="w-[46%] h-[100px] flex flex-row border border-[#312E47] rounded-lg cursor-pointer max-md:w-full max-md:mb-3" onClick={handleCollectionClick}>
    <div className="w-[100px] h-[100px] object-cover rounded-2xl flex justify-center items-center">
    <img
    src={props.collection.image || "/images/avatar.png"}
    alt={"Collection Image"}
    loading="lazy"
    className="w-full h-full object-cover rounded-lg"
    onError={(e) => { (e.target as HTMLImageElement).src = "/images/avatar.png"; }}
    />
    <div className="w-[46%] h-[100px] flex flex-row border border-[#312E47] rounded-lg cursor-pointer max-md:w-full max-md:mb-3" onClick={handleCollectionClick}>
    <div className="w-[100px] h-[100px] object-cover rounded-lg flex justify-center items-center">
    <img
    src={props.collection.image || "/images/avatar.png"}
    alt={"Collection Image"}
    loading="lazy"
    className="w-full h-full object-cover rounded-lg"
    onError={(e) => { (e.target as HTMLImageElement).src = "/images/avatar.png"; }}
    />

    juanArias8 and others added 8 commits March 11, 2026 22:58
    …draw package
    
    Remove the ~250-file vendored copy of Excalidraw from morpheus-client/excalidraw/
    and replace it with the official @excalidraw/excalidraw npm package (^0.18.0).
    
    - Add ExcalidrawCanvas component that wraps the package's Excalidraw component,
      exports the canvas as a PNG blob, and sets it as the img2img input via context
    - Simplify Excalidraw.tsx to just lazy-load ExcalidrawCanvas with next/dynamic
    - Remove excalidraw/main.css import from _app.tsx (package ships its own styles)
    - Remove excalidraw/ glob from tailwind.config.js content paths
    
    Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
    - update settings for Firebase credentials and storage configuration
    - implement FirebaseClient for managing Firebase Storage operations
    - add FirebaseImagesRepository to handle file repository operations
    - extend file repository handlers to support Firebase storage
    - pin accelerate to 0.34.2 to avoid circular import issue in 1.x
    - add pyopenssl>=23.0.0 for compatibility with cryptography>=40
    - add google-cloud-storage and google-auth for Google Cloud support
    - ignore common Python cache files and directories
    - add environment and secrets files to ignore list
    …requests
    
    - update logging for all SD actors to exclude image, palette_image, and mask fields
    - add generation timeout setting to prevent GPU hangs
    - implement actor eviction to free GPU memory for new models
    - switch storage client dynamically between S3 and Firebase
    - enhance logging by excluding sensitive fields and specifying timeout
    - throw descriptive error when blob fetch fails (e.g., due to CORS issues)
    - remove immutable and sass dependencies
    - update chokidar and source-map-js entries
    - add table listing URLs for frontend, admin panel, API, Ray Dashboard, and PGAdmin
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Projects

    None yet

    Development

    Successfully merging this pull request may close these issues.

    1 participant