-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
29 changed files
with
664 additions
and
130 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
|
||
|
||
import { ErrorMessage, Field } from "formik"; | ||
import { InputHTMLAttributes } from "react"; | ||
|
||
export const FormInputField = ({ | ||
fieldId, | ||
fieldLabel, | ||
placeholder, | ||
isInline, | ||
type = "text", | ||
...props | ||
}: { | ||
fieldId: string; | ||
placeholder?: string; | ||
isInline?: boolean; | ||
fieldLabel?: string; | ||
type?: string; | ||
|
||
} & InputHTMLAttributes<any>) => ( | ||
<label | ||
className={`input-group h-full w-full text-sm ${ | ||
isInline ? "flex-row" : "flex-col" | ||
}`} | ||
> | ||
{fieldLabel && <div className="label w-full pb-1">{fieldLabel}</div>} | ||
<Field | ||
name={fieldId} | ||
type={type} | ||
id={fieldId} | ||
autoComplete="off" | ||
{...props} | ||
placeholder={placeholder} | ||
className="input input-bordered px-3 min-h-full border-black bg-slate-50 w-full" | ||
/> | ||
<ErrorMessage className="text-red-500 text-xs mt-1" name={fieldId} /> | ||
</label> | ||
); |
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import { Menu } from "@headlessui/react" | ||
import Link from "next/link" | ||
import { ReactNode } from "react" | ||
import { BLOG_URL, DASHBOARD_URL, FEATURES_URL_HASH, NEW_USER_WELCOME_URL } from "../../config/ScreenRoutes" | ||
|
||
|
||
export const MainSiteNavbar = ({ leadingBlock }: { leadingBlock?: ReactNode }) => { | ||
const is_logged_in = true; | ||
|
||
return ( | ||
<div className="min-h-16 px-4 flex border-b-black border-b"> | ||
<nav className="mx-auto w-full max-w-6xl flex items-center justify-between gap-7"> | ||
{leadingBlock ? leadingBlock : <div className="font-bold text-2xl text-left flex-grow">WingMate</div>} | ||
<div className="hidden sm:flex justify-between flex-grow items-center"> | ||
<div className="flex justify-between gap-5"> | ||
<Link href={FEATURES_URL_HASH}> | ||
<div className="cursor-pointer hover:underline decoration-dashed">Features</div> | ||
</Link> | ||
<Link href={BLOG_URL}> | ||
<div className="cursor-pointer hover:underline decoration-dashed">Blog</div> | ||
</Link> | ||
|
||
</div> | ||
<div className="flex gap-3 items-center"> | ||
|
||
{is_logged_in ? | ||
<Link href={DASHBOARD_URL}> | ||
{/* Only for Authenticated User */} | ||
<div className="btn btn-sm btn-primary">Dashboard</div> | ||
</Link> | ||
: | ||
<Link href={NEW_USER_WELCOME_URL}> | ||
{/* Only for Non Authenticated User */} | ||
<div className="btn btn-sm btn-primary">Login</div> | ||
</Link>} | ||
</div> | ||
</div> | ||
|
||
<Menu> | ||
{({ open }) => ( | ||
<> | ||
<Menu.Button className='block text-sm xss:text-base sm:hidden'>{open ? 'Close' : 'Menu'}</Menu.Button> | ||
<MyDropdown is_logged_in={is_logged_in} /> | ||
</> | ||
)} | ||
|
||
</Menu> | ||
|
||
</nav> | ||
</div> | ||
|
||
) | ||
} | ||
|
||
|
||
function MyDropdown({ is_logged_in }: { is_logged_in: boolean }) { | ||
return ( | ||
<> | ||
<Menu.Items className='sm:hidden bg-base-100 absolute top-16 left-0 bottom-0 right-0 z-50'> | ||
<Menu.Item as='div' className='cursor-pointer w-full px-5 py-4 border-b border-b-black'> | ||
<Link | ||
href={FEATURES_URL_HASH} | ||
> | ||
<div className=""> | ||
Features | ||
</div> | ||
</Link> | ||
</Menu.Item> | ||
<Menu.Item as='div' className='cursor-pointer w-full px-5 py-4 border-b border-b-black'> | ||
<Link | ||
href={BLOG_URL} | ||
> | ||
<div className=""> | ||
Blog | ||
</div> | ||
</Link> | ||
</Menu.Item> | ||
|
||
{is_logged_in ? | ||
<Menu.Item as='div' className='cursor-pointer w-full px-5 py-4 border-b border-b-black'> | ||
{/* Only for Authenticated User */} | ||
|
||
<Link | ||
href={DASHBOARD_URL} | ||
> | ||
<div className=""> | ||
Dashboard | ||
</div> | ||
</Link> | ||
</Menu.Item> | ||
: | ||
<Menu.Item as='div' className='cursor-pointer w-full px-5 py-4 border-b border-b-black'> | ||
{/* Only for Non Authenticated User */} | ||
<Link | ||
href={NEW_USER_WELCOME_URL} | ||
> | ||
<div className=""> | ||
Login | ||
</div> | ||
</Link> | ||
</Menu.Item> | ||
} | ||
</Menu.Items> | ||
</> | ||
|
||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
export const UserProfileSiteLogo = ({siteTitle}: {siteTitle: string}) => ( | ||
<div className=""> | ||
<div className="flex items-center gap-2"> | ||
<div className="hidden xss:block avatar"> | ||
<div className="h-8 rounded-full"> | ||
<img src="https://unsplash.com/photos/wQLAGv4_OYs/download?ixid=MnwxMjA3fDB8MXxzZWFyY2h8MjB8fHVzZXIlMjBwcm9maWxlJTIwYWJzdHJhY3R8ZW58MHx8fHwxNjYwNTkxNzY2&force=true&w=100" /> | ||
</div> | ||
</div> | ||
<div className="flex flex-col"> | ||
<div className="font-medium text-lg">{siteTitle}</div> | ||
</div> | ||
</div> | ||
</div> | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
import { BookOpenIcon, ChatAltIcon, HeartIcon } from "@heroicons/react/solid"; | ||
import { Form, Formik } from "formik"; | ||
import { FormInputField } from "./Forms/FormInputField"; | ||
import { MainSiteNavbar } from "./Navbar.tsx/MainSiteNavbar"; | ||
import { UserProfileSiteLogo } from "./Navbar.tsx/UserProfileSiteLogo"; | ||
|
||
|
||
type CommentProp = { | ||
user_avatar: string, | ||
name: string, | ||
posted_at: string, | ||
comment: string, | ||
is_deleted: boolean, | ||
} | ||
|
||
type Props = { | ||
post: { | ||
title: string, | ||
body: string, // full markdown | ||
published_on: string, // date | ||
|
||
post_id: string; | ||
owner_id: string; | ||
|
||
liked_by: number, | ||
number_of_comments: number; | ||
cover_image_url: string, | ||
approx_read_time_in_minutes: number, | ||
}, | ||
isPostLoading: boolean | ||
loadMoreCommentsHandler: () => void, | ||
postCommentHandler: (comment: string) => void | ||
comments: CommentProp[] | ||
} | ||
|
||
export const PostsDetailedScreen = ({ post, isPostLoading, loadMoreCommentsHandler, comments, postCommentHandler }: Props) => { | ||
return (<> | ||
|
||
<MainSiteNavbar leadingBlock={ | ||
<UserProfileSiteLogo siteTitle={'heya'} /> | ||
} /> | ||
{isPostLoading ? | ||
<div className="alert max-w-3xl my-2 mx-auto alert-info">Fetching post... ⟨䷄⟩</div> | ||
: | ||
<div className="max-w-4xl mx-auto"> | ||
<img src={post.cover_image_url} className='flex-grow h-64 w-full' /> | ||
<div className="px-4"> | ||
<div className="text-4xl font-black my-5">{post.title}</div> | ||
|
||
<div className="flex items-center gap-2 text-sm text-gray-400 pt-1"> | ||
{new Date(post.published_on).toDateString()} | ||
|
||
|
||
<BookOpenIcon className='w-6' /> | ||
{post.approx_read_time_in_minutes} min read | ||
|
||
</div> | ||
|
||
<div className="text-sm text-gray-500 pt-3 pb-4"> | ||
TODO: Render markdown | ||
{post.body} | ||
</div> | ||
|
||
|
||
<div className="flex gap-5 text-xs mb-7"> | ||
<div className='flex text-pink-400 flex-col justify-center items-center'> | ||
<HeartIcon className='w-6' /> | ||
{post.liked_by} | ||
</div> | ||
<div className="flex flex-col text-blue-400 justify-center items-center"> | ||
<ChatAltIcon className='w-6' /> | ||
{post.number_of_comments} | ||
</div> | ||
</div> | ||
<CommentsUI hasMore postCommentHandler={postCommentHandler} comments={comments} loadMoreCommentsHandler={loadMoreCommentsHandler} /> | ||
|
||
</div> | ||
|
||
</div> | ||
} | ||
|
||
|
||
</> | ||
) | ||
} | ||
|
||
|
||
const CommentsUI = ({ comments, hasMore, postCommentHandler, loadMoreCommentsHandler }: { comments: CommentProp[], hasMore: boolean, loadMoreCommentsHandler: () => void, postCommentHandler: (comment: string) => void }) => { | ||
// fetch user | ||
|
||
|
||
const userAvatar = "https://unsplash.com/photos/wQLAGv4_OYs/download?ixid=MnwxMjA3fDB8MXxzZWFyY2h8MjB8fHVzZXIlMjBwcm9maWxlJTIwYWJzdHJhY3R8ZW58MHx8fHwxNjYwNTkxNzY2&force=true&w=100" | ||
const isLoggedIn = true | ||
|
||
return ( | ||
<div className="bg-base-200"> | ||
<div className="p-5"> | ||
{hasMore && <div className="text-gray-400 font-bold text-xs cursor-pointer" onClick={loadMoreCommentsHandler}>Load previous comments...</div>} | ||
|
||
{comments.map((e, indx) => ( | ||
<div className="text-sm mt-2 mb-5" key={indx}> | ||
<div className="flex items-center gap-5"> | ||
<div className="avatar"> | ||
<div className="w-10 rounded-full"> | ||
<img src={e.user_avatar} /> | ||
</div> | ||
</div> | ||
<div className="bg-base-100 rounded py-2 px-3"> | ||
<div className="font-medium space-x-2"><span>{e.name}</span> <span className="text-gray-500 text-xs">{new Date(e.posted_at).toDateString()}</span></div> | ||
<div className="text-gray-500">{e.comment}</div> | ||
</div> | ||
</div> | ||
</div> | ||
))} | ||
|
||
|
||
<Formik onSubmit={(e) => postCommentHandler(e.new_comment)} initialValues={{ new_comment: '' }}> | ||
<Form> | ||
<div className="flex gap-5 h-10 items-center"> | ||
<div className="avatar"> | ||
<div className="w-10 rounded-full"> | ||
<img src={userAvatar} /> | ||
</div> | ||
</div> | ||
<FormInputField required fieldId="new_comment" placeholder="Add comment..." /> | ||
<button className="btn btn-primary btn-sm h-full" >Submit</button> | ||
</div> | ||
</Form> | ||
|
||
</Formik> | ||
</div> | ||
</div> | ||
) | ||
|
||
} |
Oops, something went wrong.