Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
9f9a2f9
Initial plan
Copilot Nov 10, 2025
155efe5
Add GraphQL mutations for updateItemListing, pauseItemListing, and de…
Copilot Nov 10, 2025
c6afcd0
Implement Edit Listing UI components with full CRUD operations
Copilot Nov 10, 2025
e10d0bb
Add Storybook story for edit listing and fix linting issues
Copilot Nov 10, 2025
7541d10
Add documentation comment to container
Copilot Nov 10, 2025
ef2937d
Add comprehensive tests for Edit Listing feature and All Listings Tab…
dani-vaibhav Nov 14, 2025
f643981
Merge branch 'main' into copilot/implement-edit-listing-page
dani-vaibhav Nov 19, 2025
a2117f0
Add TypeScript binary scripts for Twilio service
dani-vaibhav Nov 19, 2025
7fc1278
Refactor tests for Edit Listing and All Listings Table components
dani-vaibhav Nov 19, 2025
6d53b42
Enhance listing state management by adding 'Active' state and updatin…
dani-vaibhav Nov 19, 2025
dab3b4c
Adjust layout spacing for Edit Listing form and create listing buttons
dani-vaibhav Nov 19, 2025
a995e6d
Merge branch 'main' into copilot/implement-edit-listing-page
dani-vaibhav Nov 19, 2025
deed697
Refactor sharer field in EditListingItemListingFields fragment to use…
dani-vaibhav Nov 19, 2025
791180e
Add exclusion for edit-listing component in coverage report
dani-vaibhav Nov 19, 2025
f685570
Refactor resolver helper functions for improved maintainability
dani-vaibhav Nov 21, 2025
0c923fb
Merge branch 'main' into copilot/implement-edit-listing-page
dani-vaibhav Nov 21, 2025
b9d4f0e
feat: enhance item listing mutations with status and error handling
dani-vaibhav Nov 24, 2025
525fe2f
Merge branch 'main' into copilot/implement-edit-listing-page
dani-vaibhav Nov 25, 2025
740091c
Merge branch 'main' into copilot/implement-edit-listing-page
dani-vaibhav Nov 25, 2025
438c293
feat: add update feature for item listings with deletion and image ha…
dani-vaibhav Nov 25, 2025
d203176
feat: update refetchQueries for listing mutations to include HomeAllL…
dani-vaibhav Nov 25, 2025
c1142fc
feat: enhance date handling in create and edit listing components
dani-vaibhav Nov 26, 2025
f73a7e9
Merge branch 'main' into copilot/implement-edit-listing-page
dani-vaibhav Nov 26, 2025
46a3715
feat: simplify edit listing URL structure by removing user ID dependency
dani-vaibhav Nov 26, 2025
94f81d1
feat: update vitest configuration to conditionally disable Storybook …
dani-vaibhav Nov 27, 2025
c3a3ce9
fix: improve code formatting and consistency in HomeTabsLayout component
dani-vaibhav Nov 27, 2025
1f25182
feat: add pnpm overrides for node-forge version to ensure compatibility
dani-vaibhav Nov 28, 2025
db5c181
fix: address code review - add ownership checks, preserve full user o…
Copilot Nov 28, 2025
ab224ef
Merge branch 'main' into copilot/implement-edit-listing-page
dani-vaibhav Dec 1, 2025
8b6b12e
fix: update node-forge version to 1.3.2 for compatibility
dani-vaibhav Dec 1, 2025
d735836
fix: update navigation routes to redirect to home page instead of /home
dani-vaibhav Dec 1, 2025
f2c0657
Merge branch 'main' into copilot/implement-edit-listing-page
dani-vaibhav Dec 5, 2025
5091e3a
Merge branch 'main' into copilot/implement-edit-listing-page
jason-t-hankins Dec 16, 2025
ecc1e59
fix test build errors
jason-t-hankins Dec 16, 2025
56e2a88
remove duplications detected by knip
jason-t-hankins Dec 16, 2025
247a74f
fix listing view error
jason-t-hankins Dec 16, 2025
449bf0a
fix edit listing for admin users
jason-t-hankins Dec 16, 2025
ccce03c
fix test files after admin change
jason-t-hankins Dec 16, 2025
ef3656b
reduce duplication in listing forms as well as listing resolver
jason-t-hankins Dec 17, 2025
aa24ebb
fix small codesmell errors
jason-t-hankins Dec 17, 2025
f700cb4
add edit listing stories and increase test coverage
jason-t-hankins Dec 17, 2025
e0251b9
reenable vitest in ui-sharethrift
jason-t-hankins Dec 17, 2025
23cc040
increase test coverage for new lines in item-listing.resolvers
jason-t-hankins Dec 18, 2025
4c6afd7
Merge branch 'main' into copilot/implement-edit-listing-page
jason-t-hankins Dec 18, 2025
d79916c
fix 'published' wording in feature file
jason-t-hankins Dec 18, 2025
d9988d3
increase coverage for create-listing
jason-t-hankins Dec 18, 2025
e546c52
fix buttons from list starte standardizing
jason-t-hankins Dec 18, 2025
72468f7
update storybook packages to 9.1.17
jason-t-hankins Dec 19, 2025
b8b1fe3
fix false knip flag
jason-t-hankins Dec 19, 2025
319e77d
increase coverage in container file
jason-t-hankins Dec 19, 2025
413dcde
add role-based unblockListing to resolver
jason-t-hankins Dec 19, 2025
53d9813
fix redundant call error, add testing coverage to item-listing.resolvers
jason-t-hankins Dec 19, 2025
201577b
update failing tests
jason-t-hankins Dec 19, 2025
f433377
Merge branch 'main' into copilot/implement-edit-listing-page
jason-t-hankins Dec 19, 2025
9769cbc
update storybook
jason-t-hankins Dec 19, 2025
fbc830d
Merge branch 'main' into copilot/implement-edit-listing-page
jason-t-hankins Dec 23, 2025
2043d0b
fix update test
jason-t-hankins Dec 23, 2025
ff5142d
update create-listing.container to use dayjs
jason-t-hankins Jan 5, 2026
90e9cf4
same dayjs change in edit listing
jason-t-hankins Jan 5, 2026
0596923
cleanup constants in edit-listing.container and fix time inconsistenc…
jason-t-hankins Jan 5, 2026
1b97b5a
set knip to ignore generated.ts files and update qs vulnerability fou…
jason-t-hankins Jan 5, 2026
a6812ab
Merge branch 'main' into copilot/implement-edit-listing-page
rohit-r-kumar Jan 6, 2026
a4130b0
Merge branch 'main' into copilot/implement-edit-listing-page
jason-t-hankins Jan 7, 2026
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
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
# Dependencies
/node_modules
**/node_modules

# Build outputs
**/dist
**/.tsbuildinfo

.DS_Store
**/coverage
# .gitignore template - https://github.com/github/gitignore/blob/main/Node.gitignore
Expand Down
1 change: 1 addition & 0 deletions apps/ui-sharethrift/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"@vitejs/plugin-react": "^4.7.0",
"@vitest/browser": "3.2.4",
"@vitest/coverage-v8": "^3.2.4",
"@vitest/runner": "^3.2.4",
"eslint": "^9.30.1",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.20",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { Row, Col, Button, Form, Input, Select, DatePicker, Space } from 'antd';
import { Row, Col, Button } from 'antd';
import type { ConfigType } from 'dayjs';
import dayjs from 'dayjs';

const { TextArea } = Input;
const { RangePicker } = DatePicker;
import { ListingFormFields } from '../shared/listing-form-fields.tsx';

interface ListingFormProps {
categories: string[];
Expand Down Expand Up @@ -34,80 +32,11 @@ export const ListingForm: React.FC<ListingFormProps> = ({
};

return (
<div className="create-listing-form-responsive">
<Space direction="vertical" size="large" style={{ width: '100%' }}>
<Form.Item
label="Title"
name="title"
rules={[
{ required: true, message: 'Title is required' },
{ max: 200, message: 'Title cannot exceed 200 characters' },
]}
>
<Input placeholder="Enter item title" />
</Form.Item>

<Form.Item
label="Location"
name="location"
rules={[
{ required: true, message: 'Location is required' },
{ max: 255, message: 'Location cannot exceed 255 characters' },
]}
>
<Input placeholder="Enter location" />
</Form.Item>

<Form.Item
label="Category"
name="category"
rules={[{ required: true, message: 'Category is required' }]}
>
<Select placeholder="Select a category">
{categories.map((category) => (
<Select.Option key={category} value={category}>
{category}
</Select.Option>
))}
</Select>
</Form.Item>

<Form.Item
label="Reservation Period"
name="sharingPeriod"
rules={[
{ required: true, message: 'Reservation period is required' },
]}
>
<RangePicker
style={{ width: '100%' }}
placeholder={['Start date', 'End date']}
disabledDate={disabledDate}
/>
</Form.Item>

<Form.Item
label="Description"
name="description"
rules={[
{ required: true, message: 'Description is required' },
{
max: maxCharacters,
message: `Description cannot exceed ${maxCharacters} characters`,
},
]}
>
<TextArea
placeholder="Describe your item"
rows={6}
showCount={{
formatter: ({ count }: { count: number }) =>
`${count}/${maxCharacters}`,
}}
/>
</Form.Item>

{/* Action Buttons */}
<ListingFormFields
categories={categories}
maxCharacters={maxCharacters}
disabledDate={disabledDate}
actions={
<Row
gutter={16}
style={{ marginTop: '24px' }}
Expand Down Expand Up @@ -143,8 +72,8 @@ export const ListingForm: React.FC<ListingFormProps> = ({
</Button>
</Col>
</Row>
</Space>
</div>
}
/>
);
};

Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import type React from 'react';
import { useState, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import { useMutation } from "@apollo/client/react";
import { useMutation } from '@apollo/client/react';
import { message } from 'antd';
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import {
CreateListing,
type CreateListingFormData,
} from './create-listing.tsx';

dayjs.extend(utc);
import {
HomeCreateListingContainerCreateItemListingDocument,
type HomeCreateListingContainerCreateItemListingMutation,
type HomeCreateListingContainerCreateItemListingMutationVariables,
ListingsPageContainerGetListingsDocument,
} from '../../../../../generated.tsx';

interface CreateListingContainerProps {
Expand Down Expand Up @@ -55,16 +60,23 @@ export const CreateListingContainer: React.FC<CreateListingContainerProps> = (
: 'Listing published successfully!',
);

// Don't navigate automatically - let user choose from modal
},
onError: (error) => {
console.error('Error creating listing:', error);
message.error('Failed to create listing. Please try again.');
},
// Refetch listings to update the cache
refetchQueries: ['GetListings'],
// Don't navigate automatically - let user choose from modal
},
);
onError: (error) => {
console.error('Error creating listing:', error);
message.error('Failed to create listing. Please try again.');
},
// Refetch listings to update the cache
refetchQueries: [{ query: ListingsPageContainerGetListingsDocument }],
});

const toUtcMidnight = (value: string): Date => {
const date = dayjs(value).utc().startOf('day');
if (!date.isValid()) {
throw new TypeError('Invalid date string provided for reservation period');
}
return date.toDate();
};

const handleSubmit = async (
formData: CreateListingFormData,
Expand All @@ -82,8 +94,8 @@ export const CreateListingContainer: React.FC<CreateListingContainerProps> = (
description: formData.description,
category: formData.category,
location: formData.location,
sharingPeriodStart: new Date(formData.sharingPeriod[0]),
sharingPeriodEnd: new Date(formData.sharingPeriod[1]),
sharingPeriodStart: toUtcMidnight(formData.sharingPeriod[0]),
sharingPeriodEnd: toUtcMidnight(formData.sharingPeriod[1]),
images: formData.images,
isDraft,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
}
.create-listing-main-responsive {
flex-direction: column !important;
gap: 16px !important;
gap: 0 !important;
align-items: center !important;
margin-bottom: 0 !important;
padding-bottom: 24px !important;
Expand All @@ -17,6 +17,7 @@
display: block !important;
justify-content: flex-start !important;
align-items: stretch !important;
margin-bottom: 32px !important;
}
.create-listing-images-responsive,
.create-listing-form-responsive {
Expand All @@ -31,21 +32,33 @@
aspect-ratio: auto !important;
height: auto !important;
min-height: 300px !important;
margin-bottom: 16px !important;
margin-bottom: 0 !important;
margin-top: 24px !important;
padding-bottom: 32px !important;
padding-bottom: 16px !important;
}
.create-listing-form-responsive {
width: 100% !important;
max-width: none !important;
margin-left: auto !important;
margin-right: auto !important;
margin-top: 0 !important;
margin-top: 24px !important;
position: relative !important;
z-index: 1 !important;
padding-top: 40px !important;
padding-top: 0 !important;
margin-bottom: 32px !important;
}
/* Ensure form labels and inputs are properly spaced */
.create-listing-form-responsive .ant-form-item {
margin-bottom: 20px !important;
}
.create-listing-form-responsive .ant-form-item-label {
padding-bottom: 4px !important;
}
.create-listing-form-responsive .ant-input,
.create-listing-form-responsive .ant-select,
.create-listing-form-responsive .ant-picker {
font-size: 16px !important; /* Prevent zoom on iOS */
}
.listing-gallery-responsive .slick-arrow {
color: var(--color-secondary, #3f8176) !important;
}
Expand Down Expand Up @@ -83,16 +96,47 @@
}

/* Add vertical spacing between buttons when they wrap */
.create-listing-buttons .ant-col {
margin-bottom: 8px !important;
.create-listing-buttons {
display: flex !important;
flex-wrap: wrap !important;
gap: 12px !important;
}
.create-listing-buttons .ant-col:last-child {

.create-listing-buttons .ant-col {
margin-bottom: 0 !important;
padding: 0 !important;
}

/* Mobile button stacking */
@media (max-width: 768px) {
.create-listing-buttons {
flex-direction: column !important;
gap: 12px !important;
}
.create-listing-buttons .ant-col {
width: 100% !important;
max-width: 100% !important;
}
.create-listing-buttons .ant-col .ant-btn {
width: 100% !important;
}
}

/* Tablet layout - wrap buttons */
@media (min-width: 769px) and (max-width: 1024px) {
.create-listing-buttons {
gap: 8px !important;
}
.create-listing-buttons .ant-col .ant-btn {
padding-left: 12px !important;
padding-right: 12px !important;
font-size: 14px !important;
}
}

.listing-gallery-responsive label,
.listing-gallery-responsive .slick-slide img,
.listing-gallery-responsive .slick-slide label,
.listing-gallery-responsive label {
.listing-gallery-responsive .slick-slide label {
max-width: none !important;
max-height: none !important;
width: 100% !important;
Expand Down Expand Up @@ -134,18 +178,41 @@
transform: scale(1.1) !important;
}

@media (max-width: 600px) {
/* Desktop layout - add padding between columns */
@media (min-width: 769px) {
.image-col {
margin-left: -16px !important;
margin-right: -16px !important;
width: calc(100% + 32px) !important;
padding-right: 32px !important;
}
.form-col {
padding-left: 32px !important;
}
}

@media (max-width: 600px) {
/* Tablet layout - add spacing */
@media (min-width: 601px) and (max-width: 768px) {
.image-col {
padding-right: 24px !important;
margin-bottom: 24px !important;
}
.form-col {
padding-left: 24px !important;
}
}

/* Mobile layout */
@media (max-width: 600px) {
.image-col {
margin-left: -16px !important;
margin-right: -16px !important;
width: calc(100% + 32px) !important;
margin-bottom: 32px !important;
padding-bottom: 0 !important;
}
.form-col {
margin-left: 0 !important;
margin-right: 0 !important;
width: 100% !important;
padding-left: 0 !important;
padding-right: 0 !important;
}
}
Loading