Skip to content

Commit

Permalink
Fixes and updates (#61)
Browse files Browse the repository at this point in the history
* Jovells workflow auto sync after pr merge (#4)

* Update main.yml

* Update main.yml

* fixed protected routes issue

* added query invalidations after listing expt

* Fix nodata message when profile not finished loading and add token ID to ExpertHubCard

* refine suggested users massage when not signed in

* refined axpt-hub listings

* fixed some expts not showing in bookings page
  • Loading branch information
Jovells authored Jan 15, 2024
1 parent fc9d212 commit 49ac07a
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,21 @@ import { PROFILE_PAGE } from "./page-links";
import { HiCheckBadge, HiOutlineFire } from "react-icons/hi2";
import { Badge } from "@/components/ui/badge";
import { useUser } from "@/lib/hooks/user";
import NoData from "@/components/ui/no-data";

export default function UserList({ filters, max = 5 }: { filters?: ProfileFilters, max?: number }) {
const { fetchProfiles} = useBackend();
const {user} = useUser();
if (filters?.isNotFollowing && !user)
return <div className="pl-3">Sign in To get Suggestions</div>
return <NoData message="Sign in To get Suggestions" />

return (
<InfiniteScroll
fetcher={fetchProfiles}
queryKey={["profiles"]}
itemKey={(data: UserProfile) => data.uid}
filters={filters}
loadingComponent=" "
noDataMessage="No profiles found. Please try later"
getNextPageParam={(lastPage) => {
if(max && max<= lastPage.length) return undefined
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default function BookExpertDialogue({data}: {data: {listing: ExptListingW
const {listing, id, remainingSessions} = data;
return <Dialog >
<DialogTrigger>
<ExpertHubCard data={listing} type="modal" />
<ExpertHubCard tokenId={id} data={listing} type="modal" />
</DialogTrigger>

<DialogContent className='w-full py-0 max-h-[90vh] overflow-hidden'>
Expand Down
10 changes: 4 additions & 6 deletions frontend/nextjs/src/app/(with wallet)/dapp/bookings/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
'use client';
import React from 'react'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { Booking, BookingFilters, Content, ExpertTicket, ExptFilters, ExptListing, ReviewItem as ReviewItemProps, UserProfile } from '@/lib/types';
import { Booking, BookingFilters, Content, ExpertTicket, ExptFilters, ExptListing, ExptListingWithAuthorProfile, ReviewItem as ReviewItemProps, UserProfile } from '@/lib/types';
import ExpertHubCard from '@/components/ui/expert-hub-card';
import SessionReviewForm from './_components/session-review-form';
import BookExpert from './_components/book-expert';
Expand All @@ -12,21 +12,19 @@ import InfiniteScroll from '@/components/ui/infinite-scroller';
import useBackend from '@/lib/hooks/useBackend';

const Bookings = () => {
const {fetchBookings} = useBackend()
const {fetchBookings, fetchExpts} = useBackend()
const {user} = useUser();

return (
<div className="col-span-4">
<h4 className='text-xl text-foreground font-bold mb-5'>Bookings</h4>
<Tabs defaultValue="tokens" className="w-full mt-4">
<TabsList>
<TabsList >
<TabsTrigger value="tokens">Tokens</TabsTrigger>
<TabsTrigger value="history">History</TabsTrigger>
</TabsList>
<TabsContent value="tokens" className='pt-2'>
<div className="w-full mt-4">
<BookExpert/>
</div>
<BookExpert />
</TabsContent>
<TabsContent value="history" className='pt-2'>
<InfiniteScroll className="grid grid-cols-[1fr] md:grid-cols-[280px_1fr] gap-8 mt-4"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import NoData from '@/components/ui/no-data';
import { useRouter } from 'next/navigation';
import { BOOKINGS_PAGE } from '@/app/(with wallet)/_components/page-links';
import { useUser } from '@/lib/hooks/user';
import { useConnectModal } from '@rainbow-me/rainbowkit';



Expand All @@ -27,37 +28,62 @@ const ExpertDetails = ({ params }: { params: { slug: string } }) => {
const { fetchSingleListing, buyExpt, delistExpts } = useBackend();
const router = useRouter();
const { user } = useUser();

const cachedListings = queryClient.getQueryData(["exptListings"]) as { pages: ExptListingWithAuthorProfile[][] } | undefined

let listing: ExptListingWithAuthorProfile | undefined;

if (cachedListings) {
cachedListings.pages.find((page: ExptListingWithAuthorProfile[]) => {
listing = page.find((item) => { item.id === params.slug })
})
}
const {openConnectModal} = useConnectModal()



const { isLoading, data: listing } = useQuery({
queryKey: ["singleExptListing", params.slug],
queryFn: async () => {
const cachedListings = queryClient.getQueriesData({queryKey: ["exptListings"]}) as [queryKey: any, data: {pages: ExptListingWithAuthorProfile[][]} | undefined][]

console.log('cachedexpts', cachedListings);
let listing: ExptListingWithAuthorProfile

if (cachedListings[0]) {
cachedListings[0][1]?.pages.some((page: ExptListingWithAuthorProfile[]) => {
const found = page.find((item) => item.id === params.slug )
if (found) {
listing = found
return true
}
})
return listing! || await fetchSingleListing(params.slug)
}
else return await fetchSingleListing(params.slug)},
});



async function handleBuyExpt() {
const successful = await buyExpt(listing!);
if(successful){
if(!user){
return openConnectModal?.()
}
const tokenBoughtId = await buyExpt(listing!);
if(tokenBoughtId){
queryClient.invalidateQueries({queryKey: ['singleExptListing', params.slug]})
queryClient.setQueriesData({queryKey:['exptListings']}, (oldData: any) => {
console.log('oldData', oldData);
return {
...oldData,
pages: oldData.pages.map((page: ExptListingWithAuthorProfile[]) => {
return page.map((item) => {
if(item.id === listing?.id){
item.remainingTokenIds = item.remainingTokenIds.filter((tokenId) => tokenId !== tokenBoughtId)
}
return item

})
})
}
})
router.push(BOOKINGS_PAGE)
}
}



const { isLoading } = useQuery({
queryKey: ["", params.slug],
queryFn: () => fetchSingleListing(params.slug),
select(data) {
listing = data
return data
},
enabled: !listing,
});


async function handleDelistExpt(){
console.log('deslist not implemented yet');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { toast } from "@/components/ui/use-toast"

import { Textarea } from '@/components/ui/textarea'
import { cn, isValidFileType } from "@/lib/utils"
import { ClaimHistoryItem, NewExptListing, UserProfile } from '@/lib/types';
import { ClaimHistoryItem, ExptListingWithAuthorProfile, NewExptListing, UserProfile } from '@/lib/types';
import { Input } from '@/components/ui/input'
import {
Select,
Expand Down Expand Up @@ -102,14 +102,15 @@ const [coverPhotoPreview, setCoverPhotoPreview] = useState<string | null>(null);
tokenIds: profile.ownedExptIds?.slice(0, collectionSize) || [],
}
console.log('listing', listing)
const res = await listExpts(listing)
const finalListing = await listExpts(listing)
queryClient.setQueryData(["profile", user?.uid], (oldData: UserProfile, )=>{
return {
...oldData,
ownedExptIds: oldData.ownedExptIds?.filter((el)=>!listing.tokenIds?.includes(el))
} satisfies UserProfile
})
router.push(EXPERT_TICKET_PAGE(res))
router.push(EXPERT_TICKET_PAGE(finalListing.id))
queryClient.invalidateQueries({queryKey: ['exptListings']})

toast({
title: "You submitted the following values:",
Expand Down
25 changes: 14 additions & 11 deletions frontend/nextjs/src/app/(with wallet)/dapp/my-profile/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,17 @@ import NoData from '@/components/ui/no-data';
const Profile = () => {
// const { uid } = useParams();
const { user } = useUser();
const { fetchProfile, followUser, balances, fetchUnclaimedMent, claimMent, unfollowUser, checkFollowing } = useBackend();
const { fetchProfile, followUser, unfollowUser, checkFollowing } = useBackend();
const router = useRouter();

const isCurrentUserProfile = true

//fetch profile
const { data: profile} = useQuery({
const { data: profile, isLoading, error} = useQuery({
queryKey: ["profile", user?.uid],
queryFn: () => fetchProfile(user?.uid as string),
throwOnError: (error)=>{ console.log(error); return false}
throwOnError: (error)=>{ console.log(error); return false},
enabled: !!user?.uid
});

console.log('profile on page, uid', profile, user?.uid)
Expand Down Expand Up @@ -79,26 +80,28 @@ const Profile = () => {


//fetch followers
const { data: followers, isLoading } = useQuery({
const { data: followers } = useQuery({
queryKey: ["followers", user?.uid],
queryFn: () => fetchProfile(user?.uid as string),
enabled: !!user?.uid,
})



if (!profile && isLoading) {
return (<div className="h-screen">
<DataLoading />
</div>)
}

if(!profile){

if(!profile && error){
return <div className="h-screen">
<NoData message="Error Loading Profile"/>
</div>
}

if (!profile) {
return (<div className="h-screen">
<DataLoading />
</div>)
}


return (
<div className="">
Expand Down Expand Up @@ -161,7 +164,7 @@ const Profile = () => {
<HiOutlineTicket className="w-4 h-4 ml-1" />
{/* TODO: @jovells after refactoring, this shows as NaN sometimes. */}
{/* it doesn't show NaN when you navigate from another page, but when you refresh */}
<div className="ml-1">{profile.ownedExptIds?.length} EXPTS </div>
<div className="ml-1">{profile.ownedExptIds?.length} EXPT </div>
</div>

<div className="flex items-center text-sm text-muted">
Expand Down
16 changes: 12 additions & 4 deletions frontend/nextjs/src/components/ui/expert-hub-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ type Props = {
data: ExptListingWithAuthorProfile,
disableLink?: boolean;
type?: "link" | "modal";
tokenId?: number | string;
}


const ExpertHubCard = ({ data, disableLink = false, type = "link" }: Props) => {
const { price, imageURL, collectionName, id, authorProfile } = data
const ExpertHubCard = ({ data, tokenId, disableLink = false, type = "link" }: Props) => {
const { price, imageURL, remainingTokenIds, collectionName, id, authorProfile } = data

const CardTemplate = () => (<Card className='border border-stroke/[.1] p-4 bg-glass backdrop-blur-md min-w-[230px] hover:bg-accent-shade'>

Expand All @@ -42,14 +43,21 @@ const ExpertHubCard = ({ data, disableLink = false, type = "link" }: Props) => {
<div className="flex items-center justify-between w-full">
<div className="flex justify-between w-full">
<div className="">
<p className='text-md text-foreground'>{authorProfile.displayName}</p>
<p className='text-md text-foreground'>{authorProfile.displayName}</p>
<p className='text-sm text-muted'>@{authorProfile.username}</p>
</div>

<div className="flex h-[16px] mt-1 items-center text-accent-3">
<div >
<div className="flex justify-end items-center text-accent-3">
<p className='text-md text-muted font-semibold'>L{authorProfile.level}</p>
<HiOutlineFire className="w-4 h-4 ml-1" />
</div>
{tokenId?
<p className='text-sm text-muted'>Token Id: {tokenId}</p>
:
<p className='text-sm text-muted'>{remainingTokenIds.length} token(s)</p>
}
</div>
</div>
</div>
<div className="flex gap-2 overflow-hidden mt-3 capitalize">
Expand Down
4 changes: 2 additions & 2 deletions frontend/nextjs/src/components/ui/infinite-scroller.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type Props = {
max?: number;
Separator?: React.ReactNode;
noDataComponent?: React.ReactNode;
loadingComonent?: React.ReactNode;
loadingComponent?: React.ReactNode;
noDataMessage?: string;
} & React.HtmlHTMLAttributes<HTMLDivElement>;

Expand All @@ -39,7 +39,7 @@ export default function InfiniteScroll({
enabled,
Separator,
noDataComponent,
loadingComonent: loadingComponent,
loadingComponent,
noDataMessage='No data loaded',
...props
}: Props) {
Expand Down
Loading

0 comments on commit 49ac07a

Please sign in to comment.