updates: tagging project QA, general QA

This commit is contained in:
MTG2000
2022-10-05 13:12:47 +03:00
parent 186462659e
commit 074ce12f11
9 changed files with 84 additions and 63 deletions

View File

@@ -34,10 +34,10 @@ export default function CoverImageInput(props: Props) {
wrapperClass='h-full'
render={({ img, isUploading, isDraggingOnWindow }) =>
<div className="w-full h-full group relative ">
{!img && <div className={`w-full h-full flex flex-col justify-center items-center bg-gray-500 outline outline-2 outline-gray-200 ${props.rounded ?? 'rounded-12'}`}>
<p className="text-center text-gray-100 text-body1 md:text-h1 mb-8"><FaImage /></p>
<div className={`text-gray-100 text-center text-body4`}>
Drop a <span className="font-bold">COVER IMAGE</span> here or <br /> <span className="text-blue-300 underline">Click to browse</span>
{!img && <div className={`w-full h-full flex flex-col justify-center items-center bg-gray-100 border-dashed border-2 border-gray-200 ${props.rounded ?? 'rounded-12'}`}>
<p className="text-center text-gray-800 text-body1 md:text-h1 mb-8"><FaImage /></p>
<div className={`text-gray-700 text-center text-body4`}>
Drop a <span className="font-bold">COVER IMAGE</span> here or <br /> <span className="text-blue-400 underline">Click to browse</span>
</div>
</div>}
{img && <>
@@ -45,10 +45,10 @@ export default function CoverImageInput(props: Props) {
{!isUploading &&
<div className="flex flex-wrap gap-16 absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 ">
<button type='button' className='py-8 px-16 rounded-12 bg-black bg-opacity-70 opacity-0 group-hover:opacity-100 hover:bg-opacity-90 transition-opacity text-white text-h1'>
<button type='button' className='w-42 h-42 flex justify-center items-center rounded-full bg-gray-800 bg-opacity-60 opacity-0 group-hover:opacity-100 hover:bg-opacity-90 transition-opacity text-white text-body3'>
<CgArrowsExchangeV />
</button>
<button type='button' className='py-8 px-16 rounded-12 bg-black bg-opacity-70 opacity-0 group-hover:opacity-100 hover:bg-opacity-90 transition-opacity text-white text-h1' onClick={(e) => { e.stopPropagation(); props.onChange(null) }}>
<button type='button' className='w-42 h-42 flex justify-center items-center rounded-full bg-gray-800 bg-opacity-60 opacity-0 group-hover:opacity-100 hover:bg-opacity-90 transition-opacity text-white text-body3' onClick={(e) => { e.stopPropagation(); props.onChange(null) }}>
<IoMdClose />
</button>
</div>

View File

@@ -5,7 +5,7 @@ import Card from "src/Components/Card/Card"
export default function PostCardSkeleton() {
return <div>
<div className="flex gap-8 items-center mb-8">
<Skeleton circle width={24} height={24} />
<Skeleton circle width={32} height={32} />
<span className='flex gap-4 mt-4'>
<p className="text-gray-900 text-body5 font-medium"><Skeleton width="12ch" /></p>
</span>

View File

@@ -17,10 +17,12 @@ export default function PostCardHeader(props: Props) {
const dateToShow = () => {
const passedTime = dayjs().diff(props.date, 'hour');
if (passedTime === 0) return 'now';
if (passedTime < 24) return `${dayjs().diff(props.date, 'hour')}h ago`
return dayjs(props.date).format('MMMM DD');
const passedTimeHrs = dayjs().diff(props.date, 'hour');
const passedTimesDays = Math.ceil(passedTimeHrs / 24);
if (passedTimeHrs === 0) return 'now';
if (passedTimeHrs < 24) return `${dayjs().diff(props.date, 'hour')}h ago`
if (passedTimesDays < 29) return `${passedTimesDays} days`
return dayjs(props.date).format('DD MMM');
}
if (!props.author) return null
@@ -29,10 +31,10 @@ export default function PostCardHeader(props: Props) {
<div className="flex gap-8 items-center mb-8">
<span className='flex'>
<Link to={createRoute({ type: 'profile', id: props.author.id, username: props.author.name })}>
<Avatar width={24} src={props.author.avatar} />
<Avatar width={32} src={props.author.avatar} />
</Link>
{props.project && <Link className='-ml-12' to={createRoute({ type: "project", tag: props.project.hashtag })}>
<Avatar src={props.project.thumbnail_image} width={24} />
<Avatar src={props.project.thumbnail_image} width={32} />
</Link>}
</span>
<span className='flex gap-4'>

View File

@@ -34,7 +34,7 @@ export default function TagProjectInput({
const query = useMyProjectsQuery()
const placeholder = props.placeholder ?? <div className="flex gap-8 items-center font-medium text-gray-600"> <span className="w-32 h-32 bg-gray-50 border border-gray-100 rounded-full flex justify-center items-center"><FiPlus /></span> Tag a project </div>
const placeholder = props.placeholder ?? <div className="flex gap-8 items-center text-gray-500"> <span className="w-32 h-32 bg-gray-50 border border-gray-100 rounded-full flex justify-center items-center"><FiPlus /></span> Tag a project </div>
const handleChange = (newValue: OnChangeValue<Project, false>,) => {
props.onChange?.(newValue);

View File

@@ -79,7 +79,7 @@ export default function FeedPage() {
filterChanged={setSortByFilter}
/>
</div>
<div id="content">
<div id="content" className='pt-16 md:pt-0'>
<PostsList
isLoading={feedQuery.loading}
items={feedQuery.data?.getFeed}
@@ -88,22 +88,23 @@ export default function FeedPage() {
/>
</div>
<aside id='categories' className='no-scrollbar'>
<div className="pb-16 md:overflow-y-scroll sticky-side-element">
<h1 className="text-h2 font-bolder mb-24">Discover</h1>
<Button
href={createRoute({ type: "write-story" })}
color='primary'
fullWidth
>
Write a story
</Button>
<div className="my-24"></div>
<div className="my-24"></div>
<PopularTagsFilter
value={tagFilter}
onChange={setTagFilter as any}
/>
<div className="md:overflow-y-scroll sticky-side-element flex flex-col gap-16 md:gap-24">
<h1 className="text-h2 font-bolder order-1">Discover</h1>
<div className='order-3 md:order-2'>
<Button
href={createRoute({ type: "write-story" })}
color='primary'
fullWidth
>
Write a story
</Button>
</div>
<div className='order-2 md:order-3'>
<PopularTagsFilter
value={tagFilter}
onChange={setTagFilter as any}
/>
</div>
</div>
</aside>
<aside id='side' className='no-scrollbar'>

View File

@@ -36,7 +36,7 @@
.grid {
display: grid;
// grid-template-columns: 1fr;
gap: 32px;
gap: 16px;
& > * {
min-width: 0;
@@ -44,8 +44,8 @@
grid-template-areas:
"title"
"sort-by"
"categories"
"sort-by"
"content";
:global {
@@ -69,6 +69,7 @@
}
@media screen and (min-width: 768px) {
gap: 32px;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: auto auto 1fr;

View File

@@ -15,12 +15,13 @@ interface Props {
export default function PostPageHeader(props: Props) {
const dateToShow = () => {
const passedTime = dayjs().diff(props.date, 'hour');
if (passedTime === 0) return 'now';
if (passedTime < 24) return `${dayjs().diff(props.date, 'hour')}h ago`
return dayjs(props.date).format('MMMM DD');
const passedTimeHrs = dayjs().diff(props.date, 'hour');
const passedTimesDays = Math.ceil(passedTimeHrs / 24);
if (passedTimeHrs === 0) return 'now';
if (passedTimeHrs < 24) return `${dayjs().diff(props.date, 'hour')}h ago`
if (passedTimesDays < 29) return `${passedTimesDays} days`
return dayjs(props.date).format('DD MMM');
}
if (!props.author) return null
@@ -47,7 +48,7 @@ export default function PostPageHeader(props: Props) {
</Link>
</>}
</span>
<p className="text-body5 text-gray-500 font-medium">Published {dateToShow()}</p>
<p className="text-body5 text-gray-500">Published {dateToShow()}</p>
</div>
</div>
)

View File

@@ -7,10 +7,13 @@ import IconButton from "src/Components/IconButton/IconButton";
import { Menu, MenuItem } from "@szhsin/react-menu";
import { useAppSelector } from "src/utils/hooks";
import { useUpdateStory } from './useUpdateStory'
import { FaPen } from "react-icons/fa";
import DOMPurify from 'dompurify';
import Card from "src/Components/Card/Card";
import PostPageHeader from "../PostPageHeader/PostPageHeader";
import { FiEdit2, FiLink } from "react-icons/fi";
import CopyToClipboard from "react-copy-to-clipboard";
import { createRoute } from "src/utils/routing";
import { NotificationsService } from "src/services";
interface Props {
@@ -30,33 +33,46 @@ export default function StoryPageContent({ story }: Props) {
<>
<div id="content" className="bg-white md:p-32 md:border-2 border-gray-200 rounded-16 relative"> </div>
<Card id="content" onlyMd className="relative max">
<PostPageHeader
className="mb-16"
author={story.author}
project={story.project}
date={story.createdAt} />
<div className="flex justify-between items-center flex-wrap mb-16">
<PostPageHeader
author={story.author}
project={story.project}
date={story.createdAt} />
<div className="shrink-0 text-gray-400">
<CopyToClipboard
text={createRoute({ type: "story", title: story.title, id: story.id })}
onCopy={() => NotificationsService.info(" Copied share link to clipboard", { icon: "📋" })}
>
<IconButton>
<FiLink />
</IconButton>
</CopyToClipboard>
{curUser?.id === story.author.id && <Menu
menuClassName='!p-8 !rounded-12'
menuButton={<IconButton className="text-gray-400"><FiEdit2 /></IconButton>}>
<MenuItem
onClick={handleEdit}
className='!p-16 font-medium flex gap-16 hover:bg-gray-100 !rounded-12'
>
Edit story
</MenuItem>
<MenuItem
onClick={handleDelete}
className='!p-16 font-medium flex gap-16 hover:bg-gray-100 !rounded-12'
>
Delete
</MenuItem>
</Menu>}
</div>
</div>
{story.cover_image &&
<img src={story.cover_image}
className='w-full h-[120px] md:h-[240px] object-cover rounded-12 mb-16'
className='w-full min-h-[120px] max-h-[320px] object-cover rounded-12 mb-16'
// className='w-full object-cover rounded-12 md:rounded-16 mb-16'
alt="" />}
<div className="flex flex-col gap-24 relative">
{curUser?.id === story.author.id && <Menu
menuClassName='!p-8 !rounded-12'
menuButton={<IconButton className="absolute top-0 right-0 text-gray-400"><FaPen /></IconButton>}>
<MenuItem
onClick={handleEdit}
className='!p-16 font-medium flex gap-16 hover:bg-gray-100 !rounded-12'
>
Edit story
</MenuItem>
<MenuItem
onClick={handleDelete}
className='!p-16 font-medium flex gap-16 hover:bg-gray-100 !rounded-12'
>
Delete
</MenuItem>
</Menu>}
<h1 className="text-[42px] leading-[58px] font-bolder">{story.title}</h1>
{story.tags.length > 0 && <div className="flex flex-wrap gap-8">
{story.tags.map(tag => <Badge key={tag.id} size='sm'>

View File

@@ -18,7 +18,7 @@ export default function SkillsCard({ skills, isOwner }: Props) {
<p className="text-gray-700 text-body4">No skills added</p>
{isOwner && <Button color='primary' className='mt-16' size='sm' href='/edit-profile/roles-skills'>Add skills</Button>}
</>}
<ul className=' flex flex-wrap gap-x-8 gap-y-20'>
<ul className=' flex flex-wrap gap-8'>
{skills.map((skill) => <li key={skill.id} className="text-body5 border border-gray-200 px-12 py-4 bg-gray-100 rounded-48 font-medium">{skill.title}</li>)}
</ul>
</div>