Skip to content

Commit

Permalink
New notifications popover
Browse files Browse the repository at this point in the history
  • Loading branch information
afzalsayed96 committed Jun 16, 2024
1 parent d6f6aee commit a1fd612
Show file tree
Hide file tree
Showing 21 changed files with 4,548 additions and 2,357 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@dashx/react": "^0.0.6",
"@dashx/react": "^0.1.1",
"@headlessui/react": "^2.0.4",
"@heroicons/react": "^2.1.3",
"axios": "^1.7.2",
Expand Down Expand Up @@ -54,6 +54,7 @@
"@tailwindcss/forms": "^0.5.2",
"eslint": "^9.2.0",
"eslint-config-react-app": "^7.0.1",
"prettier": "^3.2.5",
"tailwindcss": "^3.1.3"
}
}
40 changes: 22 additions & 18 deletions public/index.html
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
<!DOCTYPE html>
<html lang="en" class="h-full bg-gray-50">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/dashx_logo.svg?v=2" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="DashX Demo App using React.js" />
<link rel="stylesheet" href="https://rsms.me/inter/inter.css" />

<!--
<head>
<meta charset="utf-8" />
<script src="https://cdn.tailwindcss.com?plugins=forms,typography"></script>
<link rel="icon" href="%PUBLIC_URL%/dashx_logo.svg?v=2" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="DashX Demo App using React.js" />
<link rel="stylesheet" href="https://rsms.me/inter/inter.css" />

<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Expand All @@ -22,12 +24,13 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>DashX Demo React</title>
</head>
<body class="h-full">
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
<title>DashX Demo React</title>
</head>

<body class="h-full">
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
Expand All @@ -37,5 +40,6 @@
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
</body>

</html>
4 changes: 4 additions & 0 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import Settings from './pages/Settings'
import DashboardLayout from './components/layouts/DashboardLayout'
import RequireUser from './components/authentication/RequireUser'
import RequireVisitor from './components/authentication/RequireVisitor'
import Logout from './pages/Logout'

const App = () => {
return (
Expand All @@ -31,6 +32,9 @@ const App = () => {
<Route path="settings" element={<Settings />} />
</Route>
</Route>
<Route element={<RequireUser />}>
<Route path="logout" element={<Logout />} />
</Route>

<Route element={<RequireVisitor />}>
<Route path="login" element={<Login />} />
Expand Down
2 changes: 1 addition & 1 deletion src/components/Avatar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const Avatar = ({ user }) => {

return (
<div className="flex items-center justify-center">
<img src={avatarUrl} className="rounded-full w-10 h-10" alt="Avatar" />
<img src={avatarUrl} className="rounded-full w-full h-full" alt="Avatar" />
</div>
)
}
Expand Down
115 changes: 47 additions & 68 deletions src/components/Navbar.jsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,34 @@
import classNames from 'classnames'
import React, { Fragment, useEffect } from 'react'
import React, { useEffect } from 'react'
import { Bars3Icon } from '@heroicons/react/24/outline'
import { Link, NavLink, useNavigate } from 'react-router-dom'
import { Link, NavLink, useMatch } from 'react-router-dom'
import { MagnifyingGlassIcon } from '@heroicons/react/24/solid'
import { Menu, MenuButton, MenuItem, MenuItems, Transition } from '@headlessui/react'
import { NotificationBell } from '@dashx/react'
import { NotificationBell } from '@dashx/react/widgets'

import Avatar from './Avatar'
import { useCurrentUserContext } from '../contexts/CurrentUserContext'

import api from '../lib/api'
import { Button, Card, Flex, Popover } from '@dashx/react'

const userNavigation = [
{ name: 'Profile', href: '/update-profile' },
{ name: 'Settings', href: '/settings' }
]

const NavItem = ({ name, href }) => {
const match = useMatch(href)

return (
<Button size="small" asChild variant="ghost" mode={match ? 'distinct' : 'subtle'}>
<NavLink key={name} to={href}>
{name}
</NavLink>
</Button>
)
}

const Navbar = ({ setSidebarOpen }) => {
const navigate = useNavigate()
const { logout, user, setUser } = useCurrentUserContext()
const { user, setUser } = useCurrentUserContext()

useEffect(() => {
const getProfile = async () => {
Expand All @@ -31,7 +41,7 @@ const Navbar = ({ setSidebarOpen }) => {

return (
<div className="md:pl-64 flex flex-col">
<div className="sticky top-0 z-10 flex-shrink-0 flex h-16 bg-white shadow">
<div className="sticky top-0 flex-shrink-0 flex h-16 bg-white shadow">
<button
type="button"
className="px-4 border-r border-gray-200 text-gray-500 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500 md:hidden"
Expand Down Expand Up @@ -60,68 +70,37 @@ const Navbar = ({ setSidebarOpen }) => {
</div>
</form>
</div>
<div className="ml-4 flex items-center md:ml-6">
<button
type="button"
className="bg-white p-1 rounded-full text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
>
<span className="sr-only">View notifications</span>
<NotificationBell />
</button>
<div className="ml-4 flex items-center md:ml-6 gap-3">
<NotificationBell />

<Menu as="div" className="ml-3 relative">
<div>
<MenuButton className="max-w-xs bg-white flex items-center text-sm rounded-full">
<span className="sr-only">Open user menu</span>
<Avatar user={user} />
</MenuButton>
</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"
>
<MenuItems className="origin-top-right absolute right-0 mt-2 w-48 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 focus:outline-none">
{userNavigation.map((item) => (
<MenuItem
key={item.name}
className="block px-4 py-2 text-sm text-gray-700 w-full text-left hover:bg-gray-100 first:rounded-t-md last:rounded-b-md"
>
{() => (
<NavLink
key={item.name}
to={item.href}
className={({ isActive }) =>
classNames(
'text-gray-300', // Default text color
{
'!bg-gray-900 !text-white': isActive,
'hover:bg-gray-100': !isActive
}
)
}
>
{item.name}
</NavLink>
)}
</MenuItem>
))}
<button
className="block px-4 py-2 flex text-sm text-gray-700 w-full text-left hover:bg-gray-100"
onClick={() => {
logout()
navigate('/login')
}}
>
<Link to="#">Logout</Link>
<Popover.Root>
<Popover.Trigger>
<Button
shape="square"
roundness="full"
aria-label="Open user menu"
mode="subtle"
asChild
>
<button className="!p-0">
<Avatar user={user} />
</button>
</MenuItems>
</Transition>
</Menu>
</Button>
</Popover.Trigger>
<Popover.Content width="200px">
<Card asChild spacing="small">
<Flex gap={1} direction="column">
{userNavigation.map((item) => (
<NavItem key={item.name} {...item} />
))}

<Button size="small" asChild variant="ghost" mode="negative">
<Link to="/logout">Logout</Link>
</Button>
</Flex>
</Card>
</Popover.Content>
</Popover.Root>
</div>
</div>
</div>
Expand Down
9 changes: 5 additions & 4 deletions src/components/Post.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import React from 'react'
import { BookmarkIcon } from '@heroicons/react/24/outline'

import dayjs from '../lib/dayjs'
import { Card } from '@dashx/react'

const Post = ({ post, toggleBookmark }) => {
const { created_at, bookmarked_at, text, user } = post
const { first_name, last_name } = user
const published = dayjs(created_at).fromNow()

return (
<div className="relative flex gap-4 mb-4 bg-gray-50 rounded shadow-md p-4 overflow-hidden">
<Card>
<img
className="h-10 w-10 rounded-full bg-gray-400 flex items-center justify-center ring-8 ring-white"
src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
Expand All @@ -24,16 +25,16 @@ const Post = ({ post, toggleBookmark }) => {
{bookmarked_at ? (
<BookmarkIcon className="cursor-pointer text-gray-600 h-6 w-6 fill-gray-600" />
) : (
<BookmarkIcon className="cursor-pointer text-gray-600 h-6 w-6" />
)}
<BookmarkIcon className="cursor-pointer text-gray-600 h-6 w-6" />
)}
</button>
</div>
<p className="mt-0.5 text-sm text-gray-500">Posted {published}</p>
<div className="mt-2 text-sm text-gray-700">
<p className="text-justify text-ellipsis overflow-hidden truncate line-clamp-3">{text}</p>
</div>
</div>
</div>
</Card>
)
}

Expand Down
8 changes: 1 addition & 7 deletions src/components/Sidebar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,7 @@ import { Link, NavLink, useNavigate } from 'react-router-dom'

import classNames from 'classnames'
import { Dialog, DialogPanel, Transition, TransitionChild } from '@headlessui/react'
import {
BellIcon,
BookmarkIcon,
CogIcon,
HomeIcon,
XMarkIcon,
} from '@heroicons/react/24/outline'
import { BellIcon, BookmarkIcon, CogIcon, HomeIcon, XMarkIcon } from '@heroicons/react/24/outline'

import DashXLogoWhite from '../assets/dashx_logo_white.png'

Expand Down
14 changes: 7 additions & 7 deletions src/components/ToggleSwitch.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ const ToggleSwitch = (props) => {
'ml-4 relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-50 focus:outline-none'
)}
>
<span
aria-hidden="true"
className={classNames(
field.value?.enabled ? 'translate-x-5' : 'translate-x-0',
'inline-block h-5 w-5 rounded-full bg-white shadow transform ring-0 transition ease-in-out duration-200'
)}
/>
<span
aria-hidden="true"
className={classNames(
field.value?.enabled ? 'translate-x-5' : 'translate-x-0',
'inline-block h-5 w-5 rounded-full bg-white shadow transform ring-0 transition ease-in-out duration-200'
)}
/>
</Switch>
)
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/authentication/RequireUser.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import { Navigate, Outlet, useLocation } from 'react-router-dom'

import { useCurrentUserContext } from '../../contexts/CurrentUserContext'

const RequireUser = () => {
const RequireUser = ({ withRedirect = false }) => {
const location = useLocation()
const { user } = useCurrentUserContext()

if (user) {
return <Outlet />
}

return <Navigate to="/login" state={{ from: location.pathname }} replace />
return <Navigate to="/login" state={withRedirect ? { from: location.pathname } : {}} replace />
}
export default RequireUser
2 changes: 1 addition & 1 deletion src/contexts/CurrentUserContext.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { jwtDecode } from 'jwt-decode'
import { jwtDecode } from 'jwt-decode'
import React, { createContext, useContext, useState } from 'react'
import { useDashXProvider } from '@dashx/react'

Expand Down
4 changes: 0 additions & 4 deletions src/index.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

* {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
Expand Down
Loading

0 comments on commit a1fd612

Please sign in to comment.