Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding pagination for catalog-api and Adding catalogs Page for dashboard app #151

Merged
merged 1 commit into from
Jul 12, 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
36 changes: 28 additions & 8 deletions src/backend/services/catalog-api/src/handlers/catalog.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::models::catalog::{Catalog, CatalogRequest, CatalogResponse, NewCatalog, UpdateCatalog};
use crate::models::catalog::{Catalog, CatalogItem, CatalogRequest, CatalogsResponse, NewCatalog, UpdateCatalog};

use crate::db::db::establish_connection;
use crate::schema::{self};
use bigdecimal::ToPrimitive;
use diesel::dsl::Limit;
use diesel::prelude::*;
use opentelemetry::global::{self, ObjectSafeSpan};
use opentelemetry::trace::Tracer;
Expand Down Expand Up @@ -72,20 +73,31 @@ pub fn delete(catalog_id: i32) {
}

#[openapi]
#[get("/all?<category_name>", format = "json")]
pub fn get_catalogs(category_name: Option<String>) -> Result<Json<Vec<CatalogResponse>>> {
#[get("/all?<category_name>&<offset>&<limit>", format = "json")]
pub fn get_catalogs(
category_name: Option<String>,
offset: Option<i64>,
limit: Option<i64>,
) -> Result<Json<CatalogsResponse>> {
use schema::catalog::dsl::*;
let connection = &mut establish_connection();

let mut query = catalog.into_boxed();
if let Some(ref cat_name) = category_name {
query = query.filter(category.eq(cat_name));
}
let res = query

let offset = offset.unwrap_or(0);
let limit = limit.unwrap_or(20);
let total = catalog.select(diesel::dsl::count(id)).first(connection).expect("failed to get catalogs count");

let catalog_items: Vec<CatalogItem> = query
.offset(offset)
.limit(limit)
.load::<Catalog>(connection)
.expect("failed to loading catalogs")
.into_iter()
.map(|c| CatalogResponse {
.map(|c| CatalogItem {
id: c.id,
name: c.name,
description: c.description,
Expand All @@ -95,12 +107,20 @@ pub fn get_catalogs(category_name: Option<String>) -> Result<Json<Vec<CatalogRes
category: c.category,
})
.collect();
return Ok(Json(res));

let result = CatalogsResponse {
total,
catalog_items,
offset,
limit,
};

return Ok(Json(result));
}

#[openapi]
#[get("/<catalog_id>", format = "json")]
pub fn get_catalog(catalog_id: i32) -> Result<Json<CatalogResponse>> {
pub fn get_catalog(catalog_id: i32) -> Result<Json<CatalogItem>> {
use schema::catalog::dsl::*;

let connection = &mut establish_connection();
Expand All @@ -109,7 +129,7 @@ pub fn get_catalog(catalog_id: i32) -> Result<Json<CatalogResponse>> {
.first::<Catalog>(connection)
.expect("failed to loading catalogs");

let res = CatalogResponse {
let res = CatalogItem {
id: c.id,
name: c.name,
description: c.description,
Expand Down
11 changes: 10 additions & 1 deletion src/backend/services/catalog-api/src/models/catalog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub struct CatalogRequest {

#[derive(Serialize, Deserialize, JsonSchema)]
#[serde(crate = "rocket::serde")]
pub struct CatalogResponse {
pub struct CatalogItem {
pub id: i32,
pub name: String,
pub description: Option<String>,
Expand All @@ -65,3 +65,12 @@ pub struct CatalogResponse {
pub currency: String,
pub category: String,
}

#[derive(Serialize, Deserialize, JsonSchema)]
#[serde(crate = "rocket::serde")]
pub struct CatalogsResponse {
pub catalog_items: Vec<CatalogItem>,
pub total: i64,
pub offset: i64,
pub limit: i64,
}
2 changes: 1 addition & 1 deletion src/backend/services/web-app/src/app/foods/foods.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const FoodsPage = ({
</div>
<div className="order-last min-h-screen w-full md:order-none">
<div className="flex flex-wrap justify-center">
{foodItems.map((item) => (
{foodItems.catalog_items.map((item) => (
<Item foodItem={item} key={item.id} />
))}
</div>
Expand Down
5 changes: 3 additions & 2 deletions src/backend/services/web-app/src/lib/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ async function fetchItems(apiUrl: string) {
}

const items: FoodItems = FoodItemsScheme.parse(await res.json());
const updatedItems = items.map((item) => {
const catalog_items = items.catalog_items.map((item) => {
return {
...item,
image: process.env.INTERNAL_API_BASE_URL + item.image
};
});

return updatedItems;

return {...items, catalog_items}
}

export async function fetchCategories(): Promise<Categories> {
Expand Down
7 changes: 6 additions & 1 deletion src/backend/services/web-app/src/lib/types/food-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ export const FoodItemScheme = z.object({
currency: z.string()
});

export const FoodItemsScheme = z.array(FoodItemScheme);
export const FoodItemsScheme = z.object({
catalog_items: z.array(FoodItemScheme),
total: z.number(),
offset: z.number(),
limit: z.number()
});

export const CategoriesScheme = z.array(
z.object({
Expand Down
12 changes: 12 additions & 0 deletions src/backend/services/web.admin/dashboard-app/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ const nextConfig = {
protocol: "https",
hostname: "*.public.blob.vercel-storage.com",
},
{
protocol: 'http',
hostname: 'localhost'
},
{
protocol: 'http',
hostname: 'traefik'
},
{
protocol: 'http',
hostname: 'host.docker.internal'
}
],
},
};
Expand Down
19 changes: 14 additions & 5 deletions src/backend/services/web.admin/dashboard-app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions src/backend/services/web.admin/dashboard-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
},
"dependencies": {
"@heroicons/react": "^2.1.1",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-dialog": "^1.1.1",
"@radix-ui/react-dropdown-menu": "^2.1.1",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-tabs": "^1.1.0",
"@radix-ui/react-tooltip": "^1.1.2",
Expand All @@ -24,10 +24,11 @@
"react": "^18",
"react-dom": "^18",
"tailwind-merge": "^2.2.1",
"tailwindcss-animate": "^1.0.7"
"tailwindcss-animate": "^1.0.7",
"zod": "^3.23.8"
},
"devDependencies": {
"@types/node": "^20",
"@types/node": "^20.14.10",
"@types/react": "^18",
"@types/react-dom": "^18",
"autoprefixer": "^10.0.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { File, PlusCircle } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { ProductsTable } from './products-table';
import { getProducts } from '@/lib/db';
import { fetchCatalogs } from '@/lib/fetch';


export default async function ProductsPage({
Expand All @@ -12,9 +12,11 @@ export default async function ProductsPage({
}) {
const search = searchParams.q ?? '';
const offset = searchParams.offset ?? 0;
const { products, newOffset, totalProducts } = await getProducts(
const productsPerPage = 10;
const { products, newOffset, totalProducts } = await fetchCatalogs(
search,
Number(offset)
Number(offset),
productsPerPage,
);

return (
Expand Down Expand Up @@ -48,6 +50,7 @@ export default async function ProductsPage({
products={products}
offset={newOffset ?? 0}
totalProducts={totalProducts}
productsPerPage={productsPerPage}
/>
</TabsContent>
</Tabs>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import {
} from '@/components/ui/dropdown-menu';
import { MoreHorizontal } from 'lucide-react';
import { TableCell, TableRow } from '@/components/ui/table';
import { SelectProduct } from '@/lib/db';
import { deleteProduct } from './actions';
import { SelectProduct } from '@/lib/fetch';

export function Product({ product }: { product: SelectProduct }) {
return (
Expand All @@ -32,7 +32,7 @@ export function Product({ product }: { product: SelectProduct }) {
</Badge>
</TableCell>
<TableCell className="hidden md:table-cell">{`$${product.price}`}</TableCell>
<TableCell className="hidden md:table-cell">{product.stock}</TableCell>
<TableCell className="hidden md:table-cell">{product.currency}</TableCell>
<TableCell className="hidden md:table-cell">
{product.availableAt.toLocaleDateString()}
</TableCell>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,34 @@ import { Product } from './product';
import { useRouter } from 'next/navigation';
import { ChevronLeft, ChevronRight } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { SelectProduct } from '@/lib/db';
import { SelectProduct } from '@/lib/fetch';

export function ProductsTable({
products,
offset,
totalProducts
totalProducts,
productsPerPage,
}: {
products: SelectProduct[];
offset: number;
totalProducts: number;
productsPerPage: number;
}) {
let router = useRouter();
let productsPerPage = 5;

function prevPage() {
router.back();
}

function nextPage() {
router.push(`/?offset=${offset}`, { scroll: false });
router.push(`/products?offset=${offset}`, { scroll: false });
}

return (
<Card>
<CardHeader>
<CardTitle>Products</CardTitle>
<CardDescription>
Manage your products and view their sales performance.
Manage your products.
</CardDescription>
</CardHeader>
<CardContent>
Expand All @@ -59,9 +59,7 @@ export function ProductsTable({
<TableHead>Name</TableHead>
<TableHead>Status</TableHead>
<TableHead className="hidden md:table-cell">Price</TableHead>
<TableHead className="hidden md:table-cell">
Total Sales
</TableHead>
<TableHead className="hidden md:table-cell">Currency</TableHead>
<TableHead className="hidden md:table-cell">Created at</TableHead>
<TableHead>
<span className="sr-only">Actions</span>
Expand Down
39 changes: 0 additions & 39 deletions src/backend/services/web.admin/dashboard-app/src/lib/db.ts

This file was deleted.

Loading
Loading