Skip to content

Commit

Permalink
Allow featuring/unfeaturing listing from list view
Browse files Browse the repository at this point in the history
  • Loading branch information
DinerIsmail committed Oct 27, 2024
1 parent abb2bb4 commit aa7a9eb
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 7 deletions.
2 changes: 0 additions & 2 deletions app/admin/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,6 @@ export default function AdminPage() {
const { permissions, isPending: isLoadingPermissions } = usePermissions()
const { mutate: deleteListing } = useDeleteListing()

console.log('AdminPage', allowedWebs)

const allowedListings = useMemo(() => {
if (isLoadingListings || isLoadingPermissions) return null
if (isOwnerOfCurrentWeb || session.user.admin) return listings
Expand Down
25 changes: 25 additions & 0 deletions app/api/listing/[id]/feature/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import prisma from '@prisma-rw'

export async function PATCH(_request, { params }) {
try {
const listingId = Number(params.id)

const listing = await prisma.listing.update({
where: {
id: listingId,
},
data: {
featured: true,
},
})

return Response.json({
listing,
})
} catch (e) {
console.error(`[RW] Unable to feature listing - ${e}`)
return new Response(`Unable to feature listing - ${e}`, {
status: 500,
})
}
}
25 changes: 25 additions & 0 deletions app/api/listing/[id]/unfeature/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import prisma from '@prisma-rw'

export async function PATCH(_request, { params }) {
try {
const listingId = Number(params.id)

const listing = await prisma.listing.update({
where: {
id: listingId,
},
data: {
featured: false,
},
})

return Response.json({
listing,
})
} catch (e) {
console.error(`[RW] Unable to unfeature listing - ${e}`)
return new Response(`Unable to unfeature listing - ${e}`, {
status: 500,
})
}
}
32 changes: 31 additions & 1 deletion components/admin/editable-list/table/TableContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@ import {
Tag,
TagLeftIcon,
TagLabel,
IconButton,
} from '@chakra-ui/react'
import { PiWarningCircleBold } from 'react-icons/pi'
import { FaStar, FaRegStar } from 'react-icons/fa'
import useFeatureListing from '@hooks/listings/useFeatureListing'

import CategoryTag from '@components/category-tag'

const TableContent = ({ goToEdit, items, removeItem }) => {
const { featureListing, unfeatureListing } = useFeatureListing()
if (!items) return null

return (
Expand All @@ -34,6 +38,7 @@ const TableContent = ({ goToEdit, items, removeItem }) => {
</Th>
))}
<Th>Info</Th>
<Th>Featured</Th>
<Th position="sticky" right={0} bg="gray.100"></Th>
</Tr>
</Thead>
Expand Down Expand Up @@ -77,6 +82,31 @@ const TableContent = ({ goToEdit, items, removeItem }) => {
</Flex>
</Td>

<Td>
<Tooltip
borderRadius="md"
label="Display this listing at the top of the web page for 7 days."
>
<IconButton
aria-label="Toggle featured"
icon={
item.featured ? <FaStar color="green" /> : <FaRegStar />
}
colorScheme="gray"
size="md"
fontSize="20px"
isRound={true}
onClick={() => {
if (item.featured) {
unfeatureListing(item.id)
} else {
featureListing(item.id)
}
}}
/>
</Tooltip>
</Td>

<Td position="sticky" right={0} background="gray.100">
<Stack direction="column" spacing={2}>
<Button
Expand Down Expand Up @@ -111,7 +141,7 @@ export const columns = [
{
Header: 'Category',
accessor: 'category',
Cell: function StatusCell(category) {
Cell: function CategoryCell(category) {
if (!category || !category.color) return null
return (
<CategoryTag fontSize="xs" colorHex={category.color}>
Expand Down
3 changes: 1 addition & 2 deletions components/admin/listing-form/ListingForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -647,8 +647,7 @@ const ListingForm = ({ categories, listing, handleSubmit }: Props) => {
Featured
</Checkbox>
<Text color="gray.500" fontSize="sm">
Determines whether the listing is shown at the top of
the page.
Display this listing at the top of the page for 7 days.
</Text>
<FormErrorMessage>
{form.errors.featured?.toString()}
Expand Down
4 changes: 2 additions & 2 deletions hooks/listings/useCreateListing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ export default function useCreateListing() {
return useMutation({
mutationFn: createListingRequest,
onMutate: (newListing) => {
const previousListings = queryClient.getQueryData(['listings'])
const previousListings = queryClient.getQueryData(['listings', 'list'])
queryClient.setQueryData(['listings', newListing.id], newListing)
return { previousListings, newListing }
},
onError: (_err, _newListing, context) => {
queryClient.setQueryData(['listings'], context?.previousListings)
},
onSettled: () => {
void queryClient.invalidateQueries({
queryClient.invalidateQueries({
queryKey: ['listings'],
})
},
Expand Down
50 changes: 50 additions & 0 deletions hooks/listings/useFeatureListing.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { useAppContext } from '@store/hooks'

const featureListingRequest = async (id) => {
const response = await fetch(`api/listing/${id}/feature`, {
method: 'PATCH',
})

const data = await response.json()
const { listing } = data
return listing
}

const unfeatureListingRequest = async (id) => {
const response = await fetch(`api/listing/${id}/unfeature`, {
method: 'PATCH',
})

const data = await response.json()
const { listing } = data
return listing
}

export default function useFeatureListing() {
const queryClient = useQueryClient()
const { selectedWebSlug: webSlug } = useAppContext()

const { mutate: featureListing } = useMutation({
mutationFn: featureListingRequest,
onSettled: () => {
queryClient.invalidateQueries({
queryKey: ['listings', 'list', { webSlug }],
})
},
})

const { mutate: unfeatureListing } = useMutation({
mutationFn: unfeatureListingRequest,
onSettled: () => {
queryClient.invalidateQueries({
queryKey: ['listings', 'list', { webSlug }],
})
},
})

return {
featureListing,
unfeatureListing,
}
}

0 comments on commit aa7a9eb

Please sign in to comment.