Skip to content
Open
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
12 changes: 11 additions & 1 deletion app/admin/stock/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ import { useEffect } from "react";
import Navbar from "@/components/NavBar";
import StockManagementDashboard from "@/components/products/StockManagementDashboard";

/**
* Stock management page component that renders the admin inventory dashboard and enforces admin-only access.
*
* If authentication is loading, displays a centered spinner. If authentication has finished and the user is not
* an admin, redirects to "/dashboard" and renders nothing. When the user is an admin, renders the page layout with
* Navbar and the StockManagementDashboard.
*
* @returns The page's React element: a centered loading spinner while auth is loading, `null` for non-admin users,
* or the admin dashboard layout when the user is an admin.
*/
export default function StockManagementPage() {
const { isAdmin, isLoading } = useAuth();
const router = useRouter();
Expand Down Expand Up @@ -42,4 +52,4 @@ export default function StockManagementPage() {
</main>
</div>
);
}
}
10 changes: 9 additions & 1 deletion app/products/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ import Navbar from "@/components/NavBar";
import { getPublicProductById, recordProductView } from "@/lib/api/products";
import type { ProductWithDetails, ProductMedia } from "@/types/product";

/**
* Render a product detail page showing media, variants, and product metadata.
*
* Fetches the public product using the route `id`, displays loading or error states,
* shows primary media with a thumbnail strip, a gallery, and variant cards, and
* records a product view after a successful load.
*
* @returns A React element that renders the product detail page UI.
*/
export default function ProductDetailPage() {
const params = useParams<{ id: string }>();
const id = params?.id;
Expand Down Expand Up @@ -159,4 +168,3 @@ export default function ProductDetailPage() {
);
}


10 changes: 9 additions & 1 deletion app/products/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ const DEFAULT_FILTERS = {
limit: 12,
};

/**
* Renders the products listing page with search, category and price filters, and paginated product results.
*
* The component fetches filter options and product data when filters change, maintains loading and error states,
* and provides UI controls for searching, selecting categories, setting a price range, clearing filters, and
* navigating pages.
*
* @returns The rendered React element for the products listing page.
*/
export default function ProductsPage() {
const [products, setProducts] = useState<ProductWithDetails[]>([]);
const [loading, setLoading] = useState<boolean>(true);
Expand Down Expand Up @@ -235,4 +244,3 @@ export default function ProductsPage() {
);
}


12 changes: 11 additions & 1 deletion components/products/StockManagementDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ interface BulkUpdateItem {
newStock: number;
}

/**
* Stock management dashboard UI for viewing low-stock items and performing bulk stock updates.
*
* Displays low-stock and out-of-stock counts, a list of low-stock variants with search and export CSV capabilities,
* and a bulk update panel that lets users queue variants, edit target stock levels, and apply batched stock updates.
*
* Shows loading, error, empty, and success states and provides a refresh action to reload low-stock data.
*
* @returns The React element that renders the stock management dashboard.
*/
export default function StockManagementDashboard() {
const { lowStockItems, loading, error, refetch } = useLowStock(10);
const [bulkUpdates, setBulkUpdates] = useState<BulkUpdateItem[]>([]);
Expand Down Expand Up @@ -389,4 +399,4 @@ export default function StockManagementDashboard() {
</div>
</div>
);
}
}
23 changes: 18 additions & 5 deletions lib/api/products.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ export async function getProducts(
}

/**
* Get product by ID (admin)
* Fetches a product by its ID for admin access.
*
* @returns The product details wrapped in an `ApiResponse`
*/
export async function getProductById(
id: string
Expand All @@ -84,8 +86,16 @@ export async function getProductById(

// ==================== PUBLIC BROWSE ====================
/**
* Get public product list with filters
* Supports: categoryId, search (q), minPrice, maxPrice, page, limit
* Fetches a paginated list of public products that match the provided filters.
*
* @param params - Filter and pagination options
* @param params.categoryId - ID of the category to filter products by
* @param params.q - Full-text search query
* @param params.minPrice - Minimum price to include
* @param params.maxPrice - Maximum price to include
* @param params.page - Page number for pagination
* @param params.limit - Number of items per page
* @returns A paginated response containing product details and pagination metadata. On failure `success` is `false` and `data` is an empty array.
*/
export async function getPublicProducts(params: {
categoryId?: string;
Expand Down Expand Up @@ -119,7 +129,10 @@ export async function getPublicProducts(params: {
}

/**
* Get public product details by ID
* Retrieve public product details for the specified product ID.
*
* @param id - The public product ID
* @returns The API response containing the product with details
*/
export async function getPublicProductById(
id: string
Expand Down Expand Up @@ -436,4 +449,4 @@ export async function updateMetrics(): Promise<ApiResponse<any>> {
return apiCall('/api/v1/admin/products/analytics/update-metrics', {
method: 'POST',
});
}
}
12 changes: 10 additions & 2 deletions lib/hooks/useProducts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,15 @@ export function useFilterOptions() {
}

/**
* Hook for low stock alerts
* Provide low-stock product variants for a given threshold and a refetch control.
*
* @param threshold - Stock level threshold used to determine which variants are considered low stock (default 10)
* @returns An object containing:
* - `lowStockItems`: the same array as `variants`, alias for low-stock variants
* - `variants`: array of `ProductVariant` representing low-stock variants
* - `loading`: `true` while a fetch is in progress, `false` otherwise
* - `error`: error message when a fetch fails, or `null` when there is no error
* - `refetch`: function to re-run the low-stock fetch with the current `threshold`
*/
export function useLowStock(threshold: number = 10) {
const [variants, setVariants] = useState<ProductVariant[]>([]);
Expand Down Expand Up @@ -387,4 +395,4 @@ export function useLowStock(threshold: number = 10) {
error,
refetch,
};
}
}