Skip to content

Commit

Permalink
Feat/search dropdown live (#58)
Browse files Browse the repository at this point in the history
* test search dropdown live

* working searchbar

* live SearchDropdown

* live SearchDropdown wip

* live SearchDropdown wip

---------

Co-authored-by: Lucanis <[email protected]>
  • Loading branch information
Neox63 and Lucanis authored Sep 20, 2024
1 parent cf94b51 commit 4fb24e3
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 50 deletions.
8 changes: 4 additions & 4 deletions base.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1"/>
{% block meta %}{% endblock %}
<meta name="viewport" content="width=device-width, initial-scale=1"/> {% block meta %}{% endblock %}
<title>
{% block title %}Welcome!{% endblock %}
{% block title %}Welcome!
{% endblock %}
</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫️</text><text y=%221.3em%22 x=%220.2em%22 font-size=%2276%22 fill=%22%23fff%22>sf</text></svg>">
{% block stylesheets %}
Expand All @@ -17,7 +17,7 @@
</head>
<body class="no-js">
{% block header %}
{% include '@components/Layout/Header/Header.html.twig' %}
{% include '@components/Layout/Header/Header.html.twig' with { type: "searchbar" } %}
{% endblock %}

{% block body %}{% endblock %}
Expand Down
38 changes: 18 additions & 20 deletions components/Layout/Header/Header.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,31 @@
<div class='flex'>
{% if type == "searchbar" %}
<div class='hidden lg:block xl:hidden'>
{% include '@components/Molecules/HeaderButton/HeaderButton.html.twig' with {icon: 'menu', text: 'Cart', classes: 'HeaderButton--light', small: true } %}
{% include '@components/Molecules/HeaderButton/HeaderButton.html.twig' with {icon: 'menu', text: 'Cart', classes: 'HeaderButton--light', small: true } %}
</div>
{% endif %}

<div class='flex items-center self-center h-full'>
<a href="/" class='Header-logo'>
{{ ux_icon('thelia') }}
</a>
{{ ux_icon('thelia') }}
</a>
</div>
</div>

{% if type == "searchbar" %}
<div class='w-[500px] 2xl:w-[800px] hidden lg:flex items-stretch flex-col justify-center absolute top-1/2 left-1/2 -translate-y-1/2 -translate-x-1/2'>
{% include '@components/Molecules/SearchBar/SearchBar.html.twig' %}
</div>
{{ component('Flexy:SearchBar') }}
{% else %}
<nav id="Menu">
<button type="button" data-menu-back="-1">
{{ ux_icon('arrow-left') }}
</button>
{{ ux_icon('arrow-left') }}
</button>
<button type="button" data-menu-close>
{{ ux_icon('close') }}
</button>
{{ ux_icon('close') }}
</button>
<ul class="Header-navigation" data-menu-sub="0">
{% for category in categories %}
{% include '@components/Molecules/ItemHeader/ItemHeader.html.twig' with { customText: category.i18ns.title, href: category.publicUrl} %}
{% endfor %}
{% for category in categories %}
{% include '@components/Molecules/ItemHeader/ItemHeader.html.twig' with { customText: category.i18ns.title, href: category.publicUrl} %}
{% endfor %}
</ul>
</nav>
{% endif %}
Expand All @@ -41,15 +39,15 @@
{% if type == "searchbar" %}
<nav id="Menu" class='Header-navWrap'>
<button type="button" data-menu-back="-1">
{{ ux_icon('arrow-left') }}
</button>
{{ ux_icon('arrow-left') }}
</button>
<button type="button" data-menu-close>
{{ ux_icon('close') }}
</button>
{{ ux_icon('close') }}
</button>
<ul class="Header-navigation">
{% for category in categories %}
{% include '@components/Molecules/ItemHeader/ItemHeader.html.twig' with { customText: category.i18ns.title, href: category.publicUrl} %}
{% endfor %}
{% for category in categories %}
{% include '@components/Molecules/ItemHeader/ItemHeader.html.twig' with { customText: category.i18ns.title, href: category.publicUrl} %}
{% endfor %}
</ul>
</nav>
{% endif %}
57 changes: 51 additions & 6 deletions components/Molecules/SearchBar/SearchBar.html.twig
Original file line number Diff line number Diff line change
@@ -1,10 +1,55 @@
{% set type = type|default('classic') %} {# type: 'classic'|'white' #}
{% set type = type|default('classic') %}
{# type: 'classic'|'white' #}
{% set value = value|default('') %}

{% set classes = '' %}
{% if type != 'classic' %}{% set classes = classes ~ ' SearchBar--' ~ type %}{% endif %}
{% if type != 'classic' %}
{% set classes = classes ~ ' SearchBar--' ~ type %}
{% endif %}

<label class="SearchBar {{ classes }}" aria-label={{"Search"|trans}}>
<button class='w-4 h-4'>{{ ux_icon("search") }}</button>
<input type="text" name="query" placeholder={{"e.g. Shoes, T-shirts, ..."|trans}} autocomplete='off' value="{{ value }}"/>
</label>
<div {{ attributes }} class="w-[500px] 2xl:w-[800px] z-50 self-center">
<label class="SearchBar" aria-label={{"Search"|trans}}>
<button class='w-4 h-4'>{{ ux_icon("search") }}</button>
<input type="text" name="query" placeholder={{"e.g. Shoes, T-shirts, ..."|trans}} autocomplete='off' data-model="debounce(300)|query"/>
</label>

{% if this.products|length > 0 or this.categories|length > 0 %}
<div class="SearchDropdown">
<div class="SearchDropdown-results-grid">
<div class="mb-8 SearchDropdown-results-products">
<div class="mb-[14px] text-sm uppercase text-grey">
Produits
</div>

{% if this.products|length == 0 %}
<div class="font-medium">Aucun résultat pour cette recherche</div>
{% else %}
<div class="SearchDropdown-results">
{% for product in this.products %}
{% include '@components/Organisms/ProductCard/ProductCard.html.twig' with product %}
{% endfor %}
</div>
{% endif %}
</div>
<div class="mb-8 SearchDropdown-results-categories">
<div class="mb-[14px] uppercase text-grey text-sm">Catégories</div>

<div class="SearchDropdown-results">
<div class="SearchDropdown-results-categories-list">
{% for category in this.categories %}
<a href={{category.publicUrl}} class="underline" key={result.id}>
{{category.i18ns.title}}
</a>
{% endfor %}
</div>
</div>
</div>
{% if this.products|length > 4 %}
<a href="/search?query={{query}}" class="mx-auto mt-8 Button">
Voir tous les produits
</a>
{% endif %}
</div>
</div>
{% endif %}
</div>
71 changes: 71 additions & 0 deletions components/Molecules/SearchBar/searchBar.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
outline: 1px solid var(--grey-lighter);
border-radius: rem-convert(50px);
padding: 1rem 1.25rem;
z-index: 1000;

button {
margin-right: rem-convert(10px);
Expand Down Expand Up @@ -56,3 +57,73 @@
}
}
}

.SearchDropdown {
position: absolute;
top: var(--header-height);
padding-top: 35px;
padding-bottom: 59px;
width: 100vw;
left: 0;
z-index: 1000;
background-color: white;

&-results {
&-categories {
display: flex;
flex-direction: column;
@screen md {
padding-left: rem-convert(24px);
border-left: 1px solid var(--grey-lighter);
}

&-list {
display: flex;
flex-direction: column;
gap: rem-convert(24px);
}
}

&-products {
padding-left: rem-convert(24px);
}

&-grid {
display: grid;
grid-template-columns: 1fr;
@screen md {
grid-template-columns: 2fr 1fr;
}
}

--min-height-cartitem: rem-convert(50px);

display: grid;
grid-template-columns: repeat(1, 1fr);
gap: 0.5rem;

@screen sm {
grid-template-columns: repeat(2, 1fr);
}

.CartItem {
margin-top: 0;
padding: rem-convert(12px);
display: flex;
gap: 1rem;

&-img {
flex-shrink: 0;
max-width: 100px;
max-height: 100px;
}

&-contain {
display: flex;
flex-direction: column;
gap: rem-convert(10px);
justify-content: center;
}
}
}
}
41 changes: 21 additions & 20 deletions index.html.twig
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
{% extends 'base.html.twig' %}

{% block title %}index{% endblock %}
{% block title %}index
{% endblock %}

{% block body %}


{%
{%
set blocks = [
{
"image": asset("dist/images/placeholder.webp"),
Expand All @@ -31,22 +32,22 @@
]
%}

{% include '@components/Layout/Hero/Hero.html.twig' with { blocks: blocks } %}
{% include '@components/Layout/Hero/Hero.html.twig' with { blocks: blocks } %}

{{ component('Flexy:CrossSelling', {categoryId: 1, title: 'Last seen products' | trans}) }}
{{ component('Flexy:CrossSelling', {categoryId: 1, title: 'Last seen products' | trans}) }}


<div class="bg-theme-lighter">
{{ component('Flexy:CrossSelling', {categoryId: 2, title: 'Popular products' | trans}) }}
</div>
<div class="bg-theme-lightest">
{{ component('Flexy:CrossSelling', {categoryId: 3, title: 'Promotions' | trans}) }}
</div>
<div class="bg-theme-lighter">
{{ component('Flexy:CrossSelling', {categoryId: 2, title: 'Popular products' | trans}) }}
</div>
<div class="bg-theme-lightest">
{{ component('Flexy:CrossSelling', {categoryId: 3, title: 'Promotions' | trans}) }}
</div>

{{ component('Flexy:ProductCategory', {title: 'Our product categories' | trans}) }}
{{ component('Flexy:ProductCategory', {title: 'Our product categories' | trans}) }}


{%
{%
set reviews = [4,2,3]|map((note) => ({
author: 'Prénom N.',
review:"“Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.”",
Expand All @@ -55,22 +56,22 @@
}))
%}

<div class="bg-theme-lightest">
{% include '@components/Layout/Review/Review.html.twig' with {title: 'Our customers speak about us' | trans, reviews: reviews, button: {label: "See all reviews" | trans, href: "#"}} %}
</div>
<div class="bg-theme-lightest">
{% include '@components/Layout/Review/Review.html.twig' with {title: 'Our customers speak about us' | trans, reviews: reviews, button: {label: "See all reviews" | trans, href: "#"}} %}
</div>

{% set news = resources('/api/front/contents', {itemsPerPage:3}) %}
{% set news = resources('/api/front/contents', {itemsPerPage:3}) %}

{% set newsFiltered = news|map((n) => ({
{% set newsFiltered = news|map((n) => ({
title: n.i18ns.title,
date: n.createdAt|date("d/m/Y"),
url: '#',
img: {url: '/images/placeholder.webp', alt: n.i18ns.title}
}))
%}
<div class="bg-theme-lighter">
{% include '@components/Layout/SimilarContent/SimilarContent.html.twig' with {title: 'Our news' | trans, similarContents: newsFiltered, button: {label: "See all news" | trans, href: "#"}} %}
</div>
<div class="bg-theme-lighter">
{% include '@components/Layout/SimilarContent/SimilarContent.html.twig' with {title: 'Our news' | trans, similarContents: newsFiltered, button: {label: "See all news" | trans, href: "#"}} %}
</div>
{% endblock %}

{#<div class="font-bold sm:w-7/12">{{ format_money(number={$TOTAL_TAXED_AMOUNT}, currency_id=$CURRENCY) }}</div>#}
52 changes: 52 additions & 0 deletions src/Twig/SearchBar.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

/*
* This file is part of the Thelia package.
* http://www.thelia.net
*
* (c) OpenStudio <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace FlexyBundle\Twig;

use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
use Symfony\UX\LiveComponent\Attribute\LiveProp;
use Symfony\UX\LiveComponent\DefaultActionTrait;
use TwigEngine\Service\DataAccess\DataAccessService;

#[AsLiveComponent(template: '@components/Molecules/SearchBar/SearchBar.html.twig')]
class SearchBar
{
use DefaultActionTrait;

#[LiveProp(writable: true)]
public string $query = '';

private DataAccessService $dataAccessService;

public function __construct(DataAccessService $dataAccessService)
{
$this->dataAccessService = $dataAccessService;
}

public function getProducts(): array
{
if (empty($this->query)) {
return [];
}

return $this->dataAccessService->resources('/api/front/products', ['title' => $this->query, "limit" => 4]);
}

public function getCategories(): array
{
if (empty($this->query)) {
return [];
}

return $this->dataAccessService->resources('/api/front/categories', ['title' => $this->query, "limit" => 4]);
}
}

0 comments on commit 4fb24e3

Please sign in to comment.