Skip to content

Commit

Permalink
end
Browse files Browse the repository at this point in the history
  • Loading branch information
nescioquid committed Aug 29, 2022
1 parent 70357f6 commit 00a49a9
Show file tree
Hide file tree
Showing 24 changed files with 1,225 additions and 108 deletions.
51 changes: 41 additions & 10 deletions components/Feed.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,50 @@
import React from 'react';
import { RefreshIcon } from '@heroicons/react/outline';
import Tweetbox from './Tweetbox';
import React, { useState } from 'react'
import { RefreshIcon } from '@heroicons/react/outline'
import TweetBox from './TweetBox'
import { Tweet } from '../typings'
import TweetComponent from '../components/Tweet'
import { fetchTweets } from '../utils/fetchTweets'
import toast from 'react-hot-toast'

interface Props {
tweets: Tweet[]
}

const Feed = ({ tweets: tweetsProp }: Props) => {
const [tweets, setTweets] = useState<Tweet[]>(tweetsProp)

const handleRefresh = async () => {
const refreshToast = toast.loading('Refreshing...')

const tweets = await fetchTweets()
setTweets(tweets)

toast.success('Feed Updated', {
id: refreshToast,
})
}

const Feed = () => {
return (
<div className='col-span-7 lg:col-span-5 border-x'>
<div className='max-h-screen col-span-7 overflow-scroll scrollbar-hide lg:col-span-5 border-x '>
<div className='flex items-center justify-between'>
<h1 className='p-5 text-xl font-bold bp-0'>Home</h1>
<RefreshIcon className='w-8 h-8 mt-5 mr-5 transition-all duration-500 ease-out cursor-pointer text-twitter hover:rotate-180 active:scale-125' />
<RefreshIcon
className='w-8 h-8 mt-5 mr-5 transition-all duration-500 ease-out cursor-pointer text-twitter hover:rotate-180 active:scale-125'
onClick={handleRefresh}
/>
</div>
<div>
<TweetBox setTweets={setTweets} />
</div>

{/* Feed */}
<div>
<Tweetbox />
{tweets.map((tweet) => (
<TweetComponent key={tweet._id} tweet={tweet} />
))}
</div>
</div>
);
};
)
}

export default Feed;
export default Feed
21 changes: 14 additions & 7 deletions components/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React from 'react'
import {
BellIcon,
HashtagIcon,
Expand All @@ -8,10 +8,13 @@ import {
MailIcon,
UserIcon,
HomeIcon,
} from '@heroicons/react/outline';
import SidebarRow from './SidebarRow';
} from '@heroicons/react/outline'
import SidebarRow from './SidebarRow'
import { signIn, signOut, useSession } from 'next-auth/react'

const Sidebar = () => {
const { data: session } = useSession()

return (
<div className='flex flex-col items-center col-span-2 px-4 md:items-start'>
{/* could be Nextjs Image component here */}
Expand All @@ -26,10 +29,14 @@ const Sidebar = () => {
<SidebarRow Icon={MailIcon} title={'Messages'} />
<SidebarRow Icon={BookmarkIcon} title={'Bookmarks'} />
<SidebarRow Icon={CollectionIcon} title={'Lists'} />
<SidebarRow Icon={UserIcon} title={'Sign In'} />
<SidebarRow
Icon={UserIcon}
onClick={session ? signOut : signIn}
title={session ? 'Sign Out' : 'Sign In'}
/>
<SidebarRow Icon={DotsCircleHorizontalIcon} title={'More'} />
</div>
);
};
)
}

export default Sidebar;
export default Sidebar
20 changes: 12 additions & 8 deletions components/SidebarRow.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
import React, { SVGProps } from 'react';
import React, { SVGProps } from 'react'

interface Props {
Icon: (props: SVGProps<SVGSVGElement>) => JSX.Element;
title: string;
Icon: (props: SVGProps<SVGSVGElement>) => JSX.Element
title: string
onClick?: () => {}
}

const SidebarRow = ({ Icon, title }: Props) => {
const SidebarRow = ({ Icon, title, onClick }: Props) => {
return (
<div className='flex items-center px-4 py-3 space-x-2 transition-all duration-200 rounded-full cursor-pointer group max-w-fit hover:bg-gray-100'>
<div
className='flex items-center px-4 py-3 space-x-2 transition-all duration-200 rounded-full cursor-pointer group max-w-fit hover:bg-gray-100'
onClick={() => onClick?.()}
>
<Icon className='w-6 h-6' />
<p className='hidden text-base font-light md:inline-flex group-hover:text-twitter lg:text-xl'>
{title}
</p>
</div>
);
};
)
}

export default SidebarRow;
export default SidebarRow
166 changes: 166 additions & 0 deletions components/Tweet.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import {
ChatAlt2Icon,
HeartIcon,
SwitchHorizontalIcon,
UploadIcon,
} from '@heroicons/react/outline'
import { useSession } from 'next-auth/react'
import React, { useEffect, useState } from 'react'
import toast from 'react-hot-toast'
import TimeAgo from 'react-timeago'
import { Comment, CommentBody, Tweet } from '../typings'
import { fetchComments } from '../utils/fetchComments'

interface Props {
tweet: Tweet
}

const Tweet = ({ tweet }: Props) => {
const [comments, setComments] = useState<Comment[]>([])
const [commentBoxVisible, setCommentBoxVisible] = useState<boolean>(false)
const [input, setInput] = useState<string>('')

const { data: session } = useSession()

const refreshComments = async () => {
const comments: Comment[] = await fetchComments(tweet._id)
setComments(comments)
}

useEffect(() => {
refreshComments()
}, [])

const handleSubmit = async (
e: React.MouseEvent<HTMLFormElement, MouseEvent>
) => {
e.preventDefault()
const commentToast = toast.loading('Posting Comment...')

// Comment logic
const commentInfo: CommentBody = {
text: input,
tweetId: tweet._id,
username: session?.user?.name || 'Unknown User',
profileImg: session?.user?.image || 'https://links.papareact.com/gll',
}

const result = await fetch(`/api/addComment`, {
body: JSON.stringify(commentInfo),
method: 'POST',
})

console.log('WOOHOO we made it', result)
toast.success('Comment Posted!', {
id: commentToast,
})

setInput('')
setCommentBoxVisible(false)
refreshComments()
}

return (
<div
className='flex flex-col p-5 space-x-3 border-gray-100 border-y'
key={tweet._id}
>
<div className='flex space-x-3'>
<img
className='object-cover w-10 h-10 rounded-full'
src={tweet.profileImg || 'https://links.papareact.com/gll'}
alt=''
/>
<div>
<div className='flex items-center space-x-1'>
<p className='mr-1 font-bold'>{tweet.username} </p>
<p className='hidden text-sm text-gray-500 sm:inline'>
@{tweet.username.replace(/\s+/g, '').toLowerCase()} |
</p>
<TimeAgo
className='text-sm text-gray-500'
date={tweet._createdAt}
/>
</div>

<p className='pt-1'>{tweet.text}</p>
{tweet.image && (
<img
className='object-cover m-5 mb-1 ml-0 rounded-lg shadow-sm max-h-60'
src={tweet.image}
alt=''
/>
)}
</div>
</div>
<div className='flex justify-between mt-5'>
<div
className='flex items-center space-x-3 text-gray-400 cursor-pointer'
onClick={() => session && setCommentBoxVisible(!commentBoxVisible)}
>
<ChatAlt2Icon className='w-5 h-5' />
<p>{comments.length}</p>
</div>
<div className='flex items-center space-x-3 text-gray-400 cursor-pointer'>
<SwitchHorizontalIcon className='w-5 h-5' />
</div>
<div className='flex items-center space-x-3 text-gray-400 cursor-pointer'>
<HeartIcon className='w-5 h-5' />
</div>
<div className='flex items-center space-x-3 text-gray-400 cursor-pointer'>
<UploadIcon className='w-5 h-5' />
</div>
</div>

{/* Comment Box Logic */}
{commentBoxVisible && (
<form className='flex mt-3 space-x-3' onSubmit={handleSubmit}>
<input
className='flex-1 p-2 bg-gray-100 rounded-lg outline-none'
value={input}
onChange={(e) => setInput(e.target.value)}
type='text'
placeholder='Write a comment...'
/>
<button
className='text-twitter disabled:text-gray-200'
disabled={!input}
type='submit'
>
Post
</button>
</form>
)}

{comments?.length > 0 && (
<div className='p-5 my-2 mt-5 space-y-5 overflow-y-scroll border-t border-gray-100 max-h-44'>
{comments.map((comment) => (
<div className='relative flex space-x-2' key={comment._id}>
<hr className='absolute h-8 left-5 top-10 border-x border-twitter/20' />
<img
className='object-cover mt-2 rounded-full h-7 w-7'
src={comment.profileImg}
alt=''
/>
<div>
<div className='flex items-center space-x-1'>
<p className='mr-1 font-bold'>{comment.username}</p>
<p className='hidden text-sm text-gray-500 lg:inline'>
@{comment.username.replace(/\s+/g, '').toLowerCase()} |
</p>
<TimeAgo
className='text-sm text-gray-500'
date={comment._createdAt}
/>
</div>
<p>{comment.text}</p>
</div>
</div>
))}
</div>
)}
</div>
)
}

export default Tweet
Loading

0 comments on commit 00a49a9

Please sign in to comment.