Next.js Project - Online Shop

M-am apucat spatamana aceasta de Redux si Next.js si doresc sa pun in practica informatiile pe care le-am acumultat pana in momentul de fata.

Am sa procedez ca la proiectul trecut Youtube Project Practice #challenge
Dar de data aceasta cred ca o sa fie putin mai complex. Nu am nici un design anume nici nu o sa stau sa fac unul de la 0 dar am sa arunc o privire la cateva magazine online si am sa le combin intr-un singur design.

Doresc sa adaug un global state dar nu stiu inca pentru ce am sa-l folosesc, am sa vad asta pe parcurs.
Am sa folosesc reduxjs/@toolkit pentru ca este recomandat in loc de redux.

Ca de obicei am sa pun codul pe github si cred ca am sa folosesc vercel pentru deployment.

Github: GitHub - cojoclaudiu/squareify
Vercel: https://squareify.vercel.app

Day 0
Pentru inceput:
-Project structure / Clean-up
-Eslint / Prettier / Husky

6 Likes

Day 1

Astazi am sa lucrez la prima pagina, mai mult la partea de structura, incerc sa fac codul cat mai modular, incerc sa fac componentele cat mai independente, la partea de CSS am sa incerc sa folosesc cat de mult pe parcursul proiectului mai mult variabile, nu am incercat pana acum dar vreau sa adaug cat mai putin cod cu media-query pentru fiecare componenta si sa adaug mai mult @media in fisierul cu globalVariables si doar sa schimb de acolo variabilele si directiain functie de rezolutie.

Dacă e un magazin, îți recomand să te uiți peste codul de la Storefront, poate prinzi ceva idei despre structură/organizare (chiar dacă e în vue, nu react).

2 Likes

Day 1 Update
Lucrez la structura primei pagini, un blueprint sa zicem.

Am lucrat la partea de Carousel si aici vreau sa detaliez putin, sincer la inceput in urma cu cateva luni habar nu aveam sa fac asta si ma tot gandeam cu as putea sa implementez treaba asta. Dupa ceva research am vazut ca multe site-uri se folosesc CSS, overflow hiddlen {bla bla bla :roll_eyes:}, schimba directia din CSS dinamic la fiecare click.

Eu nu am vrut sa fac overflow pentru ca nu vreau iteme ascunse airuea in html. Eu m-am folosit de metoda .slice() am creat context, provider, reducer folosindu-ma de React Hooks (nu am vrut sa-l adaug global reducer ca nu-i vad sensul deocamdata).
.slice() primeste default din context start si end (0,4) iar pe on click dau dispatch la increment sau decrement.

Codul este updatat pe gihub si live pe vercel:
Github: GitHub - cojoclaudiu/squareify
Vercel: https://squareify.vercel.app

What’s nex(js)?
Header / Footer / Navigation

La partea de navigare vreau sa creez pagini cu categorii si subcategorii.
Am sa incerc pentru fiecare categorie in parte sa folosesc un stil diferit de layout si probabil pagina produsului o sa fie comuna.

Day 2
Astazi am sa lucrez la prima pagina, vreau sa arate bine cu ocazia asta am sa invat si ceva Figma, acolo voi face imaginile pentru prima pagina. Am vazut ca se cauta destul de mult Figma cel putin in UK si de aceea am decis sa o folosesc in locul photoshop-ului.

Pe prima pagina cel putin pana am sa o termin textele/imaginile o sa fie hardcoded dar ma gandesc sa fac un database realtime in firebase si de acolo sa iau datele pentru prima pagina.

O sa ma cam incetineasca putin crearea imaginilor dar vreau sa le fac in asa fel incat sa fiu eu multumit de ele.

— maybe I’m crazy but I love CSS Grid

2 Likes

DAY 3
Am zis sa postez la finalul zilei pentru ca am lucrat la prima pagina toata ziua, am scris sters regandit ca sa arate cat de cat bine si sa fie usor pe partea de responsive.
Nu pare mult dar mi-a luat aproape toata ziua ca sa fac aceste modificari.

Imgur


Imgur
Imgur

Grid este THE shit, mi se pare că e un salt mai mare în organizarea layout-urilor decât a fost flexbox (față de float).

3 Likes

Day 4
Am avut un bug la carousel care mi-a dat ceva batai de cap si am cerut ajutor pe Discord in grupul de React. Acest bug m-a tinut in loc o parte buna din zi.

Day 5
Inca lucrez la aplicatie, am adaugat datele pe firebase, acolo ma folosesc de Realtime Database.
API-ul meu arat deocamdata asa:
https://nextify31-default-rtdb.europe-west1.firebasedatabase.app/store.json

Daca vreti sa aruncati o privire sa-mi da-ti niste sugestii ce trebuie sa mai adaug la acel API sau ce trebuie sa mai modific.

-Mai mult ca sigur trebuie sa adaug descriere pentru fiecare item
-Pentru imagini probabil o sa fie un array cu mai multe link-uri sau locatii din folder-ul public pentru ca deocamdata acolo sunt locate imaginile.

-Ma gandeam ca pentru fiecare categorie sa am cate un API diferit.

-Vreau sa creez si un formular unde se pot adauga iteme pentru fiecare categorie

-Acum am descoperit ca inca exista acel bug la carousel items:

Problema apare doar cand ajung la sfarsitul array-ului cu iteme

Poate reuseste cineva sa ma ajute sa gasesc solutia ca deja imi da foarte mari batai de cap

import { createContext, useReducer } from 'react';
import useWidth from '../hooks/useWidth';

export const CarouselViewContext = createContext({
  start: null,
  end: null,
});

const carouselViewReducer = (state, action) => {
  switch (action.type) {
    case 'increment':
      return { start: state.start + 1, end: state.end + 1 };
    case 'decrement':
      return { start: state.start - 1, end: state.end - 1 };
    default:
      return state;
  }
};

const CarouselViewProvider = ({ children }) => {
  const width = useWidth();

  function getNumItems(windowWidth) {
    if (windowWidth < 621) return 1;
    if (windowWidth < 921) return 2;
    if (windowWidth < 1240) return 3;
    return 4;
  }

  const [state, dispatch] = useReducer(carouselViewReducer, { start: 0 });
  const values = { start: state.start, end: state.start + getNumItems(width) };
  const value = { state: values, dispatch };
  return <CarouselViewContext.Provider value={value}>{children}</CarouselViewContext.Provider>;
};

export default CarouselViewProvider;

import { useContext } from 'react';
import {
  IoIosArrowDropleftCircle,
  IoIosArrowDroprightCircle,
  IoIosCloseCircle,
} from 'react-icons/io';
import useData from '../../../hooks/useData';
import { CarouselViewContext } from '../../../context/CarouselViewContext';
import CarouselButton from '../CarouselButton/CarouselButton';
import Item from '../Item/Item';

import styles from './CarouselItems.module.css';

export default function CarouselItems() {
  const { items } = useData();
  const { state, dispatch } = useContext(CarouselViewContext);
  const { start, end } = state;

  const dispatchIncrement = () => dispatch({ type: 'increment' });
  const dispatchDecrement = () => dispatch({ type: 'decrement' });

  return (
    <>
      <div className={styles.trendingContainer}>
        <h3 className={styles.trending}>Trending</h3>
        <div className={styles.buttonsContainer}>
          {start > 0 ? (
            <CarouselButton dispatch={dispatchDecrement} icon={<IoIosArrowDropleftCircle />} />
          ) : (
            <CarouselButton icon={<IoIosCloseCircle />} />
          )}
          {end < items.length ? (
            <CarouselButton dispatch={dispatchIncrement} icon={<IoIosArrowDroprightCircle />} />
          ) : (
            <CarouselButton icon={<IoIosCloseCircle />} />
          )}
        </div>
      </div>

      <div className={styles.itemsContainer}>
        {items?.slice(start, end).map((item) => (
          <Item
            key={item.id}
            name={item.name}
            url={`${item.category}/${item.subCategory}/${item.name
              .replace(/ /g, '-')
              .toLowerCase()}?i=${item.id}`}
            price={item.price}
            image={item.image}
            alt={item.title}
          />
        ))}
      </div>
    </>
  );
}

Am dat console.log(start, end) si end sare la 11 cand maresc fereastra. Nu stiu cat de bine ma exprim sau ma intelegesti dar m-a obosit destul de mult problema asta. Mai jos aveti un video ca sa intelegeti la ce ma refer.

Late edit:
Bug-ul a fost fixat, cineva de pe discord m-a ajuta cu solutia.

Day 6
Astazi am sa lucrez la structura paginii pentru produse
Vreau sa adaug dupa ce termin de structurat otinuni pentru editare, stergere si adaugare produse.

Imgur

Later edit:
Lucrez la prima pagina, fac un clean up major printre componente pentru ca se repeta foarte mult cod. Cred ca am sa si “re-band”-uriesc applicatia … schimbam nume / culori / logo pentru ca vizual eu nu sunt multumit de cum arata. Revin cu update major in aceasta seara sau maine.

Day 7
Astazi lucrez la optiunea de a aduga iteme in cart
Link-urile pentru iteme sunt cele din carosel.

2 Likes

Day 8
Astazi am lucrat putin la wishlist, se pot adauga iteme ca wishlist dar pagina cu iteme nu este gata.
Am lucrat la pagina cu produsele din cos, acum este si optiunea + -
Putin la pagina cosului cand esten goala afisaza o alta componenta

Acum am alt bug la carousel… treaba asta cu caroselul ma cam tine in loc de vreo 4 zile, pe canalul oficial de react este un channel carousel bug poate doreste cineva sa ma ajute sau cei care se pricep la react/js si vor sa ma ajute imi pot lasa mesaj sau sa posteze aici.

Imgur
Imgur
Imgur

Poate ar fi mai bine daca ai preciza si bug-ul si eventul liniile de cod unde s-ar afla.
Poti sa folosesti si tab-ul de Issue. Poate se gaseste un binevoitor sa faca un pull request.

Si sa spui cum le-ai rezolvat.

2 Likes

Incerc sa fac caroselul sa afiseze itemele responsive atunci cand se mareste si miceste fereastra.

Am create un context si context provider si eu trimit dimensiunile din context {start:0, end:4} catre o alta componenta.

folosesc start si el in metoda slice() care va afisa itemele bazate pe start si end.
Start si end cresc cu +1 respectiv -1 atunci cand dam click pe butoanele de navigare.

exemplu +1
start 1 end 5 → am un gap acolo de 4 care inseamna cate itememe sa afiseze si astea 4 iteme se afisaza cand fereastra este mai mare de 1240px.

Bun eu prima data am facut asa de exemplu


const showItems =(windowSize) => {
if(windowSize  < 1240) return 3 
if(windowsSize < 921) return 2
if(windowSize < 621) return 1
return 4
}

{start:0 end: showItems}

Deci pentru fiecare dimensiune imi trebuie end sa fie un anumit numar de iteme.

Nu știu dacă este bine să ai dimensiunile hard-coded. Gândește-te la o variantă care folosește cât mai mult CSS.

Eu aș jongla cu variabilele CSS.

în CSS:

:root {
  --size: 3
}
@media (min-width: 921px) {
  :root {
    --size: 3;
  }
}

Apoi poți accesa variabila CSS din JS:

var style = getComputedStyle(document.body)
console.log( style.getPropertyValue('--size') ) 
1 Like

Probabil o sa ma gandesc sa implementez ce ai zis si tu dar atat timp cat nu functioneaza cum trebuie in varianta asta nu o sa mearga nici cu css.

Edit: Am sa incerc main varianta ta @iamntz foarte interesanta si nici nu stiam de ea. Daca nu ma ajuta la carousel sigur ma va ajuta in viitor.

Day 9
Scuzati-mi absenta din ultimele zile dar a trebuit sa lucrez la alt proiect.

Revin cu update pentru ziua a 9a pe proiect:
Astazi am reusit sa fixez bug de la carousel si am adaugat redux-persist.

Am ales redux persist deoarce mi-am cam batut capul sa configurez store-ul manual dar nu am reusit sa ajung la un rezultat bun asa ca am zis ca nu mai are rost sa reinventez roata si sa pierd timpul si am adaugat redux persist care este foarte usor de configurat, nu mai mult de 2 minute, documentatia se gaseste site-ul official redux-toolkit.

Codul este up to date pe github GitHub - cojoclaudiu/squareify and live pe https://squareify.vercel.app/

new domain: https://squareify.io/

Day 10
Astazi am facut mici modificari la culori.

Am adaugat un button / text pentru edit post si markdown:


Deocamdata pagina de edit este plain si butonul. Urmeaza sa lucrez si la UI pentru pagina de editare a produsului.

E urat sa faci asta cu React fiindca trebuie sa folosesti useRef ca sa il iei, iar ca sa fie corect ar trebui sa te folosesti de ceva fisier de constants.json/js si sa iei valoarea la build si sa il inlocuiesti in CSS iar in JS il importi din fisierul de constante.

Eu as merge cu un hook de useMediaQuery:

Chiar iti recomand sa ti-l faci tu in loc sa folosesti direct o librarie.

Incearca sa fii declarativ cu React in loc sa folosesti if-uri in cod. Daca ai un state atunci dai componenta a, daca ai un alt state dai componenta b, dar nu faci logica cu o functie pentru asta ci te folosesti de react. Asta arata ca stii sa te foloesti de children si de compozitie.

@isti37 am reusit sa fac asta ca in exemplul lui Ionut.
Stiu si de react responsive dar nu prea-i vad rostul daca am hook pentru a verifica window size.

1 Like