365 lines
14 KiB
TypeScript
365 lines
14 KiB
TypeScript
import { Fragment } from 'react'
|
|
import { Menu, Popover, Transition } from '@headlessui/react'
|
|
import {
|
|
ChatAltIcon,
|
|
CodeIcon,
|
|
DotsVerticalIcon,
|
|
EyeIcon,
|
|
FlagIcon,
|
|
PlusSmIcon,
|
|
SearchIcon,
|
|
ShareIcon,
|
|
StarIcon,
|
|
ThumbUpIcon,
|
|
} from '@heroicons/react/solid'
|
|
import {
|
|
BellIcon,
|
|
FireIcon,
|
|
HomeIcon,
|
|
MenuIcon,
|
|
TrendingUpIcon,
|
|
UserGroupIcon,
|
|
XIcon,
|
|
} from '@heroicons/react/outline'
|
|
import clsx from 'clsx'
|
|
|
|
const user = {
|
|
name: 'Chelsea Hagon',
|
|
email: 'chelsea.hagon@example.com',
|
|
imageUrl:
|
|
'https://images.unsplash.com/photo-1550525811-e5869dd03032?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
|
|
}
|
|
const navigation = [
|
|
{ name: 'Home', href: '#', icon: HomeIcon, current: true },
|
|
{ name: 'Popular', href: '#', icon: FireIcon, current: false },
|
|
{ name: 'Communities', href: '#', icon: UserGroupIcon, current: false },
|
|
{ name: 'Trending', href: '#', icon: TrendingUpIcon, current: false },
|
|
]
|
|
const userNavigation = [
|
|
{ name: 'Your Profile', href: '#' },
|
|
{ name: 'Settings', href: '#' },
|
|
{ name: 'Sign out', href: '#' },
|
|
]
|
|
const communities = [
|
|
{ name: 'Movies', href: '#' },
|
|
{ name: 'Food', href: '#' },
|
|
{ name: 'Sports', href: '#' },
|
|
{ name: 'Animals', href: '#' },
|
|
{ name: 'Science', href: '#' },
|
|
{ name: 'Dinosaurs', href: '#' },
|
|
{ name: 'Talents', href: '#' },
|
|
{ name: 'Gaming', href: '#' },
|
|
]
|
|
const tabs = [
|
|
{ name: 'Recent', href: '#', current: true },
|
|
{ name: 'Most Liked', href: '#', current: false },
|
|
{ name: 'Most Answers', href: '#', current: false },
|
|
]
|
|
const questions = [
|
|
{
|
|
id: '81614',
|
|
likes: '29',
|
|
replies: '11',
|
|
views: '2.7k',
|
|
author: {
|
|
name: 'Dries Vincent',
|
|
imageUrl:
|
|
'https://images.unsplash.com/photo-1506794778202-cad84cf45f1d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
|
|
href: '#',
|
|
},
|
|
date: 'December 9 at 11:43 AM',
|
|
datetime: '2020-12-09T11:43:00',
|
|
href: '#',
|
|
title: 'What would you have done differently if you ran Jurassic Park?',
|
|
body: `
|
|
<p>Jurassic Park was an incredible idea and a magnificent feat of engineering, but poor protocols and a disregard for human safety killed what could have otherwise been one of the best businesses of our generation.</p>
|
|
<p>Ultimately, I think that if you wanted to run the park successfully and keep visitors safe, the most important thing to prioritize would be…</p>
|
|
`,
|
|
},
|
|
// More questions...
|
|
]
|
|
const whoToFollow = [
|
|
{
|
|
name: 'Leonard Krasner',
|
|
handle: 'leonardkrasner',
|
|
href: '#',
|
|
imageUrl:
|
|
'https://images.unsplash.com/photo-1519345182560-3f2917c472ef?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
|
|
},
|
|
// More people...
|
|
]
|
|
const trendingPosts = [
|
|
{
|
|
id: 1,
|
|
user: {
|
|
name: 'Floyd Miles',
|
|
imageUrl:
|
|
'https://images.unsplash.com/photo-1463453091185-61582044d556?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
|
|
},
|
|
body: 'What books do you have on your bookshelf just to look smarter than you actually are?',
|
|
comments: 291,
|
|
},
|
|
// More posts...
|
|
]
|
|
|
|
// Note: this is mostly useful for the mobile sidebar
|
|
export default function SideNavBar() {
|
|
/* When the mobile menu is open, add `overflow-hidden` to the `body` element to prevent double scrollbars */
|
|
return (
|
|
<Popover
|
|
as="header"
|
|
className={({ open }) =>
|
|
clsx(
|
|
open ? 'fixed inset-0 z-40 overflow-y-auto' : '',
|
|
'bg-white shadow-sm lg:static lg:overflow-y-visible'
|
|
)
|
|
}
|
|
>
|
|
{({ open }) => (
|
|
<>
|
|
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
|
<div className="relative flex justify-between lg:gap-8 xl:grid xl:grid-cols-12">
|
|
<div className="flex md:absolute md:inset-y-0 md:left-0 lg:static xl:col-span-2">
|
|
<div className="flex flex-shrink-0 items-center">
|
|
<a href="#">
|
|
<img
|
|
className="block h-8 w-auto"
|
|
src="https://tailwindui.com/img/logos/workflow-mark.svg?color=rose&shade=500"
|
|
alt="Workflow"
|
|
/>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<div className="min-w-0 flex-1 md:px-8 lg:px-0 xl:col-span-6">
|
|
<div className="flex items-center px-6 py-4 md:mx-auto md:max-w-3xl lg:mx-0 lg:max-w-none xl:px-0">
|
|
<div className="w-full">
|
|
<label htmlFor="search" className="sr-only">
|
|
Search
|
|
</label>
|
|
<div className="relative">
|
|
<div className="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
|
|
<SearchIcon
|
|
className="h-5 w-5 text-gray-400"
|
|
aria-hidden="true"
|
|
/>
|
|
</div>
|
|
<input
|
|
id="search"
|
|
name="search"
|
|
className="block w-full rounded-md border border-gray-300 bg-white py-2 pl-10 pr-3 text-sm placeholder-gray-500 focus:border-rose-500 focus:text-gray-900 focus:placeholder-gray-400 focus:outline-none focus:ring-1 focus:ring-rose-500 sm:text-sm"
|
|
placeholder="Search"
|
|
type="search"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="flex items-center md:absolute md:inset-y-0 md:right-0 lg:hidden">
|
|
{/* Mobile menu button */}
|
|
<Popover.Button className="-mx-2 inline-flex items-center justify-center rounded-md p-2 text-gray-400 hover:bg-gray-100 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-rose-500">
|
|
<span className="sr-only">Open menu</span>
|
|
{open ? (
|
|
<XIcon className="block h-6 w-6" aria-hidden="true" />
|
|
) : (
|
|
<MenuIcon className="block h-6 w-6" aria-hidden="true" />
|
|
)}
|
|
</Popover.Button>
|
|
</div>
|
|
<div className="hidden lg:flex lg:items-center lg:justify-end xl:col-span-4">
|
|
<a
|
|
href="#"
|
|
className="text-sm font-medium text-gray-900 hover:underline"
|
|
>
|
|
Go Premium
|
|
</a>
|
|
<a
|
|
href="#"
|
|
className="ml-5 flex-shrink-0 rounded-full bg-white p-1 text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-rose-500 focus:ring-offset-2"
|
|
>
|
|
<span className="sr-only">View notifications</span>
|
|
<BellIcon className="h-6 w-6" aria-hidden="true" />
|
|
</a>
|
|
|
|
{/* Profile dropdown */}
|
|
<Menu as="div" className="relative ml-5 flex-shrink-0">
|
|
<div>
|
|
<Menu.Button className="flex rounded-full bg-white focus:outline-none focus:ring-2 focus:ring-rose-500 focus:ring-offset-2">
|
|
<span className="sr-only">Open user menu</span>
|
|
<img
|
|
className="h-8 w-8 rounded-full"
|
|
src={user.imageUrl}
|
|
alt=""
|
|
/>
|
|
</Menu.Button>
|
|
</div>
|
|
<Transition
|
|
as={Fragment}
|
|
enter="transition ease-out duration-100"
|
|
enterFrom="transform opacity-0 scale-95"
|
|
enterTo="transform opacity-100 scale-100"
|
|
leave="transition ease-in duration-75"
|
|
leaveFrom="transform opacity-100 scale-100"
|
|
leaveTo="transform opacity-0 scale-95"
|
|
>
|
|
<Menu.Items className="absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
|
|
{userNavigation.map((item) => (
|
|
<Menu.Item key={item.name}>
|
|
{({ active }) => (
|
|
<a
|
|
href={item.href}
|
|
className={clsx(
|
|
active ? 'bg-gray-100' : '',
|
|
'block py-2 px-4 text-sm text-gray-700'
|
|
)}
|
|
>
|
|
{item.name}
|
|
</a>
|
|
)}
|
|
</Menu.Item>
|
|
))}
|
|
</Menu.Items>
|
|
</Transition>
|
|
</Menu>
|
|
|
|
<a
|
|
href="#"
|
|
className="ml-6 inline-flex items-center rounded-md border border-transparent bg-rose-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-rose-700 focus:outline-none focus:ring-2 focus:ring-rose-500 focus:ring-offset-2"
|
|
>
|
|
New Post
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<Popover.Panel as="nav" className="lg:hidden" aria-label="Global">
|
|
<div className="mx-auto max-w-3xl space-y-1 px-2 pt-2 pb-3 sm:px-4">
|
|
{navigation.map((item) => (
|
|
<a
|
|
key={item.name}
|
|
href={item.href}
|
|
aria-current={item.current ? 'page' : undefined}
|
|
className={clsx(
|
|
item.current
|
|
? 'bg-gray-100 text-gray-900'
|
|
: 'hover:bg-gray-50',
|
|
'block rounded-md py-2 px-3 text-base font-medium'
|
|
)}
|
|
>
|
|
{item.name}
|
|
</a>
|
|
))}
|
|
</div>
|
|
<div className="border-t border-gray-200 pt-4">
|
|
<div className="mx-auto flex max-w-3xl items-center px-4 sm:px-6">
|
|
<div className="flex-shrink-0">
|
|
<img
|
|
className="h-10 w-10 rounded-full"
|
|
src={user.imageUrl}
|
|
alt=""
|
|
/>
|
|
</div>
|
|
<div className="ml-3">
|
|
<div className="text-base font-medium text-gray-800">
|
|
{user.name}
|
|
</div>
|
|
<div className="text-sm font-medium text-gray-500">
|
|
{user.email}
|
|
</div>
|
|
</div>
|
|
<button
|
|
type="button"
|
|
className="ml-auto flex-shrink-0 rounded-full bg-white p-1 text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-rose-500 focus:ring-offset-2"
|
|
>
|
|
<span className="sr-only">View notifications</span>
|
|
<BellIcon className="h-6 w-6" aria-hidden="true" />
|
|
</button>
|
|
</div>
|
|
<div className="mx-auto mt-3 max-w-3xl space-y-1 px-2 sm:px-4">
|
|
{userNavigation.map((item) => (
|
|
<a
|
|
key={item.name}
|
|
href={item.href}
|
|
className="block rounded-md py-2 px-3 text-base font-medium text-gray-500 hover:bg-gray-50 hover:text-gray-900"
|
|
>
|
|
{item.name}
|
|
</a>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="mx-auto mt-6 max-w-3xl px-4 sm:px-6">
|
|
<a
|
|
href="#"
|
|
className="flex w-full items-center justify-center rounded-md border border-transparent bg-rose-600 px-4 py-2 text-base font-medium text-white shadow-sm hover:bg-rose-700"
|
|
>
|
|
New Post
|
|
</a>
|
|
|
|
<div className="mt-6 flex justify-center">
|
|
<a
|
|
href="#"
|
|
className="text-base font-medium text-gray-900 hover:underline"
|
|
>
|
|
Go Premium
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</Popover.Panel>
|
|
</>
|
|
)}
|
|
</Popover>
|
|
)
|
|
}
|
|
|
|
export function Sidebar() {
|
|
return (
|
|
<nav aria-label="Sidebar" className="sticky top-4 divide-y divide-gray-300">
|
|
<div className="space-y-1 pb-8">
|
|
{navigation.map((item) => (
|
|
<a
|
|
key={item.name}
|
|
href={item.href}
|
|
className={clsx(
|
|
item.current
|
|
? 'bg-gray-200 text-gray-900'
|
|
: 'text-gray-600 hover:bg-gray-50',
|
|
'group flex items-center rounded-md px-3 py-2 text-sm font-medium'
|
|
)}
|
|
aria-current={item.current ? 'page' : undefined}
|
|
>
|
|
<item.icon
|
|
className={clsx(
|
|
item.current
|
|
? 'text-gray-500'
|
|
: 'text-gray-400 group-hover:text-gray-500',
|
|
'-ml-1 mr-3 h-6 w-6 flex-shrink-0'
|
|
)}
|
|
aria-hidden="true"
|
|
/>
|
|
<span className="truncate">{item.name}</span>
|
|
</a>
|
|
))}
|
|
</div>
|
|
<div className="pt-10">
|
|
<p
|
|
className="px-3 text-xs font-semibold uppercase tracking-wider text-gray-500"
|
|
id="communities-headline"
|
|
>
|
|
My communities
|
|
</p>
|
|
<div className="mt-3 space-y-2" aria-labelledby="communities-headline">
|
|
{communities.map((community) => (
|
|
<a
|
|
key={community.name}
|
|
href={community.href}
|
|
className="group flex items-center rounded-md px-3 py-2 text-sm font-medium text-gray-600 hover:bg-gray-50 hover:text-gray-900"
|
|
>
|
|
<span className="truncate">{community.name}</span>
|
|
</a>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
)
|
|
}
|