mirror of
https://github.com/harivansh-afk/GymSupps.git
synced 2026-04-15 05:02:10 +00:00
hotfix: shoppify hydrogen initialization with mock data
This commit is contained in:
parent
357979d0af
commit
4e59c6866d
15 changed files with 6510 additions and 115 deletions
3
.env.example
Normal file
3
.env.example
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# Shopify Store Configuration
|
||||
VITE_SHOPIFY_STORE_DOMAIN=your-store.myshopify.com
|
||||
VITE_SHOPIFY_STOREFRONT_TOKEN=your-storefront-access-token
|
||||
40
.gitignore
vendored
40
.gitignore
vendored
|
|
@ -1,24 +1,36 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
# Environment variables
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Dependencies
|
||||
node_modules/
|
||||
.pnp/
|
||||
.pnp.js
|
||||
|
||||
# Build output
|
||||
dist/
|
||||
build/
|
||||
|
||||
# Debug logs
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
.idea/
|
||||
.vscode/
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
# OS generated files
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
|
|
|
|||
12
hydrogen.config.ts
Normal file
12
hydrogen.config.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import {defineConfig} from '@shopify/hydrogen/config';
|
||||
|
||||
export default defineConfig({
|
||||
shopify: {
|
||||
storeDomain: 'your-store.myshopify.com',
|
||||
storefrontToken: 'your_storefront_api_token',
|
||||
storefrontApiVersion: '2024-01', // Use the latest API version
|
||||
},
|
||||
session: {
|
||||
storage: 'memory', // You can change this to 'redis' or other storage methods in production
|
||||
},
|
||||
});
|
||||
6236
package-lock.json
generated
6236
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -16,8 +16,14 @@
|
|||
"@radix-ui/react-scroll-area": "^1.0.5",
|
||||
"@radix-ui/react-separator": "^1.0.3",
|
||||
"@radix-ui/react-slot": "^1.0.2",
|
||||
"@shopify/cli": "^3.75.4",
|
||||
"@shopify/cli-hydrogen": "^9.0.8",
|
||||
"@shopify/hydrogen": "^2025.1.2",
|
||||
"@shopify/hydrogen-react": "^2025.1.2",
|
||||
"@shopify/storefront-kit-react": "^2023.1.3",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.1.0",
|
||||
"graphql-tag": "^2.12.6",
|
||||
"lucide-react": "^0.344.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
|
|
|
|||
57
src/App.tsx
57
src/App.tsx
|
|
@ -1,31 +1,35 @@
|
|||
import React, { useState } from 'react';
|
||||
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
|
||||
import { ProductsPage } from './pages/Products';
|
||||
import { Header } from './components/Header';
|
||||
import { ProductGrid } from './components/ProductGrid';
|
||||
import { ProductDetails } from './components/ProductDetails';
|
||||
import { products } from './data/products';
|
||||
|
||||
function App() {
|
||||
const App: React.FC = () => {
|
||||
const [selectedProduct, setSelectedProduct] = useState<string | null>(null);
|
||||
const [selectedCategory, setSelectedCategory] = useState<string | null>(null);
|
||||
|
||||
const categories = Array.from(new Set(products.map((p) => p.category)));
|
||||
const currentProduct = products.find((p) => p.id === selectedProduct);
|
||||
|
||||
return (
|
||||
<Router>
|
||||
<div className="min-h-screen bg-background">
|
||||
<Header />
|
||||
<main className="max-w-7xl mx-auto px-4 py-8">
|
||||
{!selectedProduct ? (
|
||||
<main className="container mx-auto p-4">
|
||||
<nav className="mb-4">
|
||||
<Link to="/local-products" className="mr-4 text-primary hover:text-primary/80">
|
||||
Local Products
|
||||
</Link>
|
||||
<Link to="/shopify-products" className="text-primary hover:text-primary/80">
|
||||
Shopify Products
|
||||
</Link>
|
||||
</nav>
|
||||
<Routes>
|
||||
<Route
|
||||
path="/local-products"
|
||||
element={
|
||||
<>
|
||||
<section className="text-center mb-12">
|
||||
<h1 className="text-4xl font-bold mb-4">
|
||||
Premium Supplements for Your Fitness Journey
|
||||
</h1>
|
||||
<p className="text-lg text-muted-foreground max-w-2xl mx-auto">
|
||||
Discover our range of high-quality supplements designed to help you achieve your fitness goals.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<div className="mb-8">
|
||||
<div className="flex flex-wrap gap-4 justify-center">
|
||||
<button
|
||||
|
|
@ -53,14 +57,7 @@ function App() {
|
|||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ProductGrid
|
||||
products={products}
|
||||
category={selectedCategory ?? undefined}
|
||||
onProductSelect={setSelectedProduct}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
{selectedProduct ? (
|
||||
<div>
|
||||
<button
|
||||
onClick={() => setSelectedProduct(null)}
|
||||
|
|
@ -68,12 +65,26 @@ function App() {
|
|||
>
|
||||
← Back to Products
|
||||
</button>
|
||||
{currentProduct && <ProductDetails product={currentProduct} />}
|
||||
<ProductDetails
|
||||
product={products.find((p) => p.id === selectedProduct)!}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<ProductGrid
|
||||
products={products}
|
||||
category={selectedCategory || undefined}
|
||||
onProductSelect={setSelectedProduct}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Route path="/shopify-products" element={<ProductsPage />} />
|
||||
</Routes>
|
||||
</main>
|
||||
</div>
|
||||
</Router>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default App;
|
||||
55
src/components/ShopifyProductCard.tsx
Normal file
55
src/components/ShopifyProductCard.tsx
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import React from 'react';
|
||||
import { Money, Image } from '@shopify/hydrogen-react';
|
||||
import { ShoppingCart } from 'lucide-react';
|
||||
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from './ui/card';
|
||||
import { Button } from './ui/button';
|
||||
import { ShopifyProduct } from '../types/shopify';
|
||||
|
||||
interface ShopifyProductCardProps {
|
||||
product: ShopifyProduct;
|
||||
onSelect: (productId: string) => void;
|
||||
}
|
||||
|
||||
export const ShopifyProductCard: React.FC<ShopifyProductCardProps> = ({ product, onSelect }) => {
|
||||
if (!product) return null;
|
||||
|
||||
return (
|
||||
<Card className="cursor-pointer" onClick={() => onSelect(product.id)}>
|
||||
<CardHeader className="p-0">
|
||||
{product.featuredImage && (
|
||||
<Image
|
||||
data={product.featuredImage}
|
||||
alt={product.title}
|
||||
className="w-full h-48 object-cover rounded-t-xl"
|
||||
/>
|
||||
)}
|
||||
</CardHeader>
|
||||
<CardContent className="p-4">
|
||||
<div className="flex justify-between items-start mb-2">
|
||||
<CardTitle className="text-lg">{product.title}</CardTitle>
|
||||
<Money
|
||||
data={product.priceRange.minVariantPrice}
|
||||
className="text-lg font-bold text-primary"
|
||||
/>
|
||||
</div>
|
||||
<p className="text-muted-foreground text-sm mb-4 line-clamp-2">
|
||||
{product.description}
|
||||
</p>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<Button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
// You'll need to implement your own add to cart logic here
|
||||
console.log('Add to cart:', product.id);
|
||||
}}
|
||||
className="w-full"
|
||||
size="lg"
|
||||
>
|
||||
<ShoppingCart className="w-4 h-4 mr-2" />
|
||||
Add to Cart
|
||||
</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
22
src/components/ShopifyProductGrid.tsx
Normal file
22
src/components/ShopifyProductGrid.tsx
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import React from 'react';
|
||||
import { ShopifyProductCard } from './ShopifyProductCard';
|
||||
import { ShopifyProduct } from '../types/shopify';
|
||||
|
||||
export const ShopifyProductGrid: React.FC<{ products: ShopifyProduct[] }> = ({ products }) => {
|
||||
const handleProductSelect = (productId: string) => {
|
||||
// Handle product selection - you can implement navigation to product details page
|
||||
console.log('Selected product:', productId);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 p-6">
|
||||
{products.map((product) => (
|
||||
<ShopifyProductCard
|
||||
key={product.id}
|
||||
product={product}
|
||||
onSelect={handleProductSelect}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
58
src/data/mockShopifyProducts.ts
Normal file
58
src/data/mockShopifyProducts.ts
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
import { ShopifyProduct } from '../types/shopify';
|
||||
|
||||
export const mockProducts: ShopifyProduct[] = [
|
||||
{
|
||||
id: '1',
|
||||
title: 'Whey Protein Isolate',
|
||||
description: 'Premium whey protein isolate for optimal muscle recovery and growth.',
|
||||
handle: 'whey-protein-isolate',
|
||||
priceRange: {
|
||||
minVariantPrice: {
|
||||
amount: '49.99',
|
||||
currencyCode: 'USD'
|
||||
}
|
||||
},
|
||||
featuredImage: {
|
||||
url: 'https://images.unsplash.com/photo-1593095948071-474c5cc2989d?q=80&w=2670&auto=format&fit=crop',
|
||||
altText: 'Whey Protein Container',
|
||||
width: 800,
|
||||
height: 800
|
||||
}
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
title: 'Pre-Workout Energy',
|
||||
description: 'Advanced pre-workout formula for enhanced performance and focus.',
|
||||
handle: 'pre-workout-energy',
|
||||
priceRange: {
|
||||
minVariantPrice: {
|
||||
amount: '39.99',
|
||||
currencyCode: 'USD'
|
||||
}
|
||||
},
|
||||
featuredImage: {
|
||||
url: 'https://images.unsplash.com/photo-1594882645126-14020914d58d?q=80&w=2785&auto=format&fit=crop',
|
||||
altText: 'Pre-workout Container',
|
||||
width: 800,
|
||||
height: 800
|
||||
}
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
title: 'BCAA Complex',
|
||||
description: 'Essential branched-chain amino acids for muscle support and recovery.',
|
||||
handle: 'bcaa-complex',
|
||||
priceRange: {
|
||||
minVariantPrice: {
|
||||
amount: '29.99',
|
||||
currencyCode: 'USD'
|
||||
}
|
||||
},
|
||||
featuredImage: {
|
||||
url: 'https://images.unsplash.com/photo-1579722820308-d74e571900a9?q=80&w=2670&auto=format&fit=crop',
|
||||
altText: 'BCAA Container',
|
||||
width: 800,
|
||||
height: 800
|
||||
}
|
||||
}
|
||||
];
|
||||
10
src/env.d.ts
vendored
Normal file
10
src/env.d.ts
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
/// <reference types="vite/client" />
|
||||
|
||||
interface ImportMetaEnv {
|
||||
readonly VITE_SHOPIFY_STORE_DOMAIN: string;
|
||||
readonly VITE_SHOPIFY_STOREFRONT_TOKEN: string;
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
readonly env: ImportMetaEnv;
|
||||
}
|
||||
|
|
@ -1,10 +1,19 @@
|
|||
import React from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import { ShopifyProvider } from '@shopify/hydrogen-react';
|
||||
import App from './App.tsx';
|
||||
import './index.css';
|
||||
|
||||
createRoot(document.getElementById('root')!).render(
|
||||
<React.StrictMode>
|
||||
<ShopifyProvider
|
||||
storeDomain={import.meta.env.VITE_SHOPIFY_STORE_DOMAIN}
|
||||
storefrontToken={import.meta.env.VITE_SHOPIFY_STOREFRONT_TOKEN}
|
||||
storefrontApiVersion="2024-01"
|
||||
countryIsoCode="US"
|
||||
languageIsoCode="EN"
|
||||
>
|
||||
<App />
|
||||
</ShopifyProvider>
|
||||
</React.StrictMode>
|
||||
);
|
||||
7
src/pages/Products.tsx
Normal file
7
src/pages/Products.tsx
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import React from 'react';
|
||||
import { ShopifyProductGrid } from '../components/ShopifyProductGrid';
|
||||
import { mockProducts } from '../data/mockShopifyProducts';
|
||||
|
||||
export const ProductsPage: React.FC = () => {
|
||||
return <ShopifyProductGrid products={mockProducts} />;
|
||||
};
|
||||
18
src/types/shopify.ts
Normal file
18
src/types/shopify.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
export interface ShopifyProduct {
|
||||
id: string;
|
||||
title: string;
|
||||
description: string;
|
||||
handle: string;
|
||||
priceRange: {
|
||||
minVariantPrice: {
|
||||
amount: string;
|
||||
currencyCode: 'USD' | 'EUR' | 'GBP' | 'CAD' | 'AUD';
|
||||
};
|
||||
};
|
||||
featuredImage: {
|
||||
url: string;
|
||||
altText: string;
|
||||
width: number;
|
||||
height: number;
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue