diff --git a/src/app/(authentication)/login/login.tsx b/src/app/(authentication)/login/login.tsx index 0977d7d..fe60266 100644 --- a/src/app/(authentication)/login/login.tsx +++ b/src/app/(authentication)/login/login.tsx @@ -1,8 +1,7 @@ 'use client' import { - Alert, - Button, Col, Form, InputGroup, Row, + Alert, Button, Col, Form, FormControl, InputGroup, Row, } from 'react-bootstrap' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faUser } from '@fortawesome/free-regular-svg-icons' @@ -12,6 +11,7 @@ import { SyntheticEvent, useState } from 'react' import { deleteCookie, getCookie } from 'cookies-next' import axios from 'axios' import Link from 'next/link' +import InputGroupText from 'react-bootstrap/InputGroupText' export default function Login() { const router = useRouter() @@ -50,16 +50,23 @@ export default function Login() { return ( <> - setError('')} dismissible>{error} + setError('')} + dismissible + > + {error} +
- + - - + - + - - + - +

Register

Create your account

-
+
diff --git a/src/app/(authentication)/register/register.tsx b/src/app/(authentication)/register/register.tsx index 1e2eda4..bf640cf 100644 --- a/src/app/(authentication)/register/register.tsx +++ b/src/app/(authentication)/register/register.tsx @@ -1,7 +1,7 @@ 'use client' import { - Alert, Button, Form, InputGroup, + Alert, Button, Form, FormControl, InputGroup, } from 'react-bootstrap' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faEnvelope, faUser } from '@fortawesome/free-regular-svg-icons' @@ -10,6 +10,7 @@ import { useRouter } from 'next/navigation' import { SyntheticEvent, useState } from 'react' import { deleteCookie, getCookie } from 'cookies-next' import axios from 'axios' +import InputGroupText from 'react-bootstrap/InputGroupText' export default function Register() { const router = useRouter() @@ -51,8 +52,8 @@ export default function Register() { setError('')} dismissible>{error} - - + - + - - + - - + - - + Math.floor(Math.random() * (max - min + 1) + min) +import UserChart from '@/components/Dashboard/UserChart' +import IncomeChart from '@/components/Dashboard/IncomeChart' +import ConversionChart from '@/components/Dashboard/ConversionChart' +import SessionChart from '@/components/Dashboard/SessionChart' +import TrafficChart from '@/components/Dashboard/TrafficChart' export default function Page() { return ( @@ -48,7 +46,7 @@ export default function Page() {
- +
26K @@ -61,84 +59,31 @@ export default function Page() {
Users
- - + - - Action - Another action - Something else - + + Action + Another action + Something else + - +
- +
- +
$6.200 @@ -151,83 +96,31 @@ export default function Page() {
Income
- - + - - Action - Another action - Something else - + + Action + Another action + Something else + - +
- +
- +
2.49% @@ -240,69 +133,31 @@ export default function Page() {
Conversion Rate
- - + - - Action - Another action - Something else - + + Action + Another action + Something else + - +
- +
- +
44K @@ -315,73 +170,31 @@ export default function Page() {
Sessions
- - + - - Action - Another action - Something else - + + Action + Another action + Something else + - +
- +
- +

Traffic

@@ -431,86 +244,10 @@ export default function Page() { marginTop: '40px', }} > - +
- - + +
Visits
@@ -558,7 +295,7 @@ export default function Page() { />
-
+
@@ -567,15 +304,15 @@ export default function Page() { className="mb-4" style={{ '--bs-card-cap-bg': '#3b5998' } as React.CSSProperties} > - + - - + +
89k
@@ -587,7 +324,7 @@ export default function Page() {
feeds
-
+
@@ -596,15 +333,15 @@ export default function Page() { className="mb-4" style={{ '--bs-card-cap-bg': '#00aced' } as React.CSSProperties} > - + - - + +
973k
@@ -616,7 +353,7 @@ export default function Page() {
tweets
-
+
@@ -625,15 +362,15 @@ export default function Page() { className="mb-4" style={{ '--bs-card-cap-bg': '#4875b4' } as React.CSSProperties} > - + - - + +
500+
@@ -645,7 +382,7 @@ export default function Page() {
feeds
-
+
@@ -654,10 +391,10 @@ export default function Page() {
- + Traffic & Sales - - + +
@@ -1008,25 +745,25 @@ export default function Page() { - - + - - Info - Edit - + Info + Edit + Delete - - + + @@ -1075,25 +812,25 @@ export default function Page() { - - + - - Info - Edit - + Info + Edit + Delete - - + + @@ -1142,25 +879,25 @@ export default function Page() { - - + - - Info - Edit - + Info + Edit + Delete - - + + @@ -1209,25 +946,25 @@ export default function Page() { - - + - - Info - Edit - + Info + Edit + Delete - - + + @@ -1276,25 +1013,25 @@ export default function Page() { - - + - - Info - Edit - + Info + Edit + Delete - - + + @@ -1343,32 +1080,32 @@ export default function Page() { - - + - - Info - Edit - + Info + Edit + Delete - - + +
- +
diff --git a/src/app/(dashboard)/pokemons/[id]/edit/edit.tsx b/src/app/(dashboard)/pokemons/[id]/edit/edit.tsx deleted file mode 100644 index 9e99416..0000000 --- a/src/app/(dashboard)/pokemons/[id]/edit/edit.tsx +++ /dev/null @@ -1,22 +0,0 @@ -'use client' - -import { Card } from 'react-bootstrap' -import PokemonForm from '@/components/Pokemon/PokemonForm' -import { Pokemon } from '@/models/pokemon' - -export type Props = { - pokemon: Pokemon; -} - -export default function Edit(props: Props) { - const { pokemon } = props - - return ( - - Add new Pokémon - - - - - ) -} diff --git a/src/app/(dashboard)/pokemons/[id]/edit/page.tsx b/src/app/(dashboard)/pokemons/[id]/edit/page.tsx index 6240f73..ad423e8 100644 --- a/src/app/(dashboard)/pokemons/[id]/edit/page.tsx +++ b/src/app/(dashboard)/pokemons/[id]/edit/page.tsx @@ -1,6 +1,11 @@ import { Pokemon } from '@/models/pokemon' import { notFound } from 'next/navigation' -import Edit, { Props } from '@/app/(dashboard)/pokemons/[id]/edit/edit' +import { Card, CardBody, CardHeader } from 'react-bootstrap' +import PokemonForm from '@/components/Pokemon/PokemonForm' + +type Props = { + pokemon: Pokemon; +} const fetchPokemon = async (params: { id: string }): Promise => { const idQuery = params.id @@ -36,6 +41,11 @@ export default async function Page({ params }: { params: { id: string } }) { const { pokemon } = await fetchPokemon(params) return ( - + + Add new Pokémon + + + + ) } diff --git a/src/app/(dashboard)/pokemons/create/page.tsx b/src/app/(dashboard)/pokemons/create/page.tsx index a701b2e..c83406b 100644 --- a/src/app/(dashboard)/pokemons/create/page.tsx +++ b/src/app/(dashboard)/pokemons/create/page.tsx @@ -1,15 +1,13 @@ -'use client' - -import { Card } from 'react-bootstrap' +import { Card, CardBody, CardHeader } from 'react-bootstrap' import PokemonForm from '@/components/Pokemon/PokemonForm' export default function Page() { return ( - Add new Pokémon - + Add new Pokémon + - +
) } diff --git a/src/app/ui/dashboard/Breadcrumb/Breadcrumb.tsx b/src/app/ui/dashboard/Breadcrumb/Breadcrumb.tsx index 27d8d47..987bd52 100644 --- a/src/app/ui/dashboard/Breadcrumb/Breadcrumb.tsx +++ b/src/app/ui/dashboard/Breadcrumb/Breadcrumb.tsx @@ -1,23 +1,21 @@ -'use client' - -import { Breadcrumb as BSBreadcrumb } from 'react-bootstrap' +import { Breadcrumb as BSBreadcrumb, BreadcrumbItem } from 'react-bootstrap' export default function Breadcrumb() { return ( - Home - - + Library - - Data + + Data ) } diff --git a/src/app/ui/dashboard/Header/HeaderFeaturedNav.tsx b/src/app/ui/dashboard/Header/HeaderFeaturedNav.tsx index 850d5b8..e793f2b 100644 --- a/src/app/ui/dashboard/Header/HeaderFeaturedNav.tsx +++ b/src/app/ui/dashboard/Header/HeaderFeaturedNav.tsx @@ -1,26 +1,24 @@ -'use client' - import Link from 'next/link' -import { Nav } from 'react-bootstrap' +import { Nav, NavItem, NavLink } from 'react-bootstrap' export default function HeaderFeaturedNav() { return ( ) } diff --git a/src/app/ui/dashboard/Header/HeaderLogout.tsx b/src/app/ui/dashboard/Header/HeaderLogout.tsx new file mode 100644 index 0000000..10acec1 --- /dev/null +++ b/src/app/ui/dashboard/Header/HeaderLogout.tsx @@ -0,0 +1,21 @@ +'use client' + +import axios from 'axios' +import { useRouter } from 'next/navigation' + +export default function HeaderLogout({ children }: { children: React.ReactNode }) { + const router = useRouter() + + const logout = async () => { + const res = await axios.post('/api/mock/logout') + if (res.status === 200) { + router.push('/login') + } + } + + return ( +
+ {children} +
+ ) +} diff --git a/src/app/ui/dashboard/Header/HeaderNotificationNav.tsx b/src/app/ui/dashboard/Header/HeaderNotificationNav.tsx index 8492ed1..e072b28 100644 --- a/src/app/ui/dashboard/Header/HeaderNotificationNav.tsx +++ b/src/app/ui/dashboard/Header/HeaderNotificationNav.tsx @@ -1,5 +1,3 @@ -'use client' - import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faBell, faEnvelope, IconDefinition } from '@fortawesome/free-regular-svg-icons' import { @@ -11,7 +9,16 @@ import { faUserPlus, } from '@fortawesome/free-solid-svg-icons' import { - Badge, Dropdown, Nav, NavLink, ProgressBar, + Badge, + Dropdown, DropdownDivider, + DropdownHeader, + DropdownItem, + DropdownMenu, + DropdownToggle, + Nav, + NavItem, + NavLink, + ProgressBar, } from 'react-bootstrap' import Link from 'next/link' import React, { PropsWithChildren } from 'react' @@ -35,56 +42,56 @@ const ItemWithIcon = (props: ItemWithIconProps) => { export default function HeaderNotificationNav() { return ( ) } diff --git a/src/app/ui/dashboard/Header/HeaderProfileNav.tsx b/src/app/ui/dashboard/Header/HeaderProfileNav.tsx index bd22c67..bb1e437 100644 --- a/src/app/ui/dashboard/Header/HeaderProfileNav.tsx +++ b/src/app/ui/dashboard/Header/HeaderProfileNav.tsx @@ -1,7 +1,13 @@ -'use client' - import { - Badge, Dropdown, Nav, NavItem, + Badge, + Dropdown, + DropdownDivider, + DropdownHeader, + DropdownItem, + DropdownMenu, + DropdownToggle, + Nav, + NavItem, } from 'react-bootstrap' import Image from 'next/image' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' @@ -19,8 +25,7 @@ import { faGear, faListCheck, faLock, faPowerOff, } from '@fortawesome/free-solid-svg-icons' import Link from 'next/link' -import axios from 'axios' -import { useRouter } from 'next/navigation' +import HeaderLogout from '@/app/ui/dashboard/Header/HeaderLogout' type ItemWithIconProps = { icon: IconDefinition; @@ -38,19 +43,10 @@ const ItemWithIcon = (props: ItemWithIconProps) => { } export default function HeaderProfileNav() { - const router = useRouter() - - const logout = async () => { - const res = await axios.post('/api/mock/logout') - if (res.status === 200) { - router.push('/login') - } - } - return ( ) diff --git a/src/app/ui/dashboard/Sidebar/SidebarNav.tsx b/src/app/ui/dashboard/Sidebar/SidebarNav.tsx index e3eec05..da20b06 100644 --- a/src/app/ui/dashboard/Sidebar/SidebarNav.tsx +++ b/src/app/ui/dashboard/Sidebar/SidebarNav.tsx @@ -1,12 +1,5 @@ -'use client' - -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { - faAddressCard, - faBell, - faFileLines, - faStar, - IconDefinition, + faAddressCard, faBell, faFileLines, faStar, } from '@fortawesome/free-regular-svg-icons' import { faBug, @@ -21,40 +14,10 @@ import { faPuzzlePiece, faRightToBracket, } from '@fortawesome/free-solid-svg-icons' -import React, { PropsWithChildren, useContext } from 'react' -import { Badge, Nav } from 'react-bootstrap' -import Link from 'next/link' +import React, { PropsWithChildren } from 'react' +import { Badge } from 'react-bootstrap' import SidebarNavGroup from '@/app/ui/dashboard/Sidebar/SidebarNavGroup' -import { SidebarContext } from '@/app/ui/dashboard/sidebar-provider' - -type SidebarNavItemProps = { - href: string; - icon?: IconDefinition; -} & PropsWithChildren - -const SidebarNavItem = (props: SidebarNavItemProps) => { - const { - icon, - children, - href, - } = props - - const { - showSidebarState: [, setIsShowSidebar], - } = useContext(SidebarContext) - - return ( - - - setIsShowSidebar(false)}> - {icon ? - : } - {children} - - - - ) -} +import SidebarNavItem from '@/app/ui/dashboard/Sidebar/SidebarNavItem' const SidebarNavTitle = (props: PropsWithChildren) => { const { children } = props diff --git a/src/app/ui/dashboard/Sidebar/SidebarNavItem.tsx b/src/app/ui/dashboard/Sidebar/SidebarNavItem.tsx new file mode 100644 index 0000000..fbc6e42 --- /dev/null +++ b/src/app/ui/dashboard/Sidebar/SidebarNavItem.tsx @@ -0,0 +1,37 @@ +'use client' + +import { IconDefinition } from '@fortawesome/free-regular-svg-icons' +import React, { PropsWithChildren, useContext } from 'react' +import { SidebarContext } from '@/app/ui/dashboard/sidebar-provider' +import { NavItem, NavLink } from 'react-bootstrap' +import Link from 'next/link' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' + +type Props = { + href: string; + icon?: IconDefinition; +} & PropsWithChildren + +export default function SidebarNavItem(props: Props) { + const { + icon, + children, + href, + } = props + + const { + showSidebarState: [, setIsShowSidebar], + } = useContext(SidebarContext) + + return ( + + + setIsShowSidebar(false)}> + {icon ? + : } + {children} + + + + ) +} diff --git a/src/components/Dashboard/ConversionChart.tsx b/src/components/Dashboard/ConversionChart.tsx new file mode 100644 index 0000000..8740164 --- /dev/null +++ b/src/components/Dashboard/ConversionChart.tsx @@ -0,0 +1,60 @@ +'use client' + +import { Line } from 'react-chartjs-2' +import React from 'react' +import { + BarElement, + CategoryScale, + Chart, + Filler, + LinearScale, + LineElement, + PointElement, + Tooltip, +} from 'chart.js' + +Chart.register(CategoryScale, LinearScale, PointElement, LineElement, BarElement, Tooltip, Filler) + +export default function ConversionChart() { + return ( + + ) +} diff --git a/src/components/Dashboard/IncomeChart.tsx b/src/components/Dashboard/IncomeChart.tsx new file mode 100644 index 0000000..043727f --- /dev/null +++ b/src/components/Dashboard/IncomeChart.tsx @@ -0,0 +1,74 @@ +'use client' + +import { Line } from 'react-chartjs-2' +import React from 'react' +import { + BarElement, + CategoryScale, + Chart, + Filler, + LinearScale, + LineElement, + PointElement, + Tooltip, +} from 'chart.js' + +Chart.register(CategoryScale, LinearScale, PointElement, LineElement, BarElement, Tooltip, Filler) + +export default function IncomeChart() { + return ( + + ) +} diff --git a/src/components/Dashboard/SessionChart.tsx b/src/components/Dashboard/SessionChart.tsx new file mode 100644 index 0000000..13f439e --- /dev/null +++ b/src/components/Dashboard/SessionChart.tsx @@ -0,0 +1,64 @@ +'use client' + +import { Bar } from 'react-chartjs-2' +import React from 'react' +import { + BarElement, + CategoryScale, + Chart, + Filler, + LinearScale, + LineElement, + PointElement, + Tooltip, +} from 'chart.js' + +Chart.register(CategoryScale, LinearScale, PointElement, LineElement, BarElement, Tooltip, Filler) + +export default function SessionChart() { + return ( + + ) +} diff --git a/src/components/Dashboard/TrafficChart.tsx b/src/components/Dashboard/TrafficChart.tsx new file mode 100644 index 0000000..1ac1f6f --- /dev/null +++ b/src/components/Dashboard/TrafficChart.tsx @@ -0,0 +1,100 @@ +'use client' + +import { Line } from 'react-chartjs-2' +import React from 'react' +import { + BarElement, + CategoryScale, + Chart, + Filler, + LinearScale, + LineElement, + PointElement, + Tooltip, +} from 'chart.js' + +Chart.register(CategoryScale, LinearScale, PointElement, LineElement, BarElement, Tooltip, Filler) + +const random = (min: number, max: number) => Math.floor(Math.random() * (max - min + 1) + min) + +export default function TrafficChart() { + return ( + + ) +} diff --git a/src/components/Dashboard/UserChart.tsx b/src/components/Dashboard/UserChart.tsx new file mode 100644 index 0000000..ac9a468 --- /dev/null +++ b/src/components/Dashboard/UserChart.tsx @@ -0,0 +1,75 @@ +'use client' + +import { Line } from 'react-chartjs-2' +import React from 'react' +import { + BarElement, + CategoryScale, + Chart, + Filler, + LinearScale, + LineElement, + PointElement, + Tooltip, +} from 'chart.js' + +Chart.register(CategoryScale, LinearScale, PointElement, LineElement, BarElement, Tooltip, Filler) + +export default function UserChart() { + return ( + + ) +} diff --git a/src/components/Form/FormError.tsx b/src/components/Form/FormError.tsx index f4607ad..f6d694c 100644 --- a/src/components/Form/FormError.tsx +++ b/src/components/Form/FormError.tsx @@ -1,8 +1,8 @@ -import { Form } from 'react-bootstrap' import React from 'react' +import Feedback from 'react-bootstrap/Feedback' export default function FormError(props: { message?: string }) { const { message } = props - return message && {message} + return message && {message} } diff --git a/src/components/Pagination/RowsPerPage.tsx b/src/components/Pagination/RowsPerPage.tsx index b0d0972..6d66a2e 100644 --- a/src/components/Pagination/RowsPerPage.tsx +++ b/src/components/Pagination/RowsPerPage.tsx @@ -1,8 +1,4 @@ -'use client' - -import { Form } from 'react-bootstrap' -import React from 'react' -import { usePathname, useRouter, useSearchParams } from 'next/navigation' +import RowPerPageSelect from '@/components/Pagination/RowsPerPageSelect' type Props = { perPage: number; @@ -11,35 +7,12 @@ type Props = { export default function RowsPerPage(props: Props) { const { perPage, setPerPage } = props - const router = useRouter() - const pathname = usePathname() - const searchParams = useSearchParams() return (
Rows per page: {' '} - { - if (setPerPage) { - setPerPage(parseInt(event.target.value, 10)) - } - - const newSearchParams = new URLSearchParams(searchParams) - newSearchParams.set('page', '1') // Go back to first page - newSearchParams.set('per_page', event.target.value) - - router.push(`${pathname}?${newSearchParams}`) - }} - > - - - - - +
) } diff --git a/src/components/Pagination/RowsPerPageSelect.tsx b/src/components/Pagination/RowsPerPageSelect.tsx new file mode 100644 index 0000000..bfb1c00 --- /dev/null +++ b/src/components/Pagination/RowsPerPageSelect.tsx @@ -0,0 +1,41 @@ +'use client' + +import { FormSelect } from 'react-bootstrap' +import React from 'react' +import { usePathname, useRouter, useSearchParams } from 'next/navigation' + +type Props = { + perPage: number; + setPerPage?: (perPage: number) => void; +} + +export default function RowPerPageSelect(props: Props) { + const { perPage, setPerPage } = props + const router = useRouter() + const pathname = usePathname() + const searchParams = useSearchParams() + + return ( + { + if (setPerPage) { + setPerPage(parseInt(event.target.value, 10)) + } + + const newSearchParams = new URLSearchParams(searchParams) + newSearchParams.set('page', '1') // Go back to first page + newSearchParams.set('per_page', event.target.value) + + router.push(`${pathname}?${newSearchParams}`) + }} + > + + + + + + ) +} diff --git a/src/components/Pokemon/PokemonList.tsx b/src/components/Pokemon/PokemonList.tsx index 563130b..d3af9c0 100644 --- a/src/components/Pokemon/PokemonList.tsx +++ b/src/components/Pokemon/PokemonList.tsx @@ -1,6 +1,6 @@ -'use client' - -import { Dropdown, Table } from 'react-bootstrap' +import { + Dropdown, DropdownItem, DropdownMenu, DropdownToggle, Table, +} from 'react-bootstrap' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faEllipsisVertical } from '@fortawesome/free-solid-svg-icons' import React from 'react' @@ -65,27 +65,27 @@ export default function PokemonList(props: Props) { {pokemon.total} - - + - - Info + + Info - Edit + Edit - Delete - - + +