Repository: openfoodfacts/openfoodfacts-explorer
Pull request #429: fix: search page issue of cards showing in single column fixed
Author: login: heymitali
Labels: name: Lists of products
Created: 2025-04-04T14:12:54Z | Merged: 2025-04-15T16:48:49Z

### What
My last [PR#347](https://github.com/openfoodfacts/openfoodfacts-explorer/pull/347) got merged which improved the product card design on homepage. While following the discussion on threads, I realised that it also impacted the layout of search page. Before my changes it was single column but product cards were stretched to full width, and in my PR I have modified the card's width. Because of which it is leaving empty space at the right side of the layout, which is not correct.

So in this PR, I have made this one line change to fix the search cards layout. Sorry for this mess up! And since this is my mistake, I would like to fix this as soon as possible, so that it won't affect other developments going on in this project.

In this PR, I am not doing changes in any other design, my intension is to just fix this bug as soon as possible.

And Thanks for raising this here: https://github.com/openfoodfacts/openfoodfacts-explorer/issues/399#issuecomment-2777361415

### Screenshot

This is show search results were looking before my last PR #347 got merged. Observe that it was single column design initially.
<img width="1344" alt="Screenshot 2025-04-04 at 7 34 46 PM" src="https://github.com/user-attachments/assets/3bbf318a-2e36-4fa1-8adc-4b72f7eea615" />

Search Results after my last PR merged. After modifying product card width, it is leaving empty space on right side.
<img width="1340" alt="Screenshot 2025-04-04 at 7 33 52 PM" src="https://github.com/user-attachments/assets/6548eed7-00d9-4bc5-8514-452cc9928175" />

Search Results after current PR's fix:
<img width="1460" alt="Screenshot 2025-04-13 at 10 29 26 AM" src="https://github.com/user-attachments/assets/c39c2b06-22a7-4dfc-b10e-60462005da6b" />

Skeleton Loading is also fixed in this PR:

https://github.com/user-attachments/assets/5a6ebe79-f0fd-41e6-b629-227ebad98558

Fixes bug(s)
#399 




Diff:
diff --git a/src/lib/ui/SmallProductCard.svelte b/src/lib/ui/SmallProductCard.svelte
index 22b3e9ad9..d442bb48c 100644
--- a/src/lib/ui/SmallProductCard.svelte
+++ b/src/lib/ui/SmallProductCard.svelte
@@ -24,7 +24,7 @@
 
 <a
 	href={`/products/${product.code}`}
-	class="flex w-full justify-center"
+	class="flex justify-center"
 	class:pointer-events-none={navigating.to}
 >
 	<div
@@ -47,7 +47,7 @@
 				>
 					<img
 						src="/Placeholder.svg"
-						class="h-16 rounded-lg bg-transparent object-cover"
+						class="h-16 rounded-lg bg-transparent object-cover opacity-70 dark:invert"
 						alt="Product front"
 					/>
 				</div>
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
index 422514b9d..241205fce 100644
--- a/src/routes/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -185,7 +185,9 @@
 	</div>
 </div>
 
-<div class="container mx-auto my-2 flex flex-col gap-4 px-4 xl:max-w-6xl">
+<div
+	class="container mx-auto my-2 flex flex-col flex-wrap gap-4 px-4 md:flex-row md:justify-evenly"
+>
 	{@render children?.()}
 </div>
 
diff --git a/src/routes/products/search/+page.svelte b/src/routes/products/search/+page.svelte
index fe12a4c44..81b2f234b 100644
--- a/src/routes/products/search/+page.svelte
+++ b/src/routes/products/search/+page.svelte
@@ -15,48 +15,53 @@
 	}
 </script>
 
-{#await data.result}
-	{#each Array(5) as _, i (i)}
-		<div class="skeleton dark:bg-base-300 h-24 bg-white p-4 shadow-md"></div>
-	{/each}
-{:then result}
-	{#if result.count > 0}
-		{#each result.products as product (product.code)}
-			<SmallProductCard {product} />
+<div
+	class="mt-8 flex grid w-full grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 lg:gap-2 xl:grid-cols-3"
+>
+	{#await data.result}
+		{#each Array(5) as _, i (i)}
+			<div class="skeleton dark:bg-base-300 h-24 bg-white p-4 shadow-md"></div>
 		{/each}
+	{:then result}
+		{#if result.count > 0}
+			{#each result.products as product (product.code)}
+				<SmallProductCard {product} />
+			{/each}
+		{:else}
+			<div class="mt-8 text-center opacity-70">
+				<p>No products found</p>
+				<p>We couldn't find any products matching your search</p>
+			</div>
+		{/if}
+	{/await}
+</div>
+{#await data.result then result}
+	<div class="join my-8 justify-center">
+		{#if result.page > 1}
+			<a href={getPageUrl(page.url, 1)} class="btn join-item"> 1 </a>
+		{/if}
+		{#if result.page > 3}
+			<button class="btn btn-disabled join-item">...</button>
+		{/if}
 
-		<div class="join my-8 justify-center">
-			{#if result.page > 1}
-				<a href={getPageUrl(page.url, 1)} class="btn join-item"> 1 </a>
-			{/if}
-			{#if result.page > 3}
-				<button class="btn btn-disabled join-item">...</button>
-			{/if}
+		{#if result.page > 2}
+			<a href={getPageUrl(page.url, result.page - 1)} class="btn join-item">
+				{result.page - 1}
+			</a>
+		{/if}
 
-			{#if result.page > 2}
-				<a href={getPageUrl(page.url, result.page - 1)} class="btn join-item">
-					{result.page - 1}
-				</a>
-			{/if}
+		<button class="btn join-item btn-active">{result.page}</button>
 
-			<button class="btn join-item btn-active">{result.page}</button>
-
-			{#if result.total_pages > result.page + 1}
-				<a href={getPageUrl(page.url, result.page + 1)} class="btn join-item">{result.page + 1}</a>
-			{/if}
-			{#if result.total_pages > result.page + 2}
-				<button class="btn btn-disabled join-item">...</button>
-			{/if}
-			{#if result.total_pages > result.page}
-				<a href={getPageUrl(page.url, result.total_pages)} class="btn join-item">
-					{result.total_pages}
-				</a>
-			{/if}
-		</div>
-	{:else}
-		<div class="mt-8 text-center opacity-70">
-			<p>No products found</p>
-			<p>We couldn't find any products matching your search</p>
-		</div>
-	{/if}
+		{#if result.total_pages > result.page + 1}
+			<a href={getPageUrl(page.url, result.page + 1)} class="btn join-item">{result.page + 1}</a>
+		{/if}
+		{#if result.total_pages > result.page + 2}
+			<button class="btn btn-disabled join-item">...</button>
+		{/if}
+		{#if result.total_pages > result.page}
+			<a href={getPageUrl(page.url, result.total_pages)} class="btn join-item">
+				{result.total_pages}
+			</a>
+		{/if}
+	</div>
 {/await}


Reviews:
user: login: gemini-code-assist[bot]
body: Hello @heymitali, I'm Gemini Code Assist[^1]! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

## Summary of Changes
This pull request addresses an issue introduced in PR#347, where changes to the product card design on the homepage inadvertently affected the layout of the search page. Specifically, the product cards on the search page were not displaying correctly, leaving empty space on the right side of the layout. This PR introduces a one-line change to fix the search cards layout, ensuring they display correctly in a multi-column format on the search page.

### Highlights
* **Bug Fix**: Corrects the layout of product cards on the search page, resolving an issue introduced in a previous pull request.
* **Layout Adjustment**: Ensures product cards display in a multi-column format on the search page, preventing empty space on the right side of the layout.

### Changelog
* **src/routes/+layout.svelte**
  * Modified the main container class to include 'flex-wrap' and 'md:justify-evenly' to enable multi-column layout on medium-sized screens and above.


<details>

<summary><b>Using Gemini Code Assist</b></summary>
<br>

The full guide for Gemini Code Assist can be found on our [documentation page](https://developers.google.com/gemini-code-assist/docs/review-github-code), here are some quick tips.

<b>Invoking Gemini</b>

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either `/gemini <command>` or `@gemini-code-assist <command>`. Below is a summary of the supported commands.

Feature | Command | Description
--- | --- | ---
Code Review | `/gemini review` | Performs a code review for the current pull request in its current state.
Pull Request Summary | `/gemini summary` | Provides a summary of the current pull request in its current state.
Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments.
Help | `/gemini help` | Displays a list of available commands.

<b>Customization</b>

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a `.gemini/` folder in the base of the repository. Detailed instructions can be found [here](https://developers.google.com/gemini-code-assist/docs/customize-gemini-behavior-github).

<b>Limitations & Feedback</b>

Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with :thumbsup: and :thumbsdown: on @gemini-code-assist comments to provide feedback.

</details>

<b>You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the [Gemini Code Assist IDE Extension](https://cloud.google.com/products/gemini/code-assist).</b>


[^1]: Review the [Privacy Notices](https://policies.google.com/privacy), [Generative AI Prohibited Use Policy](https://policies.google.com/terms/generative-ai/use-policy), [Terms of Service](https://policies.google.com/terms), and learn how to configure Gemini Code Assist in GitHub [here](https://developers.google.com/gemini-code-assist/docs/review-github-code). Gemini can make mistakes, so double check it and [use code with caution](https://support.google.com/legal/answer/13505487).

---

> A layout amiss,
> A quick fix, a gentle kiss,
> Columns now align.


state: COMMENTED
author_association: NONE
submitted_at: 2025-04-04T14:13:03Z
user: login: gemini-code-assist[bot]
body: ## Code Review
The pull request addresses a layout issue on the search page caused by a previous PR. The provided screenshots clearly illustrate the problem and the solution. The change appears to be straightforward and effective.

### Merge Readiness
The pull request appears to be ready for merging. The provided fix addresses the layout issue effectively, and the author has provided clear context and justification for the change. I am unable to directly approve the pull request, and recommend that others review and approve this code before merging.
state: COMMENTED
author_association: NONE
submitted_at: 2025-04-04T14:13:10Z
user: login: VaiTon
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-13T16:46:02Z
user: login: heymitali
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-13T17:12:50Z

Review comments:
diff_hunk: @@ -182,7 +182,9 @@
 	</div>
 </div>
 
-<div class="container mx-auto my-2 flex flex-col gap-4 px-4 xl:max-w-6xl">
+<div
+	class="container mx-auto my-2 flex flex-col flex-wrap gap-4 px-4 md:flex-row md:justify-evenly"
+>
path: src/routes/+layout.svelte
user: login: gemini-code-assist[bot]
body: ![medium](https://img.shields.io/badge/priority-medium-yellow)

Consider adding a comment explaining why `flex-wrap` and `md:justify-evenly` are added here. This will help future developers understand the purpose of these classes and maintain the layout correctly. While the commit message and PR description do a good job of explaining the context, a brief comment in the code itself can be beneficial for long-term maintainability.

```
<!-- Added flex-wrap to allow cards to wrap on smaller screens and md:justify-evenly to distribute cards evenly on medium screens and above -->
<div
	class="container mx-auto my-2 flex flex-col flex-wrap gap-4 px-4 md:flex-row md:justify-evenly"
>
```
created_at: 2025-04-04T14:13:10Z
author_association: NONE
diff_hunk: @@ -15,48 +15,54 @@
 	}
 </script>
 
-{#await data.result}
-	{#each Array(5) as _, i (i)}
-		<div class="skeleton dark:bg-base-300 h-24 bg-white p-4 shadow-md"></div>
-	{/each}
-{:then result}
-	{#if result.count > 0}
-		{#each result.products as product (product.code)}
-			<SmallProductCard {product} />
-		{/each}
-
-		<div class="join my-8 justify-center">
-			{#if result.page > 1}
-				<a href={getPageUrl(page.url, 1)} class="btn join-item"> 1 </a>
-			{/if}
-			{#if result.page > 3}
-				<button class="btn btn-disabled join-item">...</button>
-			{/if}
+<div class="mt-8 flex w-full">
+	<div class="grid w-full grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 lg:gap-2 xl:grid-cols-3">
path: src/routes/products/search/+page.svelte
user: login: VaiTon
body: Why do we need two divs here? Can't we collapse?
created_at: 2025-04-13T16:46:02Z
author_association: MEMBER
diff_hunk: @@ -15,48 +15,54 @@
 	}
 </script>
 
-{#await data.result}
-	{#each Array(5) as _, i (i)}
-		<div class="skeleton dark:bg-base-300 h-24 bg-white p-4 shadow-md"></div>
-	{/each}
-{:then result}
-	{#if result.count > 0}
-		{#each result.products as product (product.code)}
-			<SmallProductCard {product} />
-		{/each}
-
-		<div class="join my-8 justify-center">
-			{#if result.page > 1}
-				<a href={getPageUrl(page.url, 1)} class="btn join-item"> 1 </a>
-			{/if}
-			{#if result.page > 3}
-				<button class="btn btn-disabled join-item">...</button>
-			{/if}
+<div class="mt-8 flex w-full">
+	<div class="grid w-full grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 lg:gap-2 xl:grid-cols-3">
path: src/routes/products/search/+page.svelte
user: login: heymitali
body: I just checked, two divs are not needed, I have merged these divs. pls check now.
created_at: 2025-04-13T17:12:50Z
author_association: MEMBER

PR comments:
user: login: vercel[bot]
created_at: 2025-04-04T14:13:04Z
body: @heymitali is attempting to deploy a commit to the **openfoodfacts** Team on [Vercel](https://vercel.com).

A member of the Team first needs to [authorize it](https://vercel.com/git/authorize?team=openfoodfacts&type=github&job=%7B%22headInfo%22%3A%7B%22sha%22%3A%22803b494a036c83cc6fca5a67c69fa84e1fb0e65d%22%7D%2C%22id%22%3A%22QmdNHXWX7qxi3Gaanq9z3Kkbxo54AZC8mb9wu5pF15nEeR%22%2C%22org%22%3A%22openfoodfacts%22%2C%22prId%22%3A429%2C%22repo%22%3A%22openfoodfacts-explorer%22%7D).


author_association: NONE
user: login: swastikCommits
created_at: 2025-04-04T15:10:04Z
body: Hi @heymitali, I apologize for interrupting, but I believe it would be beneficial to address this later. Currently, we are focused on discussing on fixing the UI for the landing page in issue #426. 

If this PR is merged without aligning with the logic and design of the landing page, it could create unnecessary burden on @VaiTon. Later on, someone else will have to adjust the Search page to match the landing page's logic/design.

In my opinion, it would be best to keep this PR in draft status for now. If we find that we are unable to implement the logic to fix the landing page, then you would be free to proceed with this PR.
author_association: CONTRIBUTOR
user: login: heymitali
created_at: 2025-04-04T15:36:18Z
body: The fix that I did in this PR is independent of UI design of landing page. This is just related to broken search page product list alignment which occurred due to my last merged PR as mentioned in PR description. That's way, I am fixing it in this PR.

@VaiTon what do you think?
author_association: MEMBER
user: login: akashshetty1997
created_at: 2025-04-04T15:51:52Z
body: @heymitali  hey one tip in dark mode placeholder isnt visible clearly you can add this `opacity-70 dark:invert` this will make it more visible . 

Before
![image](https://github.com/user-attachments/assets/6008e23c-0eeb-4328-80c2-8832b5194ba1)

After 
![image](https://github.com/user-attachments/assets/378ec11d-34cb-4798-a102-6f1c7ef4a6b9)

author_association: CONTRIBUTOR
user: login: heymitali
created_at: 2025-04-04T15:57:18Z
body: Great catch @akashshetty1997 ! Thanks a lot for suggestion, I will push the changes.
author_association: MEMBER
user: login: heymitali
created_at: 2025-04-05T07:33:06Z
body: I think the 'check for merge conflicts' step has a bug. The strange thing is that it’s showing a reference to another pull request and causing my pull request to fail. @teolemon can you please help in checking this. I am attaching screenshot for my PR's automation below.

Error message: "Issue #243 does not have label 'PR: ready to ship'. No need to remove."

![Screenshot 2025-04-05 at 12 59 30 PM](https://github.com/user-attachments/assets/16206e51-ef56-478e-93bf-d6813fbce0f6)

author_association: MEMBER
user: login: VaiTon
created_at: 2025-04-08T18:06:52Z
body: @heymitali 

I'm open to merging this PR, at least until we decide for the better.

Please rebase on main.
author_association: MEMBER
user: login: vercel[bot]
created_at: 2025-04-09T07:20:24Z
body: [vc]: #dYN2CG3aue8abNmMEMeLx1Cm7bJaVFQiJ4juCqivL+8=:eyJpc01vbm9yZXBvIjp0cnVlLCJ0eXBlIjoiZ2l0aHViIiwicHJvamVjdHMiOlt7Im5hbWUiOiJvcGVuZm9vZGZhY3RzLWV4cGxvcmVyIiwicm9vdERpcmVjdG9yeSI6bnVsbCwiaW5zcGVjdG9yVXJsIjoiaHR0cHM6Ly92ZXJjZWwuY29tL29wZW5mb29kZmFjdHMvb3BlbmZvb2RmYWN0cy1leHBsb3Jlci9iczRFNlczcktFWlJLZVU0cmR1OUQyMjRVNTgzIiwicHJldmlld1VybCI6Im9wZW5mb29kZmFjdHMtZXhwbG9yZXItZ2l0LWZvcmstaGV5bWl0YWxpLTYxOWEzOC1vcGVuZm9vZGZhY3RzLnZlcmNlbC5hcHAiLCJuZXh0Q29tbWl0U3RhdHVzIjoiREVQTE9ZRUQiLCJsaXZlRmVlZGJhY2siOnsicmVzb2x2ZWQiOjAsInVucmVzb2x2ZWQiOjAsInRvdGFsIjowLCJsaW5rIjoib3BlbmZvb2RmYWN0cy1leHBsb3Jlci1naXQtZm9yay1oZXltaXRhbGktNjE5YTM4LW9wZW5mb29kZmFjdHMudmVyY2VsLmFwcCJ9fV19
**The latest updates on your projects**. Learn more about [Vercel for Git ↗︎](https://vercel.link/github-learn-more)

| Name | Status | Preview | Comments | Updated (UTC) |
| :--- | :----- | :------ | :------- | :------ |
| **openfoodfacts-explorer** | ✅ Ready ([Inspect](https://vercel.com/openfoodfacts/openfoodfacts-explorer/bs4E6W3rKEZRKeU4rdu9D224U583)) | [Visit Preview](https://openfoodfacts-explorer-git-fork-heymitali-619a38-openfoodfacts.vercel.app) | 💬 [**Add feedback**](https://vercel.live/open-feedback/openfoodfacts-explorer-git-fork-heymitali-619a38-openfoodfacts.vercel.app?via=pr-comment-feedback-link) | Apr 13, 2025 5:46pm |


author_association: NONE
user: login: heymitali
created_at: 2025-04-09T07:21:46Z
body: @VaiTon I have merged this branch with main. Please check.
author_association: MEMBER
user: login: VaiTon
created_at: 2025-04-09T21:57:24Z
body: I see this right now, I guess the recent merge of #454 caused this

![immagine](https://github.com/user-attachments/assets/a9c30898-3986-4972-b787-b3444c94a09f)

author_association: MEMBER
user: login: swastikCommits
created_at: 2025-04-10T00:24:29Z
body: Yeah exactly that is what I pinpointed, the changes due to #454 might create an inconsistency in the search page.
Good for us, we can fix it here.
author_association: CONTRIBUTOR
user: login: heymitali
created_at: 2025-04-10T07:44:37Z
body: I have took latest merge with main. Also fixed card layout and shimmer UI bug caused by #454 
@VaiTon please check now.

Shimmer UI Bug (Before this PR changes):
<img width="1350" alt="Screenshot 2025-04-10 at 12 59 53 PM" src="https://github.com/user-attachments/assets/0624f843-ee30-4031-a6fb-47f69b7ac26c" />

Fixed Shimmer UI Bug (Current PR):
<img width="1508" alt="Screenshot 2025-04-10 at 12 58 41 PM" src="https://github.com/user-attachments/assets/63e09f38-e4b2-4911-a7f0-a68dbc782812" />

Card Layout on Search page is also fixed.
<img width="1508" alt="Screenshot 2025-04-10 at 1 12 35 PM" src="https://github.com/user-attachments/assets/eea3de4d-acd3-4f51-bb98-bde32095dea7" />
author_association: MEMBER
user: login: heymitali
created_at: 2025-04-12T16:51:32Z
body: @VaiTon can you please help in reviewing this PR.
author_association: MEMBER
user: login: VaiTon
created_at: 2025-04-13T17:35:25Z
body: @heymitali the pagination should not be at the same height of the products

![immagine](https://github.com/user-attachments/assets/42c15b8f-0fa3-461e-bd54-a3280fd45096)

author_association: MEMBER
user: login: heymitali
created_at: 2025-04-13T17:46:44Z
body: @VaiTon I have fixed it right away. This was because initially the pagination was part of parent div which contains all cards as well as pagination. And the pagination should be outside the card because of grid layout in parent div. I did the required changes in latest commit. Please check.

<img width="1501" alt="Screenshot 2025-04-13 at 11 11 54 PM" src="https://github.com/user-attachments/assets/d09c6d14-5a8e-44f6-92b0-99794b02ae3b" />
<img width="583" alt="Screenshot 2025-04-13 at 11 11 47 PM" src="https://github.com/user-attachments/assets/d42fbd34-0e74-4aa1-8634-185016ce4a9b" />

author_association: MEMBER