Skip to content
This repository has been archived by the owner on Apr 16, 2023. It is now read-only.

Add board header #287

Open
wants to merge 4 commits into
base: v2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added public/mock-header.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
63 changes: 6 additions & 57 deletions ui/board/Board.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,77 +2,26 @@ import { observer } from 'mobx-react'
import React from 'react'
import { Post } from '../post/Post'
import { PostForm } from '../common/PostForm'
import Link from 'next/link'
import { ChatIcon, MinusCircleIcon, PlusCircleIcon } from '@heroicons/react/solid'
import { MultiLineText } from '../common/MultiLineText'
import { WithPrimaryButtonStyling } from '../common/Primitives'
import { useBoard } from '@/states/BoardState'
import { BoardHeader } from './BoardHeader'

type BoardProps = {
showPostCreate?: boolean
followButtonType?: 'follow' | 'unfollow'
onFollowButtonClick?: () => Promise<void>
}

const FollowButton: React.FC<{ onClick: React.MouseEventHandler }> = ({ onClick }) => (
<WithPrimaryButtonStyling>
<button
onClick={onClick}
className="flex block py-2 -my-2 px-2 -mx-2 md:px-4 md:-mx-4 lg:px-6 lg:-mx-6"
>
<PlusCircleIcon width={24} />
<span className="px-2">Follow</span>
</button>
</WithPrimaryButtonStyling>
)

const UnfollowButton: React.FC<{ onClick: React.MouseEventHandler }> = ({ onClick }) => (
<WithPrimaryButtonStyling>
<button
onClick={onClick}
className="flex block py-2 -my-2 px-2 -mx-2 md:px-4 md:-mx-4 lg:px-6 lg:-mx-6"
>
<MinusCircleIcon width={24} />
<span className="px-2">Unfollow</span>
</button>
</WithPrimaryButtonStyling>
)

export const Board: React.FC<BoardProps> = observer(
({ showPostCreate = true, followButtonType = 'follow', onFollowButtonClick }) => {
const state = useBoard()

return (
<div>
<div className="flex flex-col">
<h1 className="flex-row my-4 text-med dark:text-med-dark text-2xl">
<Link href={`/board/${state.id}`} legacyBehavior>
<span className="cursor-pointer">#{state.title}</span>
</Link>
</h1>
<div className="text-med dark:text-med-dark">
<MultiLineText text={state.description ?? ''} />
</div>
<div className={'flex ml-auto'}>
{onFollowButtonClick ? (
followButtonType === 'follow' ? (
<FollowButton onClick={onFollowButtonClick} />
) : (
<UnfollowButton onClick={onFollowButtonClick} />
)
) : null}
{showPostCreate ? (
<WithPrimaryButtonStyling>
<Link href={{ pathname: `/o/cp`, query: { boardId: state.id } }} legacyBehavior>
<button className="flex block py-2 -my-2 px-2 -mx-2 md:px-4 md:-mx-4 lg:px-6 lg:-mx-6">
<ChatIcon width={24} />
<span className="px-2">New Post</span>
</button>
</Link>
</WithPrimaryButtonStyling>
) : null}
</div>
</div>
<BoardHeader
showPostCreate={showPostCreate}
followButtonType={followButtonType}
onFollowButtonClick={onFollowButtonClick}
/>
<ul>
{state.posts.map((p, idx) => (
<li key={idx} className="mb-5">
Expand Down
87 changes: 87 additions & 0 deletions ui/board/BoardHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Generate board header like twitter

import { useBoard } from '@/states/BoardState'
import React from 'react'
import Link from 'next/link'
import { MultiLineText } from '../common/MultiLineText'
import { ChatIcon, MinusCircleIcon, PlusCircleIcon } from '@heroicons/react/solid'
import { Button } from '../common/Button'

interface HeaderProps {
src?: string
}

const FollowButton: React.FC<{ onClick: React.MouseEventHandler }> = ({ onClick }) => (
<Button onClick={onClick} label="Follow" size="normal" icon={<PlusCircleIcon width={24} />} />
)

const UnfollowButton: React.FC<{ onClick: React.MouseEventHandler }> = ({ onClick }) => (
<Button onClick={onClick} label="Unfollow" size="normal" icon={<MinusCircleIcon width={24} />} />
)

const HeaderImagePlaceHolder: React.FC<HeaderProps> = (props) => {
return (
<div
className={`w-full rounded-t-xl mx-auto bg-cover bg-center h-56 bg-repeat-x bg-[url(${
props.src ?? '/mock-header.jpg'
})]`}
>
{props.children}
</div>
)
}
export type BoardHeaderProps = {
showPostCreate?: boolean
followButtonType?: 'follow' | 'unfollow'
onFollowButtonClick?: (() => Promise<void>) | undefined
}
export const BoardHeader: React.FC<BoardHeaderProps> = ({
showPostCreate = true,
followButtonType = 'follow',
onFollowButtonClick,
}) => {
const board = useBoard()
return (
<div className="py-4">
{/* TODO: add certain header image */}
<HeaderImagePlaceHolder />
<div className="w-full rounded-b-xl mx-auto bg-contentbg dark:bg-contentbg-dark h-40">
<div className="relative -top-10 -left-[220px] mx-auto">
<div
className="rounded w-20 h-20 mx-auto bg-center bg-cover"
style={{ backgroundImage: 'url(/android-chrome-512x512.png)' }}
/>
</div>
<div className="relative -top-20 left-[120px]">
<h1 className="flex-row my-1 text-med dark:text-med-dark text-2xl">
<Link href={`/board/${board.id}`} legacyBehavior>
<span className="cursor-pointer">#{board.title}</span>
</Link>
</h1>
<div className="text-med dark:text-med-dark">
<MultiLineText text={board.description ?? ''} />
</div>

<div className="relative -top-2 right-40">
<div className="flex flex-col">
<div className={'flex ml-auto'}>
{onFollowButtonClick ? (
followButtonType === 'follow' ? (
<FollowButton onClick={onFollowButtonClick} />
) : (
<UnfollowButton onClick={onFollowButtonClick} />
)
) : null}
{showPostCreate ? (
<Link href={{ pathname: `/o/cp`, query: { boardId: board.id } }} legacyBehavior>
<Button icon={<ChatIcon width={24} />} label="New Post" size="normal" />
</Link>
) : null}
</div>
</div>
</div>
</div>
</div>
</div>
)
}
2 changes: 1 addition & 1 deletion ui/common/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export interface ButtonProps {

export const Button: React.FC<ButtonProps> = (props) => {
let className =
'bg-primary dark:bg-primary-dark flex items-center justify-center md:px-4 ml-2 lg:px-6 block text-med dark:text-med-dark dark:hover:text-high-dark hover:text-high border-primary dark:border-primary-dark border-opacity-40 hover:border-opacity-100 rounded-xl border border-double border-4 transition-colors'
'bg-primary dark:bg-primary-dark flex items-center justify-center md:px-4 ml-2 lg:px-6 block text-white dark:text-med-dark dark:hover:text-high-dark hover:text-high border-primary dark:border-primary-dark border-opacity-40 hover:border-opacity-100 rounded-xl border border-double border-4 transition-colors'
if (props.size === 'small') {
className += ' px-2 text-sm'
} else if (props.size === 'normal') {
Expand Down
4 changes: 2 additions & 2 deletions ui/thread/CommentInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const CommentInput: React.FC<{ onSubmit: (comment: PostContent) => void }
const [comment, setComment] = useState<PostContent>('' as PostContent)
const userState = useUserState()
return userState != null ? (
<div className="bg-slate-100 bg-opacity-85 p-4 rounded-lg mb-20">
<div className="bg-contentbg dark:bg-contentbg-dark bg-opacity-80 p-4 rounded-lg mb-20">
<p className="pb-2 ">
Comments as {userState.currentPersona?.name ?? 'an unauthorized user'}
</p>
Expand All @@ -18,7 +18,7 @@ export const CommentInput: React.FC<{ onSubmit: (comment: PostContent) => void }
onChange={(e) => setComment(e.currentTarget.value as PostContent)}
placeholder="What did you think?"
/>
<div className="bg-slate-100 bg-opacity-25 px-4 py-2 rounded-b-lg flex justify-end">
<div className="px-4 py-2 rounded-b-lg flex justify-end">
<Button onClick={() => props.onSubmit(comment)} label="Comment" size="normal" />
</div>
</div>
Expand Down