diff --git a/.eslintrc.json b/.eslintrc.json index 87cf6fe..e9323e2 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -2,6 +2,7 @@ "extends": ["next/core-web-vitals", "prettier"], "rules": { "indent": ["error", 2], - "quotes": ["error", "single"] + "quotes": ["error", "single"], + "no-unused-vars": "error" } } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index a2867dd..9129a0b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "rayfoundation", "version": "0.1.0", "dependencies": { + "@chakra-ui/icons": "^2.1.1", "@chakra-ui/next-js": "^2.2.0", "@chakra-ui/react": "^2.8.2", "@emotion/react": "^11.11.1", @@ -1033,6 +1034,18 @@ "react": ">=18" } }, + "node_modules/@chakra-ui/icons": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/icons/-/icons-2.1.1.tgz", + "integrity": "sha512-3p30hdo4LlRZTT5CwoAJq3G9fHI0wDc0pBaMHj4SUn0yomO+RcDRlzhdXqdr5cVnzax44sqXJVnf3oQG0eI+4g==", + "dependencies": { + "@chakra-ui/icon": "3.2.0" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, "node_modules/@chakra-ui/image": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@chakra-ui/image/-/image-2.1.0.tgz", diff --git a/package.json b/package.json index 9f3b2c5..979eab9 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "test:watch": "jest --watch" }, "dependencies": { + "@chakra-ui/icons": "^2.1.1", "@chakra-ui/next-js": "^2.2.0", "@chakra-ui/react": "^2.8.2", "@emotion/react": "^11.11.1", diff --git a/src/app/components/CTAButton.tsx b/src/app/components/CTAButton.tsx new file mode 100644 index 0000000..91af449 --- /dev/null +++ b/src/app/components/CTAButton.tsx @@ -0,0 +1,46 @@ +'use client' +import { Button } from '@chakra-ui/react' +import React, { useEffect, useState } from 'react' + +export default function CTAButton({ + type, + variant, + size, + colorScheme = 'brand', +}: { + type: string + variant: string + size: string + colorScheme: string +}) { + const [text, setText] = useState('') + const [url, setUrl] = useState('') + + useEffect(() => { + if (type === 'cta_donate') { + setText('Donate Now') + } + }, [type]) + + useEffect(() => { + if (type === 'cta_donate') { + setUrl('https://www.paypal.com/donate/?hosted_button_id=WT7WGSCGNCF9U') + } + }, [type]) + + const onClick = () => { + window.open(url, '_blank') + } + + return ( + + ) +} diff --git a/src/app/components/Navbar.tsx b/src/app/components/Navbar.tsx new file mode 100644 index 0000000..45649da --- /dev/null +++ b/src/app/components/Navbar.tsx @@ -0,0 +1,62 @@ +'use client' +import { Box, Flex, HStack, Text, useDisclosure } from '@chakra-ui/react' +import React, { useRef } from 'react' +import NavbarLinkToggle from './NavbarLinkToggle' +import NavbarLinks from './NavbarLinks' +import Link from 'next/link' +import CTAButton from './CTAButton' + +const links = [ + { to: '/about', text: 'About Us' }, + { to: '/contact', text: 'Contact' }, + { to: '/projects', text: 'Our Projects' }, + { to: '/team', text: 'Team' }, +] + +export default function Navbar() { + const { isOpen, onOpen, onClose } = useDisclosure() + const btnRef = useRef(null) + + return ( + + {/* Logo */} + + + + Ray Foundation + + + + {/* Links */} + + + + {/* Toggle */} + + + + ) +} diff --git a/src/app/components/NavbarLink.tsx b/src/app/components/NavbarLink.tsx new file mode 100644 index 0000000..4793ee2 --- /dev/null +++ b/src/app/components/NavbarLink.tsx @@ -0,0 +1,13 @@ +import React from 'react' +import Link from 'next/link' +import { Button } from '@chakra-ui/react' + +export default function NavbarLink({ to, text }: { to: string; text: string }) { + return ( + + + + ) +} diff --git a/src/app/components/NavbarLinkToggle.tsx b/src/app/components/NavbarLinkToggle.tsx new file mode 100644 index 0000000..84d7161 --- /dev/null +++ b/src/app/components/NavbarLinkToggle.tsx @@ -0,0 +1,22 @@ +'use client' +import { Box, Button } from '@chakra-ui/react' +import React, { RefObject } from 'react' +import { CloseIcon, HamburgerIcon } from '@chakra-ui/icons' + +export default function NavbarLinkToggle({ + isOpen, + toggle, + btnRef, +}: { + isOpen: boolean + toggle: () => void + btnRef: RefObject +}) { + return ( + + + + ) +} diff --git a/src/app/components/NavbarLinks.tsx b/src/app/components/NavbarLinks.tsx new file mode 100644 index 0000000..0f7caf1 --- /dev/null +++ b/src/app/components/NavbarLinks.tsx @@ -0,0 +1,59 @@ +'use client' +import React from 'react' +import { + Box, + Drawer, + DrawerBody, + DrawerCloseButton, + DrawerContent, + DrawerHeader, + DrawerOverlay, + Stack, + StackDivider, +} from '@chakra-ui/react' +import NavbarLink from './NavbarLink' + +export default function NavbarLinks({ + links, + isOpen, + onClose, + btnRef, +}: { + links: { to: string; text: string }[] + isOpen: boolean + onClose: () => void + btnRef: React.RefObject +}) { + return ( + <> + + + {links.map((link) => { + return + })} + + + + + + + Menu + + }> + {links.map((link) => { + return ( + + ) + })} + + + + + + ) +} diff --git a/src/app/components/__tests__/CTAButton.test.tsx b/src/app/components/__tests__/CTAButton.test.tsx new file mode 100644 index 0000000..dafa8f6 --- /dev/null +++ b/src/app/components/__tests__/CTAButton.test.tsx @@ -0,0 +1,29 @@ +import { screen, render } from '@testing-library/react' +import '@testing-library/jest-dom' +import CTAButton from '../CTAButton' +import React from 'react' + +describe('CTAButton', () => { + it('should render the donate button', () => { + render( + + ) + expect(screen.getByText('Donate Now')).toBeInTheDocument() + }) + it('should render Button when type is incorrect', () => { + render( + + ) + expect(screen.getByText('CTA Button')).toBeInTheDocument() + }) +}) diff --git a/src/app/components/__tests__/Navbar.test.tsx b/src/app/components/__tests__/Navbar.test.tsx new file mode 100644 index 0000000..d397ae7 --- /dev/null +++ b/src/app/components/__tests__/Navbar.test.tsx @@ -0,0 +1,15 @@ +import { screen, render } from '@testing-library/react' +import '@testing-library/jest-dom' +import React from 'react' +import Navbar from '../Navbar' + +describe('NavBar', () => { + it('should render the logo', () => { + render() + expect(screen.getByText('Ray Foundation')).toBeInTheDocument() + }) + it('should render the call to action button', () => { + render() + expect(screen.getByText('Donate Now')).toBeInTheDocument() + }) +}) diff --git a/src/app/components/__tests__/NavbarLink.test.tsx b/src/app/components/__tests__/NavbarLink.test.tsx new file mode 100644 index 0000000..b44b6b3 --- /dev/null +++ b/src/app/components/__tests__/NavbarLink.test.tsx @@ -0,0 +1,12 @@ +import { screen, render } from '@testing-library/react' +import '@testing-library/jest-dom' +import React from 'react' +import NavbarLink from '../NavbarLink' + +describe('NavbarLink', () => { + it('should render the link', () => { + render() + expect(screen.getByText('Home')).toBeInTheDocument() + expect(screen.getByRole('link')).toHaveAttribute('href', '/') + }) +}) diff --git a/src/app/components/__tests__/NavbarLinkToggle.test.tsx b/src/app/components/__tests__/NavbarLinkToggle.test.tsx new file mode 100644 index 0000000..396cde9 --- /dev/null +++ b/src/app/components/__tests__/NavbarLinkToggle.test.tsx @@ -0,0 +1,18 @@ +import { screen, render, fireEvent } from '@testing-library/react' +import '@testing-library/jest-dom' +import React from 'react' +import NavbarLinkToggle from '../NavbarLinkToggle' + +describe('NavbarLinkToggle', () => { + it('should render the toggle button', () => { + render() + expect(screen.getByRole('button')).toBeInTheDocument() + }) + it('should call the toggle button when clicked', () => { + const toggle = jest.fn() + render() + expect(screen.getByRole('button')).toBeInTheDocument() + fireEvent.click(screen.getByRole('button')) + expect(toggle).toHaveBeenCalled() + }) +}) diff --git a/src/app/components/__tests__/NavbarLinks.test.tsx b/src/app/components/__tests__/NavbarLinks.test.tsx new file mode 100644 index 0000000..e8c9e9f --- /dev/null +++ b/src/app/components/__tests__/NavbarLinks.test.tsx @@ -0,0 +1,33 @@ +import { screen, render } from '@testing-library/react' +import '@testing-library/jest-dom' +import React from 'react' +import NavbarLinks from '../NavbarLinks' + +describe('NavbarLinks', () => { + it('should render one link if drawer is closed', () => { + render( + + ) + expect(screen.getByText('Home')).toBeInTheDocument() + }) + + it('should render two links if drawer is open', () => { + render( + + ) + expect(screen.getAllByText('Home')).toHaveLength(2) + }) +}) diff --git a/src/app/layout.tsx b/src/app/layout.tsx index a75cd11..6a2f141 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,9 +1,6 @@ import type { Metadata } from 'next' -import { Inter } from 'next/font/google' -import './globals.css' import ThemeProvider from './_providers/ThemeProvider' - -const inter = Inter({ subsets: ['latin'] }) +import Navbar from './components/Navbar' export const metadata: Metadata = { title: 'Ray Foundation', @@ -17,8 +14,11 @@ export default function RootLayout({ }) { return ( - - {children} + + + +
{children}
+
) diff --git a/src/app/page.tsx b/src/app/page.tsx index 2176ae0..a9847cf 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,5 +1,3 @@ -import Image from 'next/image' - export default function Home() { return
Ray Foundation
} diff --git a/src/app/team/[id]/page.tsx b/src/app/team/[id]/page.tsx index 4f18fd1..9071030 100644 --- a/src/app/team/[id]/page.tsx +++ b/src/app/team/[id]/page.tsx @@ -1,14 +1,14 @@ -import { Metadata, ResolvingMetadata } from 'next' +import { Metadata } from 'next' import React from 'react' type MetadataProps = { params: { id: string } } -export async function generateMetadata( - { params }: MetadataProps, - parent: ResolvingMetadata -): Promise { +export async function generateMetadata({ + params, +}: MetadataProps): // parent: ResolvingMetadata +Promise { const id = params.id // Fetch Team Member Information Here