[offers][fix] fix profile page mobile compatible style ()

* [offers][fix] fix offer profile page mobile compatibility

* [offers][style] style profile offer card
pull/490/head
Zhang Ziqing 2 years ago committed by GitHub
parent 21c9d9410a
commit 6682d81d2e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -128,7 +128,7 @@ export default function OfferCard({
); );
} }
return ( return (
<div className="mx-8 my-4 block rounded-lg bg-white py-4 shadow-md"> <div className="mx-8 my-4 block rounded-md border-b border-gray-300 bg-white py-4">
<UpperSection /> <UpperSection />
<BottomSection /> <BottomSection />
</div> </div>

@ -110,108 +110,115 @@ export default function ProfileComments({
); );
} }
return ( return (
<div className="m-4 h-full"> <div className="bh-white h-fit px-4 md:h-[calc(100vh-4.5rem)] md:overflow-y-auto">
<div className="flex-end flex justify-end space-x-4"> <div className="bg-white pt-4 md:sticky md:top-0">
{isEditable && ( <div className="flex justify-end">
<Tooltip tooltipContent="Copy this link to edit your profile later"> <div className="grid w-fit space-y-2 md:grid-cols-1 lg:grid-cols-2 lg:space-y-0 lg:space-x-4">
<Button <div className="col-span-1 flex justify-end">
addonPosition="start" {isEditable && (
disabled={isDisabled} <Tooltip tooltipContent="Copy this link to edit your profile later">
icon={ClipboardDocumentIcon} <Button
isLabelHidden={false} addonPosition="start"
label="Copy profile edit link" disabled={isDisabled}
size="sm" icon={ClipboardDocumentIcon}
variant="secondary" isLabelHidden={false}
onClick={() => { label="Copy edit link"
copyProfileLink(profileId, token); size="sm"
gaEvent({ variant="secondary"
action: 'offers.copy_profile_edit_link', onClick={() => {
category: 'engagement', copyProfileLink(profileId, token);
label: 'Copy Profile Edit Link', gaEvent({
}); action: 'offers.copy_profile_edit_link',
showToast({ category: 'engagement',
title: `Profile edit link copied to clipboard!`, label: 'Copy Profile Edit Link',
variant: 'success', });
}); showToast({
}} title: `Profile edit link copied to clipboard!`,
variant: 'success',
});
}}
/>
</Tooltip>
)}
</div>
<div className="col-span-1 flex justify-end">
<Tooltip tooltipContent="Share this profile with your friends">
<Button
addonPosition="start"
disabled={isDisabled}
icon={ShareIcon}
isLabelHidden={false}
label="Copy public link"
size="sm"
variant="secondary"
onClick={() => {
copyProfileLink(profileId);
gaEvent({
action: 'offers.copy_profile_public_link',
category: 'engagement',
label: 'Copy Profile Public Link',
});
showToast({
title: `Public profile link copied to clipboard!`,
variant: 'success',
});
}}
/>
</Tooltip>
</div>
</div>
</div>
<h2 className="mt-2 mb-6 text-2xl font-bold">Discussions</h2>
{isEditable || session?.user?.name ? (
<div>
<TextArea
label={`Comment as ${
isEditable ? profileName : session?.user?.name ?? 'anonymous'
}`}
placeholder="Type your comment here"
value={currentReply}
onChange={(value) => setCurrentReply(value)}
/> />
</Tooltip> <div className="mt-2 flex w-full justify-end">
)} <div className="w-fit">
<Tooltip tooltipContent="Share this profile with your friends"> <Button
disabled={
commentsQuery.isLoading ||
!currentReply.length ||
createCommentMutation.isLoading
}
display="block"
isLabelHidden={false}
isLoading={createCommentMutation.isLoading}
label="Comment"
size="sm"
variant="primary"
onClick={() => handleComment(currentReply)}
/>
</div>
</div>
<HorizontalDivider />
</div>
) : (
<Button <Button
addonPosition="start" className="mb-5"
disabled={isDisabled} display="block"
icon={ShareIcon} href={loginPageHref()}
isLabelHidden={false} label="Sign in to join discussion"
label="Copy public link" variant="tertiary"
size="sm"
variant="secondary"
onClick={() => {
copyProfileLink(profileId);
gaEvent({
action: 'offers.copy_profile_public_link',
category: 'engagement',
label: 'Copy Profile Public Link',
});
showToast({
title: `Public profile link copied to clipboard!`,
variant: 'success',
});
}}
/> />
</Tooltip> )}
</div> </div>
<h2 className="mt-2 mb-6 text-2xl font-bold">Discussions</h2> <div className="h-full w-full">
{isEditable || session?.user?.name ? ( {replies?.map((reply: Reply) => (
<div> <ExpandableCommentCard
<TextArea key={reply.id}
label={`Comment as ${ comment={reply}
isEditable ? profileName : session?.user?.name ?? 'anonymous' profileId={profileId}
}`} token={isEditable ? token : undefined}
placeholder="Type your comment here"
value={currentReply}
onChange={(value) => setCurrentReply(value)}
/> />
<div className="mt-2 flex w-full justify-end"> ))}
<div className="w-fit">
<Button
disabled={
commentsQuery.isLoading ||
!currentReply.length ||
createCommentMutation.isLoading
}
display="block"
isLabelHidden={false}
isLoading={createCommentMutation.isLoading}
label="Comment"
size="sm"
variant="primary"
onClick={() => handleComment(currentReply)}
/>
</div>
</div>
<HorizontalDivider />
</div>
) : (
<Button
className="mb-5"
display="block"
href={loginPageHref()}
label="Sign in to join discussion"
variant="tertiary"
/>
)}
<div className="h-full overflow-y-auto">
<div className="h-content mb-96 w-full">
{replies?.map((reply: Reply) => (
<ExpandableCommentCard
key={reply.id}
comment={reply}
profileId={profileId}
token={isEditable ? token : undefined}
/>
))}
</div>
</div> </div>
</div> </div>
); );

@ -65,7 +65,7 @@ export default function ProfileHeader({
{ profileId: offerProfileId as string, userId: session?.user?.id }, { profileId: offerProfileId as string, userId: session?.user?.id },
], ],
{ {
onSuccess: (res) => { onSuccess: (res: boolean) => {
setSaved(res); setSaved(res);
}, },
}, },
@ -233,57 +233,60 @@ export default function ProfileHeader({
const { experiences, totalYoe, specificYoes, profileName } = background; const { experiences, totalYoe, specificYoes, profileName } = background;
return ( return (
<div className="h-40 bg-white p-4"> <div className="grid-rows-2 bg-white p-4">
<div className="justify-left flex h-1/2"> <div className="flex grid grid-cols-5 md:grid-cols-7">
<div className="mx-4 mt-2 h-16 w-16"> <div className="jsutify-start col-span-5 flex">
<ProfilePhotoHolder /> <div className="ml-0 mr-2 mt-2 h-16 w-16 md:mx-4">
</div> <ProfilePhotoHolder />
<div className="w-full"> </div>
<div className="justify-left flex flex-1"> <div>
<h2 className="flex w-4/5 text-2xl font-bold"> <h2 className="flex text-2xl font-bold">
{profileName ?? 'anonymous'} {profileName ?? 'anonymous'}
</h2> </h2>
{isEditable && ( {(experiences[0]?.companyName ||
<div className="flex h-8 w-1/5 justify-end"> experiences[0]?.jobLevel ||
{renderActionList()} experiences[0]?.jobTitle) && (
<div className="flex flex-row">
<span>
<BuildingOffice2Icon className="mr-2.5 h-5 w-5" />
</span>
<p>
<span className="mr-2 font-bold">Current:</span>
{`${experiences[0].companyName || ''} ${
experiences[0].jobLevel || ''
} ${experiences[0].jobTitle || ''} ${
experiences[0].jobType
? `(${JobTypeLabel[experiences[0].jobType]})`
: ''
}`}
</p>
</div> </div>
)} )}
</div>
{(experiences[0]?.companyName ||
experiences[0]?.jobLevel ||
experiences[0]?.jobTitle) && (
<div className="flex flex-row"> <div className="flex flex-row">
<BuildingOffice2Icon className="mr-2.5 h-5" /> <CalendarDaysIcon className="mr-2.5 h-5" />
<span className="mr-2 font-bold">Current:</span> <p>
<span> <span className="mr-2 font-bold">YOE:</span>
{`${experiences[0].companyName || ''} ${ <span className="mr-4">{totalYoe}</span>
experiences[0].jobLevel || '' {specificYoes &&
} ${experiences[0].jobTitle || ''} ${ specificYoes.length > 0 &&
experiences[0].jobType specificYoes.map(({ domain, yoe }) => {
? `(${JobTypeLabel[experiences[0].jobType]})` return (
: '' <span
}`} key={domain}
</span> className="mr-4">{`${domain}: ${yoe}`}</span>
);
})}
</p>
</div> </div>
)}
<div className="flex flex-row">
<CalendarDaysIcon className="mr-2.5 h-5" />
<span className="mr-2 font-bold">YOE:</span>
<span className="mr-4">{totalYoe}</span>
{specificYoes &&
specificYoes.length > 0 &&
specificYoes.map(({ domain, yoe }) => {
return (
<span
key={domain}
className="mr-4">{`${domain}: ${yoe}`}</span>
);
})}
</div> </div>
</div> </div>
{isEditable && (
<div className="col-span-2 col-end-6 flex h-8 justify-end md:col-end-8 md:pt-0">
{renderActionList()}
</div>
)}
</div> </div>
<div className="mt-4">
<div className="mt-8">
<Tabs <Tabs
label="Profile Detail Navigation" label="Profile Detail Navigation"
tabs={profileDetailTabs} tabs={profileDetailTabs}

@ -27,7 +27,7 @@ export default function OfferTableRow({
<td className="py-4 px-6">{formatDate(monthYearReceived)}</td> <td className="py-4 px-6">{formatDate(monthYearReceived)}</td>
<td <td
className={clsx( className={clsx(
'sticky right-0 py-4 px-6 drop-shadow md:drop-shadow-none', 'sticky right-0 bg-white px-6 py-4 drop-shadow lg:drop-shadow-none',
)}> )}>
<Link <Link
className="text-primary-600 dark:text-primary-500 font-medium hover:underline" className="text-primary-600 dark:text-primary-500 font-medium hover:underline"

@ -76,7 +76,7 @@ export default function OffersTable({
function renderFilters() { function renderFilters() {
return ( return (
<div className="m-4 flex items-center justify-between"> <div className="m-4 flex grid grid-cols-1 items-center justify-between gap-6 sm:grid-cols-4">
<DropdownMenu <DropdownMenu
align="start" align="start"
label={ label={
@ -101,7 +101,7 @@ export default function OffersTable({
/> />
))} ))}
</DropdownMenu> </DropdownMenu>
<div className="divide-x-slate-200 flex items-center space-x-4 divide-x"> <div className="divide-x-slate-200 col-span-3 flex items-center justify-end space-x-4 divide-x">
<div className="justify-left flex items-center space-x-2"> <div className="justify-left flex items-center space-x-2">
<span>View all offers in</span> <span>View all offers in</span>
<CurrencySelector <CurrencySelector

@ -1,3 +1,4 @@
import { useEffect, useState } from 'react';
import { Pagination } from '@tih/ui'; import { Pagination } from '@tih/ui';
import type { Paging } from '~/types/offers'; import type { Paging } from '~/types/offers';
@ -15,30 +16,36 @@ export default function OffersTablePagination({
startNumber, startNumber,
handlePageChange, handlePageChange,
}: OffersTablePaginationProps) { }: OffersTablePaginationProps) {
const [screenWidth, setScreenWidth] = useState(0);
useEffect(() => {
setScreenWidth(window.innerWidth);
}, []);
return ( return (
<nav <nav aria-label="Table navigation" className="p-4">
aria-label="Table navigation" <div className="flex grid grid-cols-1 items-center md:grid-cols-2">
className="flex items-center justify-between p-4"> <div className="mb-2 text-sm font-normal text-slate-500 md:mb-0">
<span className="text-sm font-normal text-slate-500"> Showing
Showing <span className="font-semibold text-slate-900">
<span className="font-semibold text-slate-900"> {` ${startNumber} - ${endNumber} `}
{` ${startNumber} - ${endNumber} `} </span>
</span> {`of `}
{`of `} <span className="font-semibold text-slate-900">
<span className="font-semibold text-slate-900"> {pagination.totalItems}
{pagination.totalItems} </span>
</span> </div>
</span> <div className="flex md:justify-end">
<Pagination <Pagination
current={pagination.currentPage + 1} current={pagination.currentPage + 1}
end={pagination.numOfPages} end={pagination.numOfPages}
label="Pagination" label="Pagination"
pagePadding={2} pagePadding={screenWidth > 500 ? 2 : 0}
start={1} start={1}
onSelect={(currPage) => { onSelect={(currPage) => {
handlePageChange(currPage - 1); handlePageChange(currPage - 1);
}} }}
/> />
</div>
</div>
</nav> </nav>
); );
} }

@ -3,7 +3,7 @@ import { signIn, useSession } from 'next-auth/react';
import { useState } from 'react'; import { useState } from 'react';
import { Button, Spinner } from '@tih/ui'; import { Button, Spinner } from '@tih/ui';
import DashboardOfferCard from '~/components/offers/dashboard/DashboardProfileCard'; import DashboardProfileCard from '~/components/offers/dashboard/DashboardProfileCard';
import { trpc } from '~/utils/trpc'; import { trpc } from '~/utils/trpc';
@ -69,7 +69,7 @@ export default function ProfilesDashboard() {
</div> </div>
)} )}
{!userProfilesQuery.isLoading && ( {!userProfilesQuery.isLoading && (
<div className="mt-8 overflow-y-auto"> <div className="overflow-y-auto py-8">
<h1 className="mx-auto mb-4 w-3/4 text-start text-4xl font-bold text-slate-900"> <h1 className="mx-auto mb-4 w-3/4 text-start text-4xl font-bold text-slate-900">
Your dashboard Your dashboard
</h1> </h1>
@ -83,7 +83,7 @@ export default function ProfilesDashboard() {
<li <li
key={profile.id} key={profile.id}
className="overflow-hidden bg-white px-4 py-4 shadow sm:rounded-md sm:px-6"> className="overflow-hidden bg-white px-4 py-4 shadow sm:rounded-md sm:px-6">
<DashboardOfferCard key={profile.id} profile={profile} /> <DashboardProfileCard key={profile.id} profile={profile} />
</li> </li>
))} ))}
</ul> </ul>

@ -202,17 +202,19 @@ export default function OfferProfile() {
</div> </div>
)} )}
{!getProfileQuery.isLoading && !getProfileQuery.isError && ( {!getProfileQuery.isLoading && !getProfileQuery.isError && (
<div className="mb-4 flex flex h-screen w-screen items-center justify-center divide-x"> <div className="h-fuill flex grid w-full grid-cols-1 items-center justify-center divide-x overflow-y-auto md:grid-cols-3">
<div className="h-full w-2/3 divide-y"> <div className="col-span-1 flex h-full flex-col divide-y md:col-span-2 md:overflow-y-auto">
<ProfileHeader <div className="h-fit md:sticky md:top-0">
background={background} <ProfileHeader
handleDelete={handleDelete} background={background}
isEditable={isEditable} handleDelete={handleDelete}
isLoading={getProfileQuery.isLoading} isEditable={isEditable}
selectedTab={selectedTab} isLoading={getProfileQuery.isLoading}
setSelectedTab={setSelectedTab} selectedTab={selectedTab}
/> setSelectedTab={setSelectedTab}
<div className="h-4/5 w-full overflow-y-scroll pb-32"> />
</div>
<div className="pb-4">
<ProfileDetails <ProfileDetails
analysis={analysis} analysis={analysis}
background={background} background={background}
@ -224,7 +226,7 @@ export default function OfferProfile() {
/> />
</div> </div>
</div> </div>
<div className="h-full w-1/3 bg-white"> <div className="col-span-1 h-full bg-white">
<ProfileComments <ProfileComments
isDisabled={deleteMutation.isLoading} isDisabled={deleteMutation.isLoading}
isEditable={isEditable} isEditable={isEditable}

Loading…
Cancel
Save