Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
0c47ac3
Initial plan
Copilot Dec 8, 2025
da4abab
Add backend block listing mutation and tests
Copilot Dec 8, 2025
b2d6bfd
Add frontend block/unblock listing UI with modals and mutations
Copilot Dec 8, 2025
f181fbd
Add access control for blocked listings and modal stories
Copilot Dec 8, 2025
d7c4c6a
Fix lint errors in modal components
Copilot Dec 8, 2025
a851a46
Address code review feedback - simplify modal and remove unused param…
Copilot Dec 8, 2025
e2a86e2
Fix sonar issues
Dec 8, 2025
e720f96
Update twilio
Dec 8, 2025
0d83de8
Update pnpm-lock.yaml
Dec 8, 2025
964647c
Update test cases
Dec 8, 2025
e7c0675
Update jws and jsonwebtoken
Dec 8, 2025
5e55f08
Update node.json
Dec 8, 2025
6d7fba8
Fixed import problem
Dec 9, 2025
e043285
Merge branch 'main' of https://github.com/simnova/sharethrift into co…
Dec 9, 2025
0c9a8a9
Update twilio
Dec 9, 2025
dd6f86e
Update import
Dec 9, 2025
bfc4680
Update import route
Dec 9, 2025
eda9272
Added test cases of ViewListingContainer
Dec 9, 2025
e973d56
Merge branch 'main' into copilot/add-block-unblock-listing-buttons-again
rohit-r-kumar Dec 9, 2025
02665e3
Potential fix for pull request finding 'Unused variable, import, func…
rohit-r-kumar Dec 9, 2025
d467702
Update test cases for coverage
Dec 9, 2025
9763e66
Update test coverage
Dec 9, 2025
0032423
Update test cases
Dec 9, 2025
099a02b
Update test cases for coverge
Dec 9, 2025
18e62b1
Update story book
Dec 9, 2025
1e4d765
Update requested changes
Dec 11, 2025
c712407
Resolved sourcery-ai comments
Dec 11, 2025
78abd26
Update
Dec 11, 2025
ca745a6
Merge branch 'main' of https://github.com/simnova/sharethrift into co…
Dec 12, 2025
2b8198d
Resolved sonar issues
Dec 12, 2025
8aad95e
Update tsconfig-base.json
Dec 12, 2025
d669c74
resolve sonar isssue
Dec 15, 2025
821267c
Resolve knip issue
Dec 15, 2025
1ab993e
Resolve sourcery-ai comment
Dec 15, 2025
acd1ffb
Resolved sourcery-ai comment
Dec 15, 2025
e44aacc
Resolved sourcery-ai comment
Dec 15, 2025
c6fa0d4
Resolve sourcery-comments
Dec 16, 2025
0802434
Update test cases and resolved sonar issues
Dec 17, 2025
3276844
Fix test cases
Dec 17, 2025
f639ed3
update test cases
Dec 17, 2025
936f3a9
Revert "update test cases"
Dec 17, 2025
ed9242e
Revert "Fix test cases"
Dec 17, 2025
e370b77
Revert "Update test cases and resolved sonar issues"
Dec 17, 2025
304416f
Rev "
Dec 17, 2025
6dff80d
Update test cases
Dec 17, 2025
d77cf25
Add test of item-listing
Dec 17, 2025
a6d46ff
Update test cases
Dec 18, 2025
0e66a1e
Update button
Dec 18, 2025
cdb96ad
Update block
Dec 18, 2025
0f093f8
Add sharer name to pop up of Unblock Listing
Dec 18, 2025
9c456ec
Resolve kip issues
Dec 18, 2025
647a5c0
Merge branch 'main' of https://github.com/simnova/sharethrift into co…
Dec 18, 2025
d8d5131
Update test cases
Dec 19, 2025
456fc6e
Solve vulnerable storybook version
Dec 19, 2025
86fcab2
Merge branch 'main' of https://github.com/simnova/sharethrift into co…
Dec 19, 2025
cca3fae
Update Comments
Dec 23, 2025
75e8067
Resolve comments
Dec 23, 2025
0018aec
Update storybook
Dec 23, 2025
ef267c9
Resolve BlockListingButton
Dec 23, 2025
bd93b20
Update event handler
Dec 23, 2025
98319d3
Update yaml
Dec 23, 2025
520f36d
Merge branch 'main' of https://github.com/simnova/sharethrift into co…
Dec 30, 2025
efd094c
Update yaml
Dec 30, 2025
f98ae57
Update express verison
Jan 5, 2026
fb43e4c
Update qs version
Jan 5, 2026
176bfab
qs package update
Jan 5, 2026
f384437
Update qs in mock
Jan 5, 2026
68143a6
Update qs
Jan 5, 2026
aca871d
Revert "qs package update"
Jan 5, 2026
0a9e08b
Revert "Update qs"
Jan 5, 2026
13ca6d2
Revert "Update qs version"
Jan 5, 2026
622f9a2
RESOLVE SYNK ISSUE
Jan 5, 2026
a5f101d
Update yaml
Jan 5, 2026
5e8e0d5
Merge branch 'main' of https://github.com/simnova/sharethrift into co…
Jan 6, 2026
403f083
Merge branch 'main' of https://github.com/simnova/sharethrift into co…
Jan 8, 2026
e0f9de4
Suggested changes done
Jan 8, 2026
98c1423
Resolce conflicts
Jan 9, 2026
90a40ed
Update yaml
Jan 9, 2026
fa1cce0
Fix Vulnerability
Jan 9, 2026
130e543
ReSolve vunerability
Jan 9, 2026
e9ec51f
Revert "ReSolve vunerability"
Jan 12, 2026
f0a9f01
Revert "Fix Vulnerability"
Jan 12, 2026
51c803f
fixed vulnerabilities (react-router-dom)
Jan 14, 2026
efdbf52
Resolve conflicts
Jan 15, 2026
8aae971
Fix pnpm-lock.yaml
Jan 15, 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
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Inline fragment (previously in admin-listings-table.fragment.graphql)
fragment AdminListingFields on ListingAll {
id
title
state
images
createdAt
sharingPeriodStart
sharingPeriodEnd
id
title
state
images
createdAt
sharingPeriodStart
sharingPeriodEnd
}

query AdminListingsTableContainerAdminListings(
Expand Down Expand Up @@ -42,5 +42,19 @@ mutation AdminListingsTableContainerDeleteListing($id: ObjectID!) {
}

mutation AdminListingsTableContainerUnblockListing($id: ObjectID!) {
unblockListing(id: $id)
unblockListing(id: $id) {
status {
success
errorMessage
}
listing {
id
title
state
images
createdAt
sharingPeriodStart
sharingPeriodEnd
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
import {
AdminListingsTableContainerAdminListingsDocument,
AdminListingsTableContainerDeleteListingDocument,
AdminListingsTableContainerUnblockListingDocument,
AdminListingsTableContainerUnblockListingDocument
} from '../../../../../../../generated.tsx';

const meta: Meta<typeof AdminListings> = {
Expand Down Expand Up @@ -56,10 +56,11 @@ const meta: Meta<typeof AdminListings> = {
},
result: {
data: {
unblockItemListing: {
__typename: 'MutationStatus',
unblockListing: {
__typename: 'BlockListingResult',
id: 'listing-1',
state: 'Published',
success: true,
errorMessage: null,
},
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { withMockApolloClient, withMockRouter } from '../../../../../../../test-
import {
AdminListingsTableContainerAdminListingsDocument,
AdminListingsTableContainerDeleteListingDocument,
AdminListingsTableContainerUnblockListingDocument,
BlockListingContainerUnblockListingDocument,
AdminListingsTableContainerUnblockListingDocument
} from '../../../../../../../generated.tsx';

const meta = {
Expand Down Expand Up @@ -49,14 +50,15 @@ const meta = {
},
{
request: {
query: AdminListingsTableContainerUnblockListingDocument,
query: BlockListingContainerUnblockListingDocument,
},
result: {
data: {
unblockItemListing: {
__typename: 'MutationStatus',
unblockListing: {
__typename: 'BlockListingResult',
id: 'listing-123',
state: 'Published',
success: true,
errorMessage: null,
},
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { useNavigate, useParams } from 'react-router-dom';
import {
AdminListingsTableContainerAdminListingsDocument,
AdminListingsTableContainerDeleteListingDocument,
AdminListingsTableContainerUnblockListingDocument,
BlockListingContainerUnblockListingDocument,
} from '../../../../../../../generated.tsx';

export function AdminViewListing(): ReactElement {
Expand All @@ -37,7 +37,7 @@ export function AdminViewListing(): ReactElement {
);

const [unblockListingMutation] = useMutation(
AdminListingsTableContainerUnblockListingDocument,
BlockListingContainerUnblockListingDocument,
);

const [deleteListingMutation] = useMutation(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import type { Meta, StoryObj } from '@storybook/react';
import { BlockListingModal } from './block-listing-modal';

const meta: Meta<typeof BlockListingModal> = {
title: 'Layouts/Home/View Listing/Block Listing Modal',
component: BlockListingModal,
parameters: {
layout: 'centered',
},
tags: ['autodocs'],
argTypes: {
visible: { control: 'boolean' },
loading: { control: 'boolean' },
onConfirm: { action: 'confirmed' },
onCancel: { action: 'cancelled' },
},
};

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
visible: true,
listingTitle: 'City Bike',
loading: false,
},
};

export const Loading: Story = {
args: {
visible: true,
listingTitle: 'City Bike',
loading: true,
},
};

export const Closed: Story = {
args: {
visible: false,
listingTitle: 'City Bike',
loading: false,
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Button, Modal } from 'antd';

interface BlockListingModalProps {
visible: boolean;
listingTitle: string;
onConfirm: () => void;
onCancel: () => void;
loading?: boolean;
}

export const BlockListingModal: React.FC<BlockListingModalProps> = ({
visible,
listingTitle,
onConfirm,
onCancel,
loading = false,
}) => {
const handleOk = () => {
onConfirm();
};

const handleCancel = () => {
onCancel();
};

return (
<Modal
title="Block Listing"
open={visible}
onCancel={handleCancel}
footer={[
<Button key="cancel" onClick={handleCancel}>
Cancel
</Button>,
<Button
key="block"
type="primary"
danger
onClick={handleOk}
loading={loading}
>
Block
</Button>,
]}
>
<p style={{ marginBottom: 16 }}>
You are about to block the listing: <strong>{listingTitle}</strong>
</p>
<p>
Are you sure you want to block this listing? This will make it
unavailable to all users except administrators.
</p>
</Modal>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
mutation BlockListingContainerBlockListing($id: ObjectID!) {
blockListing(id: $id) {
status {
success
errorMessage
}
listing {
id
state
}
}
}

mutation BlockListingContainerUnblockListing($id: ObjectID!) {
unblockListing(id: $id) {
status {
success
errorMessage
}
listing {
id
state
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import type { Meta, StoryObj } from '@storybook/react';
import {
BlockListingContainerBlockListingDocument,
BlockListingContainerUnblockListingDocument,
ViewListingDocument,
} from '../../../../../generated.tsx';
import { withMockApolloClient } from '../../../../../test-utils/storybook-decorators.tsx';
import { BlockListingButton } from './block-listing.container.tsx';

const meta: Meta<typeof BlockListingButton> = {
title: 'Containers/BlockListingButton',
component: BlockListingButton,
parameters: {
layout: 'centered',
apolloClient: {
mocks: [
{
request: {
query: BlockListingContainerBlockListingDocument,
variables: { id: 'listing-1' },
},
result: {
data: {
blockListing: {
__typename: 'ItemListing',
id: 'listing-1',
isBlocked: true,
},
},
},
},
{
request: {
query: BlockListingContainerUnblockListingDocument,
variables: { id: 'listing-1' },
},
result: {
data: {
unblockListing: {
__typename: 'ItemListing',
id: 'listing-1',
isBlocked: false,
},
},
},
},
{
request: {
query: ViewListingDocument,
variables: { id: 'listing-1' },
},
result: {
data: {
itemListing: {
__typename: 'ItemListing',
id: 'listing-1',
title: 'City Bike',
description: 'A great city bike',
category: 'Sports & Outdoors',
location: 'Toronto, ON',
state: 'Published',
images: [],
sharingPeriodStart: '2025-01-01',
sharingPeriodEnd: '2025-12-31',
createdAt: '2025-01-01T00:00:00Z',
updatedAt: '2025-01-01T00:00:00Z',
isBlocked: false,
sharer: {
__typename: 'PersonalUser',
id: 'user-1',
profile: {
firstName: 'John',
lastName: 'Doe',
},
},
},
},
},
},
],
},
},
decorators: [withMockApolloClient],
tags: ['autodocs'],
argTypes: {
listingId: { control: 'text' },
listingTitle: { control: 'text' },
isBlocked: { control: 'boolean' },
sharerName: { control: 'text' },
renderModals: { control: 'boolean' },
},
};

export default meta;
type Story = StoryObj<typeof meta>;

export const BlockButton: Story = {
args: {
listingId: 'listing-1',
listingTitle: 'City Bike',
isBlocked: false,
sharerName: 'user-1',
renderModals: true,
},
};

export const UnblockButton: Story = {
args: {
listingId: 'listing-1',
listingTitle: 'City Bike',
isBlocked: true,
sharerName: 'user-1',
renderModals: true,
},
};

export const BlockButtonWithoutModals: Story = {
args: {
listingId: 'listing-1',
listingTitle: 'City Bike',
isBlocked: false,
sharerName: 'user-1',
renderModals: false,
},
};

export const UnblockButtonWithoutModals: Story = {
args: {
listingId: 'listing-1',
listingTitle: 'City Bike',
isBlocked: true,
sharerName: 'user-1',
renderModals: false,
},
};

export const WithDefaultSharer: Story = {
args: {
listingId: 'listing-1',
listingTitle: 'Professional Camera',
isBlocked: false,
renderModals: true,
},
};
Loading
Loading