Skip to content

Initial commit#63

Draft
Edwz208 wants to merge 3 commits intomainfrom
feature/enable-edit-item-and-mobile-optimization
Draft

Initial commit#63
Edwz208 wants to merge 3 commits intomainfrom
feature/enable-edit-item-and-mobile-optimization

Conversation

@Edwz208
Copy link
Contributor

@Edwz208 Edwz208 commented Mar 22, 2026

No description provided.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the frontend item typings and filtering to prefer undefined over null, expands the items API client to support admin CRUD endpoints, and adds a small backend enhancement to expose box_code in public item serialization (plus some minor UI/CSS tweaks).

Changes:

  • Update catalogue filters to use undefined for “unset” values and align filter typing.
  • Replace PublicCollectionItem usage in some components with a new CollectionItem type and expand itemsApi with CRUD methods.
  • Backend: expose box_code on PublicCollectionItemSerializer.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
frontend/src/pages/public/CataloguePage.tsx Initializes catalogue filters using undefined values.
frontend/src/lib/types.ts Replaces placeholder item type(s) with ItemType/ItemStatus + new CollectionItem shape.
frontend/src/lib/filters.ts Changes filter field types and removes null from several filter params.
frontend/src/index.css Adds light-blue accent CSS variables.
frontend/src/components/layout/Header.css Hides .header-nav on small screens.
frontend/src/components/items/ItemList.tsx Switches item list typing to CollectionItem[].
frontend/src/components/items/ItemCard.tsx Switches item card typing to CollectionItem.
frontend/src/components/items/ItemDetailCard.tsx Adds a new item details card component.
frontend/src/components/items/DetailRow.tsx Adds a new reusable detail row component.
frontend/src/components/items/CatalogueSearchBar.tsx Uses undefined instead of null when clearing filters; adjusts search input handling.
frontend/src/components/common/Button.tsx Adds hideMobile prop to hide buttons on small screens.
frontend/src/api/items.api.ts Adds create/update/patch methods and changes item response typing/endpoint usage.
frontend/src/actions/useItems.ts Minor cleanup of queryFn comment.
backend/inventory/serializers.py Adds box_code to the public item serializer output.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +50 to 63
export interface CollectionItem {
id: number;
item_code: string;
title: string;
platform: string;
description: string;
item_type?: ItemType;
condition?: ConditionType;
is_complete?: CompletenessType;
is_functional?: CompletenessType;
date_of_entry?: string;
working_condition?: boolean;
status?: 'AVAILABLE' | 'IN_TRANSIT' | 'CHECKED_OUT' | 'MAINTENANCE';
item_type: ItemType;
working_condition: boolean;
status: ItemStatus;
current_location: LocationInfo | number | null;
is_public_visible: boolean;
is_on_floor: boolean;
location_name?: string;
current_location?: LocationInfo;
box_code?: string;
created_at?: string;
updated_at?: string;
// Software-specific fields
creator_publisher?: string;
release_year?: string;
version_edition?: string;
media_type?: string;
// Hardware-specific fields
manufacturer?: string;
model_number?: string;
year_manufactured?: string;
serial_number?: string;
hardware_type?: string;
// Non-Electronic-specific fields
item_subtype?: string;
date_published?: string;
publisher?: string;
volume_number?: string;
isbn_catalogue_number?: string;
box: BoxSummary | number | null;
}
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CollectionItem is now used as the frontend item shape, but it doesn’t match the backend responses consumed by this PR: /inventory/public/items/ (PublicCollectionItemSerializer) does not include is_public_visible or box, and instead includes fields like location_name/box_code. This makes required fields (is_public_visible, box) effectively undefined at runtime and also removes the PublicCollectionItem type that existing pages still import. Consider reintroducing a separate PublicCollectionItem type (matching PublicCollectionItemSerializer) and/or making the extra fields optional, and update API typings accordingly so public vs admin endpoints are clearly separated.

Copilot uses AI. Check for mistakes.
Comment on lines +27 to +50
getAll: async (params?: ItemFilter): Promise<CollectionItem[]> => {
const queryParams: Record<string, string> = {};

if (params?.platform) queryParams.platform = params.platform;
if (params?.is_on_floor !== undefined && params?.is_on_floor !== null)
if (params?.is_on_floor !== undefined && params?.is_on_floor !== null) {
queryParams.is_on_floor = params.is_on_floor ? 'true' : 'false';
}
if (params?.search) queryParams.search = params.search;
if (params?.ordering) queryParams.ordering = params.ordering;
if (params?.item_type) queryParams.item_type = params.item_type;
if (params?.status) queryParams.status = params.status;
if (params?.location_type) queryParams.location_type = params.location_type;

// Fetch all items by setting a large page size

queryParams.page_size = '10000';

const response = await apiClient.get('/inventory/public/items/', { params: queryParams });
return response.data.results ?? response.data;
const response = await apiClient.get('/inventory/public/items/', {
params: queryParams,
});

const data = response.data;

if (Array.isArray(data)) return data;
if (data?.results && Array.isArray(data.results)) return data.results;
return [];
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getAll() is calling the public endpoint (/inventory/public/items/) but is typed to return CollectionItem[] (which includes admin-only fields like is_public_visible and box). Either change the return type to a public item type (matching the public serializer), or route admin callers to /inventory/items/ and keep public/admin APIs separate to avoid incorrect assumptions in the UI.

Copilot uses AI. Check for mistakes.
getById: async (id: string | number): Promise<PublicCollectionItem> => {
const response = await apiClient.get(`/inventory/public/items/${id}/`);
getById: async (id: string | number): Promise<CollectionItem> => {
const response = await apiClient.get(`/inventory/items/${id}/`);
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getById() now targets /inventory/items/{id}/, but the backend CollectionItemViewSet uses CollectionItemSerializer for retrieve, which returns current_location (and box) as primary keys rather than nested objects. If any UI expects current_location.name etc., this will break. Consider either (a) updating the backend to use AdminCollectionItemSerializer for retrieve as well, or (b) normalizing the response client-side and typing getById accordingly.

Suggested change
const response = await apiClient.get(`/inventory/items/${id}/`);
const response = await apiClient.get(`/inventory/public/items/${id}/`);

Copilot uses AI. Check for mistakes.
Comment on lines 126 to 129
current_location = LocationSerializer(read_only=True)
location_name = serializers.SerializerMethodField()
box_code = serializers.CharField(source="box.box_code", read_only=True)

Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding box_code = serializers.CharField(source='box.box_code', ...) will cause an extra DB query per item unless the queryset selects the related box. The current public viewset queryset selects current_location but not box, so this introduces an N+1 query pattern for public catalogue list/detail responses. Update the public queryset to select_related('current_location', 'box') (or otherwise prefetch) to keep performance stable.

Copilot uses AI. Check for mistakes.
Comment on lines 1 to +8
export interface ItemFilter {
search?: string | null;
platform?: string | null;
platform?: string;
is_on_floor?: boolean | null;
ordering?: string | null;
item_type?: 'SOFTWARE' | 'HARDWARE' | null;
status?: 'AVAILABLE' | 'IN_TRANSIT' | 'CHECKED_OUT' | 'MAINTENANCE' | null;
location_type?: 'FLOOR' | 'STORAGE' | 'EVENT' | 'OTHER' | null;
search?: string;
ordering?: string;
item_type?: string;
status?: string;
location_type?: string;
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ItemFilter widened item_type, status, and location_type to plain string, even though this repo already defines constrained unions (ItemType, ItemStatus, and the location_type union in LocationInfo). This removes compile-time validation for filter values and makes it easier to accidentally send unsupported params to the API. Prefer reusing those existing union types (and keeping | undefined instead of | null where needed).

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants