Создаем карточку продукта

Карточка товара

Следующим шагом добавим карточку продукта и переход на нее из общего списка. Для этого добавим еще один app.html вызов в наш backend-файл. Таким образом, мы добавляем еще один обработчик адресов в этот файл

app.html('/card/:id', async(ctx,req) => {
  return <html>
    {req.params.id}
  </html>
})

Обратите внимание на то, что в адресе есть параметр :id, этот шаблон покрывает все адреса вида

https://{домен аккаунта}/backend~card/{id карточки}

Теперь давайте сделаем ссылку на эту карточку из списка. Первым делом объявим константу, в которую присвоим хендлер карточки товара

const cardScreen = app.html('/card/:id', async(ctx,req) => {
  // дальнейший код

Следующим этапом нам нужно использовать эту константу в коде, выдающем список карточек для того чтобы сформировать ссылку из списка на карточку товара. Заодно заменим тег <div> на <a>

{items.map( item =>
  <a class="card" href={cardScreen({id: item.id}).url()}>
    <img src={item.image?.getThumbnailUrl(500,300)}/>
    <div class='card-body p-2'>
      <h3>{item.title}</h3>
      <div>{item.material}</div>
      <div>{item.dimensions}</div>
    </div>
  </a>
)}

Обратите внимание на то, как формируется адрес ссылки, в нее передается id карточки

cardScreen({id: item.id}).url()

Теперь сделаем обратную ссылку из карточки на страницу списка. Для этого, точно так же, присвоим хендлер страницы списка в константу

const mainScreen = app.html('/', async(ctx,req) => {
// дальнейший код

И сделаем ссылку на этот экран в верстке карточки товара

app.html('/card/:id', async(ctx,req) => {
  return <html>
    <h3 class="mb-3"><a  href={mainScreen.url()}>Каталог картин</a></h3>
    {req.params.id}
  </html>
})

Теперь попробуем открыть наш код и посмотрим как работает список и карточка. Список показывает код, можно нажать на любой элемент и перейти на страницу карточки, в которой мы видим только id

Давайте добавим данные товара на страницу карточки. Для этого, нам нужно "поднять" данные о картине по ее id. Для этого, используем метод таблицы getById

const cardScreen = app.html('/card/:id', async(ctx,req) => {
  const item = await catalogTable.getById(ctx, req.params.id !)

  return <html>
    <h3 class="mb-3"><a  href={mainScreen.url()}>Каталог картин</a></h3>
    <h1 class={"fs-1 fs-header fw-bold"}>{item.title}</h1>
  </html>
})

Полную верстку карточки здесь приведем уже в итоговом коде ниже

Итоговый код

import {jsx} from '@app/html-jsx'
import {Heap} from '@app/heap'

const catalogTable = Heap.Table('pictures', {
  title: Heap.String(), // название. строка
  image: Heap.ImageFile(),  // изображение. обязательный
  material: Heap.Optional( Heap.String() ),  // материал. необязательный. строка. 
  dimensions: Heap.Optional( Heap.String() ),  // размеры. необязательный. строка. 
  price: Heap.NonRequired( Heap.Number(),0 ), // цена. число. по умолчанию 0
})

let currency = new Intl.NumberFormat('ru-RU', {
  style: 'currency',
  currency: 'RUB',
  maximumFractionDigits:0,
});

const mainScreen = app.html('/', async(ctx,req) => {
  const items =  await catalogTable.findAll(ctx)

  return <html>
    <head>
      <title>Каталог картин</title>
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous"/>
    </head>
    <body>
      <div class="container p-3 col-md-6 col-12">
        <h1 class={"fs-1 fs-header fs-bold"}>Каталог картин</h1>
        
        {items.map( item =>
          <a class="card" href={cardScreen({id: item.id}).url()}>
            <img src={item.image?.getThumbnailUrl(500,300)}/>
            <div class='card-body p-2'>
              <h3>{item.title}</h3>
              <div>{item.material}</div>
              <div>{item.dimensions}</div>
            </div>
          </a>
        )}
      </div>
    </body>
  </html>
})

const cardScreen = app.html('/card/:id', async(ctx,req) => {
  const item = await catalogTable.getById(ctx, req.params.id !)
  
  return <html>
    <h3 class="mb-3"><a  href={mainScreen.url()}>Каталог картин</a></h3>
    <div class={"row g-10"}>
      <div class={"col-md-8 col-12"}>
        <img class="mw-100" src={item.image?.getThumbnailUrl(900)}/>
      </div>
      <div class={"col-md-4 col-12"}>
        <h1 class={"fs-1 fs-header fw-bold"}>{item.title}</h1>
        <div>{item.material}</div>
        <div>{item.dimensions}</div>
        { item.price && <div class={"fs-2"}>{currency.format(item.price)}</div> }        
      </div>
    </div>
  </html>
})

Следующий шаг: Общий макет наших страниц

❤️ Made with love on Chatium

ООО "Чатиум"

Информация о компании