Skip to content

Commit

Permalink
feat: add admin panel
Browse files Browse the repository at this point in the history
  • Loading branch information
mucahidyazar committed Jan 30, 2023
1 parent ce0eee9 commit 0b6cfa3
Show file tree
Hide file tree
Showing 34 changed files with 496 additions and 87 deletions.
Binary file modified .DS_Store
Binary file not shown.
3 changes: 0 additions & 3 deletions .env

This file was deleted.

24 changes: 0 additions & 24 deletions .env.development

This file was deleted.

24 changes: 0 additions & 24 deletions .env.production

This file was deleted.

2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,6 @@ next-env.d.ts

# my ignores
.env
.env.*
!.env.example
BUILD
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion app/layout.tsx → app/(blog)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import './global.css'
import '../global.css'

import { Inter } from '@next/font/google'
import Image from 'next/image'
Expand Down
File renamed without changes.
File renamed without changes.
48 changes: 48 additions & 0 deletions app/(dashboard)/dashboard/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
'use client'
import cn from 'classnames'
import { serviceKill } from '@/request/services/root/services'
import { Tab } from '@/components'
import { useHealthService } from '@/request/hooks/useHealthService'

export default function Layout({ children }: { children: React.ReactNode }) {
const { error } = useHealthService()

return (
<div>
<div className="w-96 mx-auto">
<h2 className="text-2xl font-semibold mb-4 text-center">Status</h2>

<div className="flex flex-col gap-4 w-fit mx-auto">
<div className="text-gray-400 flex items-center gap-2">
<h3 className="block w-40">Stock search</h3>
<span className={cn(
"px-4 inline-block rounded-md text-sm text-white",
!error ? 'bg-green-500' : 'bg-red-500'
)}>
{!error ? 'Active' : 'Inactive'}
</span>
</div>

<div className="text-gray-400 flex items-center gap-2">
<h3 className="block w-40">API /health</h3>

<span className={cn(
"px-4 inline-block rounded-md text-sm text-white",
!error ? 'bg-green-500' : 'bg-red-500'
)}>
{!error ? 'Up' : 'Down'}
</span>
</div>
</div>
</div>

<div className="my-8 mx-auto w-fit flex gap-4">
<button className="px-4 py-2 bg-blue-500 rounded-md uppercase font-semibold text-sm" onClick={serviceKill}>Restart</button>
</div>

<div className="h-[1px] w-1/2 bg-gray-400 bg-opacity-20 mx-auto" />
<Tab />
{children}
</div>
)
}
3 changes: 3 additions & 0 deletions app/(dashboard)/dashboard/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Page from './stock/page'

export default Page
133 changes: 133 additions & 0 deletions app/(dashboard)/dashboard/stock/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
'use client'
export const revalidate = 10
import { useState } from 'react'
import cn from 'classnames'

import {
useClearResultsService,
useClearService,
useCreateService,
useStartService,
useStopService
} from '@/request/hooks'
import { useListService } from '@/request/hooks/useListService'

interface IStock {
_id: string
active: boolean
retry: number
results: any[]
}

export default function AdminPage() {
const {
data: myStockData,
mutate: myStockMutate,
} = useListService() as any
const { trigger: createTrigger } = useCreateService()
const { trigger: stopTrigger } = useStopService()
const { trigger: startTrigger } = useStartService()
const { trigger: clearResultTrigger } = useClearResultsService()
const { trigger: clearTrigger } = useClearService()

return (
<div className='flex flex-col gap-4 items-center'>
<div className='flex gap-2'>
<button
className="px-4 py-2 bg-blue-500 rounded-md uppercase font-semibold text-sm"
onClick={() => createTrigger().then(() => myStockMutate())}
>
New Search
</button>
<button
className="px-4 py-2 bg-red-500 rounded-md uppercase font-semibold text-sm"
onClick={() => clearTrigger().then(() => myStockMutate())}
>
Clear
</button>
</div>
<div className='border border-solid border-indigo-500 border-opacity-30 w-full rounded-md h-60 bg-indigo-500 bg-opacity-10 overflow-y-auto'>
{myStockData?.data?.myStock.map((data: IStock) =>
<Row
key={data._id}
data={data}
startTrigger={() => startTrigger({ id: data._id }).then(() => myStockMutate())}
stopTrigger={() => stopTrigger({ id: data._id }).then(() => myStockMutate())}
clearResultTrigger={() => clearResultTrigger({ id: data._id }).then(() => myStockMutate())}
/>
)}
</div>
</div>
)
}

interface IRow {
data: IStock
stopTrigger: () => void
startTrigger: () => void
clearResultTrigger: () => void
}
const Row = ({ data, stopTrigger, startTrigger, clearResultTrigger }: IRow) => {
const [isCollapsed, setIsCollapsed] = useState(false)

const clearHandler = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
e.stopPropagation()
clearResultTrigger()
}

const startAndStopHandler = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
e.stopPropagation()
if (data.active) {
stopTrigger()
} else {
startTrigger()
}
}

return (
<div key={data._id} className='group'>
<div
className={cn(
'flex justify-between p-4 cursor-pointer bg-opacity-30 hover:bg-opacity-20 duration-150 group-[&:not(:last-child)]:border-b border-white border-opacity-10',
data.active ? 'bg-green-500' : 'bg-red-500'
)}
onClick={() => setIsCollapsed(!isCollapsed)}
>
<div className='flex flex-col gap-2'>

<div className='flex gap-2'>
<div>{data._id}</div>
</div>
<div>
<p className='text-xs text-gray-400'>
Retry: <span>{data.retry}</span>
</p>
<p className='text-xs text-gray-400'>
Active: <span>{data.active ? 'Yes' : 'No'}</span>
</p>
</div>
</div>
<div className='flex gap-4'>
<button onClick={clearHandler}>Clear</button>
<button onClick={startAndStopHandler}>{data.active ? 'Stop' : 'Start'}</button>
</div>
</div>
{isCollapsed && (
<div className='p-2 text-xs bg-indigo-500 bg-opacity-10'>
{data.results.map((result, index) => (
<div
key={index + result.brand.name}
className='flex gap-4 p-1 [&:not(:last-child)]:border-b border-solid border-indigo-200 border-opacity-20'
>
<div className='w-20'>{result.brand.name}</div>
<div className='w-96 flex-grow'>
<p className='line-clamp-3'>{result.link}</p>
</div>
<div>{result.hasFound ? 'Found' : 'Not Found'}</div>
</div>
))}
</div>
)}
</div>
)
}
76 changes: 76 additions & 0 deletions app/(dashboard)/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import '../global.css'

import { Inter } from '@next/font/google'
import Image from 'next/image'

import { LINKS } from '@/mocks'
import { Chip, HomeArticle, HomeSection, Navbar } from '@/components'

const inter = Inter({ subsets: ['latin'] })

export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head />
<body
className={`${inter.className} flex flex-col text-gray-300 overflow-x-hidden`}
>
<div className="fixed top-0 w-full">
<ul className="flex items-center justify-center gap-2 gap-x-4 p-2 w-fit mx-auto bg-gray-500 bg-opacity-10 hover:bg-opacity-20 rounded-b-md -translate-y-6 hover:-translate-y-0 duration-150 cursor-pointer">
{LINKS.map(link => (
<a
href={link.url}
key={link.url}
className="hover:scale-105 duration-150 flex items-center justify-center opacity-30 hover:opacity-100"
>
<Image
src={`/svg/socials/${link.icon}.svg`}
alt={link.label}
width={16}
height={16}
/>
</a>
))}
</ul>
</div>
<header className="flex items-center justify-between mx-auto py-10 gap-20 container">
<Image
src="/svg/full-logo.svg"
alt="logo"
width={400}
height={80}
className="w-40 h-8"
/>
<Navbar />
</header>
<main className="container mx-auto flex-grow">
{children}
</main>
<footer className="max-w-4xl mx-auto py-8 px-4 w-full lg:px-0">
<div className="flex justify-between items-center w-full">
<p className="opacity-40 text-xs">
Created in 2022 by Mucahid Yazar
</p>

<ul className="flex gap-2">
{LINKS.map(link => (
<a
href={link.url}
key={link.url}
className="hover:scale-105 duration-150 flex items-center justify-center opacity-40 hover:opacity-60"
>
<Image
src={`/svg/socials/${link.icon}.svg`}
alt={link.label}
width={16}
height={16}
/>
</a>
))}
</ul>
</div>
</footer>
</body>
</html>
)
}
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"@types/react": "^18.0.25",
"@types/react-dom": "^18.0.9",
"axios": "^1.2.0",
"classnames": "^2.3.2",
"commitizen": "^4.2.5",
"cz-conventional-changelog": "^3.3.0",
"eslint": "^8.28.0",
Expand All @@ -52,6 +53,7 @@
"flowbite-react": "^0.3.5",
"graphql": "^16.6.0",
"husky": "^8.0.2",
"js-cookie": "^3.0.1",
"leaflet": "^1.9.3",
"moment": "^2.29.4",
"next": "^13.1.3",
Expand All @@ -65,10 +67,14 @@
"react-syntax-highlighter": "^15.5.0",
"react-toastify": "^9.1.1",
"remark-gfm": "^3.0.1",
"swr": "^2.0.1",
"typescript": "^4.9.3",
"yup": "^0.32.11"
},
"devDependencies": {
"@tailwindcss/line-clamp": "^0.4.2",
"@types/js-cookie": "^3.0.2",
"@types/leaflet": "^1.9.0",
"@types/react-syntax-highlighter": "^15.5.5",
"autoprefixer": "^10.4.13",
"postcss": "^8.4.19",
Expand Down

0 comments on commit 0b6cfa3

Please sign in to comment.