Skip to content
This repository has been archived by the owner on Dec 6, 2024. It is now read-only.

feat: implement product verification #87

Merged
merged 4 commits into from
Dec 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions frontend/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ RPC_URL=

DATABASE_URL=

BACKEND_BASE_URL=http://localhost:3000/api


48 changes: 48 additions & 0 deletions frontend/src/app/api/product/[productId].ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import type { NextApiRequest, NextApiResponse } from 'next';

type ProductDetails = {
product_id: string;
name: string;
image: string;
manufacturer: string;
manufactureDate: string;
expiryDate: string;
};

type ErrorResponse = {
error: string;
};

const BASE_URL = process.env.BACKEND_BASE_URL || 'http://localhost:3000'; // Update to match your backend URL

export default async function handler(
req: NextApiRequest,
res: NextApiResponse<ProductDetails | ErrorResponse>
) {
const { productId } = req.query;

if (req.method !== 'GET') {
return res.status(405).json({ error: 'Method Not Allowed' });
}

if (!productId || typeof productId !== 'string') {
return res.status(400).json({ error: 'Invalid or missing productId' });
}

try {
const response = await fetch(`${BASE_URL}/products/${productId}`);

if (!response.ok) {
const errorBody = await response.json();
return res
.status(response.status)
.json({ error: errorBody.error || 'Failed to fetch product details' });
}

const productDetails: ProductDetails = await response.json();
return res.status(200).json(productDetails);
} catch (error: any) {
console.error('Error fetching product details:', error.message);
return res.status(500).json({ error: 'Internal Server Error' });
}
}
20 changes: 18 additions & 2 deletions frontend/src/components/Scan.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
StarIcon2,
} from '@/assets/icons';
import { CONTRACT_ADDR, formatDate, formatIpfsHash } from '@/lib/config';
import { fetchIpfsFile } from '@/services/apiService';
import { fetchIpfsFile, fetchProductDetails } from '@/services/apiService';
import { useAccount, useReadContract } from '@starknet-react/core';
import React, { useEffect, useMemo, useState } from 'react';
import { useParams } from 'next/navigation';
Expand All @@ -22,6 +22,7 @@
};

export default function ScanProduct() {
const [productId, setProductId] = useState<string>('');
const [product, setProduct] = useState<ProductProps | any>();
const [contractData, setContractData] = useState<{
product_id: string;
Expand All @@ -34,13 +35,28 @@
const { address } = useAccount();
let payload = params?.product;

useEffect(() => {
const fetchData = async () => {
try {
if (payload) {
const product = await fetchProductDetails(payload[0]);
setProductId(product.productId);
}
} catch (e) {
console.error('Error fetching from Product:', e);
}
};

fetchData();
}, [payload]);

const toggleUserModal = () => {
setOpenWallet((prev) => !prev);
};

const { data } = useReadContract({
functionName: 'verify',
args: [payload.toString()],
args: [productId],
abi,
address: CONTRACT_ADDR,
watch: true,
Expand Down Expand Up @@ -93,7 +109,7 @@
</p>
</div>
<div className="col-span-2 w-full h-full">
<img

Check warning on line 112 in frontend/src/components/Scan.tsx

View workflow job for this annotation

GitHub Actions / lint-and-build-frontend

Using `<img>` could result in slower LCP and higher bandwidth. Consider using `<Image />` from `next/image` to automatically optimize images. This may incur additional usage or cost from your provider. See: https://nextjs.org/docs/messages/no-img-element
src={product?.image}
className="w-full h-full object-cover"
alt="product-image"
Expand Down Expand Up @@ -195,7 +211,7 @@
</p>

<div className="">
<img src={product?.image} alt="product-image" />

Check warning on line 214 in frontend/src/components/Scan.tsx

View workflow job for this annotation

GitHub Actions / lint-and-build-frontend

Using `<img>` could result in slower LCP and higher bandwidth. Consider using `<Image />` from `next/image` to automatically optimize images. This may incur additional usage or cost from your provider. See: https://nextjs.org/docs/messages/no-img-element
<div className="flex items-center justify-between pt-5">
{/* <div className="space-y-2 flex items-center justify-center flex-col">
<ScanIcon2 />
Expand Down
13 changes: 13 additions & 0 deletions frontend/src/services/apiService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,16 @@ export const handleFlagProduct = async function (

return await response.json();
};

export const fetchProductDetails = async (productId: string) => {
try {
const response = await fetch(`/api/product/${productId}`);
if (!response.ok) {
throw new Error(await response.text());
}
return await response.json();
} catch (error) {
console.error('Error fetching product details:', error);
throw error;
}
};
Loading