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

* [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 (
<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 />
<BottomSection />
</div>

@ -110,108 +110,115 @@ export default function ProfileComments({
);
}
return (
<div className="m-4 h-full">
<div className="flex-end flex justify-end space-x-4">
{isEditable && (
<Tooltip tooltipContent="Copy this link to edit your profile later">
<Button
addonPosition="start"
disabled={isDisabled}
icon={ClipboardDocumentIcon}
isLabelHidden={false}
label="Copy profile edit link"
size="sm"
variant="secondary"
onClick={() => {
copyProfileLink(profileId, token);
gaEvent({
action: 'offers.copy_profile_edit_link',
category: 'engagement',
label: 'Copy Profile Edit Link',
});
showToast({
title: `Profile edit link copied to clipboard!`,
variant: 'success',
});
}}
<div className="bh-white h-fit px-4 md:h-[calc(100vh-4.5rem)] md:overflow-y-auto">
<div className="bg-white pt-4 md:sticky md:top-0">
<div className="flex justify-end">
<div className="grid w-fit space-y-2 md:grid-cols-1 lg:grid-cols-2 lg:space-y-0 lg:space-x-4">
<div className="col-span-1 flex justify-end">
{isEditable && (
<Tooltip tooltipContent="Copy this link to edit your profile later">
<Button
addonPosition="start"
disabled={isDisabled}
icon={ClipboardDocumentIcon}
isLabelHidden={false}
label="Copy edit link"
size="sm"
variant="secondary"
onClick={() => {
copyProfileLink(profileId, token);
gaEvent({
action: 'offers.copy_profile_edit_link',
category: 'engagement',
label: 'Copy Profile Edit Link',
});
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>
)}
<Tooltip tooltipContent="Share this profile with your friends">
<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
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',
});
}}
className="mb-5"
display="block"
href={loginPageHref()}
label="Sign in to join discussion"
variant="tertiary"
/>
</Tooltip>
)}
</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)}
<div className="h-full w-full">
{replies?.map((reply: Reply) => (
<ExpandableCommentCard
key={reply.id}
comment={reply}
profileId={profileId}
token={isEditable ? token : undefined}
/>
<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>
);

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

@ -27,7 +27,7 @@ export default function OfferTableRow({
<td className="py-4 px-6">{formatDate(monthYearReceived)}</td>
<td
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
className="text-primary-600 dark:text-primary-500 font-medium hover:underline"

@ -76,7 +76,7 @@ export default function OffersTable({
function renderFilters() {
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
align="start"
label={
@ -101,7 +101,7 @@ export default function OffersTable({
/>
))}
</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">
<span>View all offers in</span>
<CurrencySelector

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

@ -3,7 +3,7 @@ import { signIn, useSession } from 'next-auth/react';
import { useState } from 'react';
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';
@ -69,7 +69,7 @@ export default function ProfilesDashboard() {
</div>
)}
{!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">
Your dashboard
</h1>
@ -83,7 +83,7 @@ export default function ProfilesDashboard() {
<li
key={profile.id}
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>
))}
</ul>

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

Loading…
Cancel
Save