# Shopify Stack

Stack para desenvolvimento de apps e storefronts Shopify com Hydrogen e Liquid.

## Visão Geral

| Aspecto | Tecnologia |
|---------|------------|
| **Storefront** | Hydrogen / Liquid |
| **Apps** | Shopify App Bridge + Remix |
| **API** | GraphQL Storefront/Admin API |
| **CLI** | Shopify CLI |
| **Hosting** | Shopify hosting / Vercel |

## Triggers

Keywords: `shopify`, `hydrogen`, `liquid`, `ecommerce`, `storefront`, `shopify app`, `graphql`

## Tipos de Projetos Shopify

### 1. Theme Development (Liquid)

Customização de temas existentes ou criação de novos.

```
theme/
├── assets/
├── config/
├── layout/
│   └── theme.liquid
├── locales/
├── sections/
│   └── hero.liquid
├── snippets/
└── templates/
    └── product.liquid
```

### 2. Custom Storefront (Hydrogen)

Storefront headless com React e Remix.

```
hydrogen-app/
├── app/
│   ├── components/
│   ├── routes/
│   └── styles/
├── public/
├── remix.config.js
└── package.json
```

### 3. Shopify App

App que estende funcionalidades do Shopify Admin.

```
shopify-app/
├── app/
│   ├── routes/
│   │   └── app._index.tsx
│   └── shopify.server.ts
├── extensions/
└── shopify.app.toml
```

## Shopify CLI

```bash
# Instalar
npm install -g @shopify/cli

# Criar app
shopify app init

# Criar tema
shopify theme init

# Criar storefront Hydrogen
npm create @shopify/hydrogen

# Dev server
shopify app dev
shopify theme dev
npm run dev  # Hydrogen
```

## Hydrogen (Storefront)

### Setup

```bash
npm create @shopify/hydrogen@latest -- --template demo-store
cd my-store
npm run dev
```

### Configuração

```typescript
// hydrogen.config.ts
import { defineConfig } from '@shopify/hydrogen/config';

export default defineConfig({
  shopify: {
    defaultCountryCode: 'BR',
    defaultLanguageCode: 'PT',
    storeDomain: 'your-store.myshopify.com',
    storefrontToken: process.env.PUBLIC_STOREFRONT_API_TOKEN,
    storefrontApiVersion: '2024-01',
  },
});
```

### Fetch de Produtos

```tsx
// app/routes/products._index.tsx
import { json } from '@shopify/remix-oxygen';
import { useLoaderData } from '@remix-run/react';
import { ProductGrid } from '~/components/ProductGrid';

const PRODUCTS_QUERY = `#graphql
  query Products($first: Int!) {
    products(first: $first) {
      nodes {
        id
        title
        handle
        priceRange {
          minVariantPrice {
            amount
            currencyCode
          }
        }
        featuredImage {
          url
          altText
        }
      }
    }
  }
`;

export async function loader({ context }: { context: HydrogenContext }) {
  const { products } = await context.storefront.query(PRODUCTS_QUERY, {
    variables: { first: 12 },
  });

  return json({ products: products.nodes });
}

export default function ProductsIndex() {
  const { products } = useLoaderData<typeof loader>();

  return (
    <div className="container mx-auto p-4">
      <h1 className="text-2xl font-bold mb-6">Produtos</h1>
      <ProductGrid products={products} />
    </div>
  );
}
```

### Componente de Produto

```tsx
// app/components/ProductCard.tsx
import { Image, Money } from '@shopify/hydrogen';
import { Link } from '@remix-run/react';

interface Props {
  product: {
    id: string;
    title: string;
    handle: string;
    priceRange: {
      minVariantPrice: {
        amount: string;
        currencyCode: string;
      };
    };
    featuredImage?: {
      url: string;
      altText?: string;
    };
  };
}

export function ProductCard({ product }: Props) {
  return (
    <Link to={`/products/${product.handle}`} className="group">
      <div className="aspect-square overflow-hidden rounded-lg bg-gray-100">
        {product.featuredImage && (
          <Image
            data={product.featuredImage}
            className="h-full w-full object-cover group-hover:scale-105 transition"
          />
        )}
      </div>
      <h3 className="mt-4 text-sm text-gray-700">{product.title}</h3>
      <Money
        data={product.priceRange.minVariantPrice}
        className="mt-1 text-lg font-medium text-gray-900"
      />
    </Link>
  );
}
```

## Liquid (Theme Development)

### Section Exemplo

```liquid
{% comment %} sections/hero.liquid {% endcomment %}

<section class="hero" style="background-image: url('{{ section.settings.background_image | img_url: 'master' }}');">
  <div class="hero__content">
    <h1>{{ section.settings.heading }}</h1>
    <p>{{ section.settings.subheading }}</p>

    {% if section.settings.button_link != blank %}
      <a href="{{ section.settings.button_link }}" class="btn">
        {{ section.settings.button_text }}
      </a>
    {% endif %}
  </div>
</section>

{% schema %}
{
  "name": "Hero",
  "settings": [
    {
      "type": "image_picker",
      "id": "background_image",
      "label": "Background Image"
    },
    {
      "type": "text",
      "id": "heading",
      "label": "Heading",
      "default": "Welcome to our store"
    },
    {
      "type": "text",
      "id": "subheading",
      "label": "Subheading"
    },
    {
      "type": "url",
      "id": "button_link",
      "label": "Button Link"
    },
    {
      "type": "text",
      "id": "button_text",
      "label": "Button Text",
      "default": "Shop Now"
    }
  ],
  "presets": [
    {
      "name": "Hero"
    }
  ]
}
{% endschema %}
```

### Product Template

```liquid
{% comment %} templates/product.liquid {% endcomment %}

<div class="product-page">
  <div class="product-gallery">
    {% for image in product.images %}
      <img
        src="{{ image | img_url: '600x600' }}"
        alt="{{ image.alt | escape }}"
        loading="lazy"
      />
    {% endfor %}
  </div>

  <div class="product-info">
    <h1>{{ product.title }}</h1>
    <p class="price">{{ product.price | money }}</p>

    <div class="description">
      {{ product.description }}
    </div>

    {% form 'product', product %}
      <select name="id">
        {% for variant in product.variants %}
          <option value="{{ variant.id }}" {% unless variant.available %}disabled{% endunless %}>
            {{ variant.title }} - {{ variant.price | money }}
          </option>
        {% endfor %}
      </select>

      <input type="number" name="quantity" value="1" min="1" />

      <button type="submit" {% unless product.available %}disabled{% endunless %}>
        {% if product.available %}
          Add to Cart
        {% else %}
          Sold Out
        {% endif %}
      </button>
    {% endform %}
  </div>
</div>
```

## Shopify App

### App Setup

```bash
shopify app init --template=remix
cd my-app
shopify app dev
```

### App Bridge

```tsx
// app/routes/app._index.tsx
import { json } from '@remix-run/node';
import { useLoaderData } from '@remix-run/react';
import { authenticate } from '../shopify.server';
import { Page, Layout, Card, Text } from '@shopify/polaris';

export async function loader({ request }) {
  const { admin, session } = await authenticate.admin(request);

  const response = await admin.graphql(`
    query {
      shop {
        name
        email
      }
    }
  `);

  const { data } = await response.json();

  return json({ shop: data.shop });
}

export default function Index() {
  const { shop } = useLoaderData<typeof loader>();

  return (
    <Page title="Dashboard">
      <Layout>
        <Layout.Section>
          <Card>
            <Text variant="headingMd" as="h2">
              Welcome to {shop.name}
            </Text>
            <Text as="p">Store email: {shop.email}</Text>
          </Card>
        </Layout.Section>
      </Layout>
    </Page>
  );
}
```

## GraphQL APIs

### Storefront API

```graphql
# Produtos
query {
  products(first: 10) {
    nodes {
      id
      title
      handle
      description
    }
  }
}

# Carrinho
mutation cartCreate($input: CartInput!) {
  cartCreate(input: $input) {
    cart {
      id
      checkoutUrl
    }
  }
}
```

### Admin API

```graphql
# Pedidos
query {
  orders(first: 10) {
    nodes {
      id
      name
      totalPriceSet {
        shopMoney {
          amount
        }
      }
    }
  }
}
```

## Documentação de Referência

- [Shopify CLI](https://shopify.dev/docs/apps/tools/cli)
- [Hydrogen](https://shopify.dev/docs/storefronts/hydrogen)
- [Liquid](https://shopify.dev/docs/themes/liquid)
- [Storefront API](https://shopify.dev/docs/api/storefront)
- [Admin API](https://shopify.dev/docs/api/admin)
- [Polaris](https://polaris.shopify.com/)

## Checklist de Projeto

- [ ] Shopify CLI instalado
- [ ] Partner account configurado
- [ ] Development store criada
- [ ] API tokens configurados
- [ ] Theme/App estrutura criada
- [ ] GraphQL queries definidas
- [ ] Polaris para UI (apps)
- [ ] Testes com theme check

---

*MORPH-SPEC by Polymorphism Tech*
