Skip to content

Commit

Permalink
[IR#59] - close_avatar_dropdown_on_item_click
Browse files Browse the repository at this point in the history
  • Loading branch information
nicitaacom authored Nov 8, 2023
2 parents db8f8c0 + 4c05c44 commit 42a77c1
Show file tree
Hide file tree
Showing 37 changed files with 465 additions and 126 deletions.
2 changes: 1 addition & 1 deletion app/(auth)/auth/callback/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ export async function GET(request: Request) {

return NextResponse.redirect(
`${requestUrl.origin}/auth/client?userId=${user?.id}&username=${user?.user_metadata.name}
&email=${user?.user_metadata.email}&profile_picture_url=${user?.user_metadata.picture}`,
&email=${user?.user_metadata.email}&avatar_url=${user?.user_metadata.picture}`,
)
}
4 changes: 2 additions & 2 deletions app/(auth)/auth/client/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ export default function Page() {
const userId = useSearchParams().get("userId")
const username = useSearchParams().get("username")
const email = useSearchParams().get("email")
const profile_picture_url = useSearchParams().get("profile_picture_url")
const avatar_url = useSearchParams().get("avatar_url")
useEffect(() => {
userStore.setUser(userId ?? "", username ?? "", email ?? "", profile_picture_url ?? "")
userStore.setUser(userId ?? "", username ?? "", email ?? "", avatar_url ?? "")
router.push("/")
//to prevent error about too many re-renders
// eslint-disable-next-line react-hooks/exhaustive-deps
Expand Down
4 changes: 3 additions & 1 deletion app/(site)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ export default async function Home({ searchParams }: SearchProps) {
const entries = products.slice(start, end)

return (
<div className="max-w-[1024px] text-2xl text-white flex flex-col gap-y-8 justify-between items-center py-12 min-h-[calc(100vh-4rem)] mx-auto">
<div
className="w-full py-12 h-[calc(100vh-64px)] overflow-x-hidden overflow-y-auto
text-2xl text-title flex flex-col gap-y-8 justify-between items-center mx-auto">
<section className="flex flex-col gap-y-4">
<Products products={entries} />
</section>
Expand Down
8 changes: 7 additions & 1 deletion app/(site)/search/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,14 @@ interface SearchPageProps {
}

export function generateMetadata({ searchParams: { query } }: SearchPageProps): Metadata {
if (query === undefined) {
return {
title: `Search - 23_store`,
}
}

return {
title: `Search ${query} - Flowmazon`,
title: `Search ${query} - 23_store`,
}
}

Expand Down
5 changes: 3 additions & 2 deletions app/components/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ export default function Layout({ children }: { children: React.ReactNode }) {

return (
<div
className="bg-background text-title
min-h-screen transition-colors duration-300 pt-[62px]">
className="flex flex-col w-full overflow-hidden min-h-screen
bg-background text-title
transition-colors duration-300">
{children}
<AnimatePresence>{toast.isOpen && <Toast />}</AnimatePresence>
</div>
Expand Down
28 changes: 6 additions & 22 deletions app/components/Navbar/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import Link from "next/link"
import { FiPhoneCall } from "react-icons/fi"
import { BiSearchAlt } from "react-icons/bi"

import supabaseServer from "@/libs/supabaseServer"
import { contact } from "@/constant/contacts"
import { Language } from "../Language"
import { DropdownContainer } from "../ui/DropdownContainer"
import { SwitchDarkMode } from ".."
import { NavbarWrapper } from "./components/NavbarWrapper"
import {
Expand All @@ -16,6 +12,8 @@ import {
OpenCartModalButton,
OpenUserMenuButton,
} from "./components"
import { CtrlKBadge } from "./components/CtrlKBadge"
import { SupportButton } from "./components/SupportButton"

export default async function Navbar() {
const {
Expand All @@ -31,7 +29,9 @@ export default async function Navbar() {
</div>
{/* SEARCH + LANGUAGE */}
<div className="flex flex-row gap-x-2">
<NavbarSearch />
<NavbarSearch>
<CtrlKBadge />
</NavbarSearch>
<Language className="hidden laptop:flex" />
</div>

Expand All @@ -40,23 +40,7 @@ export default async function Navbar() {
<SwitchDarkMode className="max-[500px]:hidden" />
<BiSearchAlt className="flex tablet:hidden" size={28} />
<OpenCartModalButton />
<DropdownContainer
classNameDropdownContainer="hidden mobile:flex"
className="before:translate-x-[-300%] translate-x-[35%] w-[125px]"
icon={<FiPhoneCall size={28} />}>
<div className="flex flex-col gap-y-2 justify-center items-center px-4 py-2">
<div className="flex flex-col justify-center items-center">
<Link
className="hover:text-brand text-title text-center duration-300"
href={contact.telegram}
target="_blank"
rel="preload">
Telegram
</Link>
<p className="whitespace-nowrap">(response 8s)</p>
</div>
</div>
</DropdownContainer>
<SupportButton />
{user ? <OpenUserMenuButton /> : <OpenAuthModalButton />}
</div>
</NavbarWrapper>
Expand Down
22 changes: 22 additions & 0 deletions app/components/Navbar/components/CtrlKBadge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"use client"

import { useCtrlKModal } from "@/store/ui/ctrlKModal"
import { useEffect } from "react"

export function CtrlKBadge() {
const ctrlKModal = useCtrlKModal()

useEffect(() => {
const handleKeydown = (e: KeyboardEvent) => {
if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
//to prevent focus state on browser searchbar
e.preventDefault()
ctrlKModal.toggle()
}
}
document.addEventListener("keydown", handleKeydown)
return () => document.removeEventListener("keydown", handleKeydown)
}, [ctrlKModal, ctrlKModal.toggle])

return <div className="bg-icon-color rounded inline-block text-title-foreground px-[4px] py-[2px[">⌘+K</div>
}
3 changes: 2 additions & 1 deletion app/components/Navbar/components/NavbarSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ async function searchProducts(formData: FormData) {
}
}

export function NavbarSearch() {
export function NavbarSearch({ children: Children }: { children: React.ReactNode }) {
return (
<form action={searchProducts}>
<SearchInput
className="hidden tablet:flex w-[40vw] max-w-[600px]"
startIcon={<BiSearchAlt size={24} />}
endIcon={Children}
name="searchQuery"
placeholder="Search..."
/>
Expand Down
5 changes: 3 additions & 2 deletions app/components/Navbar/components/NavbarWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ export function NavbarWrapper({ children }: { children: React.ReactNode }) {
}, [])
return (
<nav
className={`fixed flex flex-row justify-between items-center
px-4 tablet:px-6 laptop:px-8 py-2 max-h-[64px] mx-auto z-[99] text-title w-full transition-all duration-300
id="nav"
className={`relative w-full min-h-[64px] flex flex-row justify-between items-center
px-4 tablet:px-6 laptop:px-8 py-2 mx-auto z-[99] text-title transition-colors duration-300
${scrollPosition < 40 ? "bg-background" : "bg-foreground"}`}>
{children}
</nav>
Expand Down
20 changes: 17 additions & 3 deletions app/components/Navbar/components/OpenUserMenuButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,25 @@ import LogoutDropdownItem from "./LogoutDropdownItem"
import { SwitchDarkMode } from "@/components"
import { contact } from "@/constant/contacts"
import { DropdownContainer, DropdownItem } from "@/components/ui"
import { useAvatarDropdown } from "@/store/ui/avatarDropdown"
import { useRouter } from "next/navigation"

export function OpenUserMenuButton() {
const router = useRouter()
const avatarDropdown = useAvatarDropdown()
const userStore = useUserStore()
const mode = useDarkMode()

function openAdminPanel() {
router.push("?modal=AdminPanel")
avatarDropdown.closeDropdown()
}

function openChangeLanguageModal() {
router.push("?modal=ChangeLanguage")
avatarDropdown.closeDropdown()
}

return (
<DropdownContainer
classNameDropdownContainer="ml-1"
Expand All @@ -25,22 +39,22 @@ export function OpenUserMenuButton() {
<>
<Image
className="w-[32px] h-[32px] rounded-full"
src={userStore.profilePictureUrl ? userStore.profilePictureUrl : "/placeholder.jpg"}
src={userStore.avatarUrl ? userStore.avatarUrl : "/placeholder.jpg"}
alt="user logo"
width={32}
height={32}
/>
</>
}>
<DropdownItem label="Admin panel" icon={BsWindow} href="?modal=AdminPanel" />
<DropdownItem label="Admin panel" icon={BsWindow} onClick={openAdminPanel} />
<DropdownItem
className="flex justify-center mobile:hidden"
label="Support"
icon={FiPhoneCall}
href={contact.telegram}
target="_blank"
/>
<DropdownItem label="Change language" icon={TbWorld} href="?modal=ChangeLanguage" />
<DropdownItem label="Change language" icon={TbWorld} onClick={openChangeLanguageModal} />
<DropdownItem
className="min-[501px]:hidden"
label="Dark mode"
Expand Down
27 changes: 27 additions & 0 deletions app/components/Navbar/components/SupportButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Link from "next/link"
import { FiPhoneCall } from "react-icons/fi"

import { contact } from "@/constant/contacts"
import { DropdownContainer } from "@/components/ui"

export function SupportButton() {
return (
<DropdownContainer
classNameDropdownContainer="hidden mobile:flex"
className="before:translate-x-[-300%] translate-x-[35%] w-[125px]"
icon={<FiPhoneCall size={28} />}>
<div className="flex flex-col gap-y-2 justify-center items-center px-4 py-2">
<div className="flex flex-col justify-center items-center">
<Link
className="hover:text-brand text-title text-center duration-300"
href={contact.telegram}
target="_blank"
rel="preload">
Telegram
</Link>
<p className="whitespace-nowrap">(response 8s)</p>
</div>
</div>
</DropdownContainer>
)
}
8 changes: 4 additions & 4 deletions app/components/ui/DropdownContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client"

import useCloseOnClickOutlise from "@/hooks/ui/useCloseOnClickOutside"
import useAvatarDropdownClose from "@/hooks/ui/useAvatarDropdownClose"
import { twMerge } from "tailwind-merge"

interface DropdownContainerProps {
Expand All @@ -18,11 +18,11 @@ export function DropdownContainer({
className = "",
classNameDropdownContainer = "",
}: DropdownContainerProps) {
const { isDropdown, dropdownContainerRef, setIsDropdown } = useCloseOnClickOutlise()
const { isDropdown, toggle, avatarDropdownRef } = useAvatarDropdownClose()

return (
<div className={`relative z-10 ${classNameDropdownContainer}`} ref={dropdownContainerRef}>
<div className="cursor-pointer hover:brightness-75 duration-300" onClick={() => setIsDropdown(!isDropdown)}>
<div className={`relative z-10 ${classNameDropdownContainer}`} ref={avatarDropdownRef}>
<div className="cursor-pointer hover:brightness-75 duration-300" onClick={toggle}>
{icon}
</div>

Expand Down
3 changes: 3 additions & 0 deletions app/components/ui/Inputs/SearchInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ interface InputProps extends React.HTMLAttributes<HTMLInputElement> {
type?: string
className?: string
startIcon?: React.ReactElement
endIcon?: React.ReactNode
pattern?: string
name?: string
required?: boolean
Expand All @@ -14,6 +15,7 @@ export function SearchInput({
type = "text",
className = "",
startIcon,
endIcon,
pattern,
required = false,
name,
Expand All @@ -32,6 +34,7 @@ export function SearchInput({
required={required}
{...props}
/>
<div className="absolute right-0 top-[50%] translate-y-[-55%] translate-x-[-25%]">{endIcon}</div>
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import { useSwipeable } from "react-swipeable"
import { twMerge } from "tailwind-merge"
import { AnimatePresence, motion } from "framer-motion"

interface ModalContainerProps {
interface ModalQueryContainerProps {
children: React.ReactNode
modalQuery: string
className?: string
isLoading?: boolean
}

export function ModalContainer({ children, modalQuery, className, isLoading }: ModalContainerProps) {
export function ModalQueryContainer({ children, modalQuery, className, isLoading }: ModalQueryContainerProps) {
const pathname = usePathname()
const router = useRouter()
const queryParams = useSearchParams()
Expand Down
6 changes: 3 additions & 3 deletions app/components/ui/Modals/AdminPanel/AdminPanelModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { RadioButton } from "@/components/ui"
import useUserStore from "@/store/user/userStore"
import { IDBProduct } from "@/interfaces/IDBProduct"

import { ModalContainer } from "../../ModalContainer"
import { ModalQueryContainer } from "../ModalContainers/ModalQueryContainer"
import { EditProductForm } from "./components/EditProductForm"
import { AddProductForm } from "./components/AddProductForm"
import { DeleteProductForm } from "./components/DeleteProductForm"
Expand All @@ -35,7 +35,7 @@ export function AdminPanelModal({ label, ownerProducts }: AdminPanelModalProps)
}, [])

return (
<ModalContainer
<ModalQueryContainer
className={twMerge(
`w-[100vw] max-w-[768px] max-h-full
flex flex-col bg-primary rounded-md border-[1px] border-solid border-border-color pt-8 transition-all duration-500`,
Expand Down Expand Up @@ -105,6 +105,6 @@ export function AdminPanelModal({ label, ownerProducts }: AdminPanelModalProps)

{productAction === "Delete product" && <DeleteProductForm ownerProducts={ownerProducts} />}
</div>
</ModalContainer>
</ModalQueryContainer>
)
}
6 changes: 3 additions & 3 deletions app/components/ui/Modals/AreYouSureClearCartModal.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use client"

import { useAreYouSureClearCartModal } from "@/store/ui/areYouSureClearCartModal"
import { AreYouSureModal } from "../AreYouSureModal"
import { AreYouSureModalContainer } from "./ModalContainers/AreYouSureModalContainer"
import useCartStore from "@/store/user/cartStore"

export function AreYouSureClearCartButton() {
Expand All @@ -10,13 +10,13 @@ export function AreYouSureClearCartButton() {
const cartStore = useCartStore()

return (
<AreYouSureModal
<AreYouSureModalContainer
isOpen={areYouSuteClearCartModal.isOpen}
label={"Are you sure you want to clear cart?"}
primaryButtonVariant="danger"
primaryButtonAction={cartStore.clearCart}
primaryButtonLabel="Delete"
secondaryButtonAction={areYouSuteClearCartModal.closeModal}
secondaryButtonLabel="Back"></AreYouSureModal>
secondaryButtonLabel="Back"></AreYouSureModalContainer>
)
}
Loading

0 comments on commit 42a77c1

Please sign in to comment.