✨ Matrix console create product
This commit is contained in:
parent
daba03c2e8
commit
945bd5d357
@ -52,6 +52,10 @@ export function CapDrawer({ width, open, onClose }: { width: number; open: boole
|
||||
title: 'Terms & Conditions',
|
||||
href: '/terms',
|
||||
},
|
||||
{
|
||||
title: 'SN Console',
|
||||
href: '/console',
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
@ -93,7 +97,7 @@ export function CapDrawer({ width, open, onClose }: { width: number; open: boole
|
||||
))}
|
||||
</List>
|
||||
<Divider />
|
||||
<Box sx={{ display: 'flex', flexWrap: 'wrap', px: 2, py: 1.5 }}>
|
||||
<Box sx={{ display: 'flex', flexWrap: 'wrap', px: 2, py: 1.5, gap: 1 }}>
|
||||
{additionalLinks.map((l) => (
|
||||
<NextLink passHref href={l.href} key={l.href}>
|
||||
<Link variant="body2" color={'textSecondary'} fontSize={13}>
|
||||
|
@ -1,9 +1,10 @@
|
||||
import { checkAuthenticatedClient, redirectToLogin } from '@/services/auth'
|
||||
import { JSX, useEffect } from 'react'
|
||||
import { DashboardLayout, Navigation } from '@toolpad/core'
|
||||
import { Stack, Typography } from '@mui/material'
|
||||
import { Box, Stack, Typography } from '@mui/material'
|
||||
import NextLink from 'next/link'
|
||||
|
||||
import HomeIcon from '@mui/icons-material/Home'
|
||||
import AppsIcon from '@mui/icons-material/Apps'
|
||||
|
||||
export function ConsoleLayout({ children }: { children: JSX.Element }) {
|
||||
@ -12,6 +13,11 @@ export function ConsoleLayout({ children }: { children: JSX.Element }) {
|
||||
}, [])
|
||||
|
||||
const navigation: Navigation = [
|
||||
{
|
||||
segment: '',
|
||||
title: 'Home',
|
||||
icon: <HomeIcon />,
|
||||
},
|
||||
{
|
||||
segment: 'console/matrix',
|
||||
title: 'Matrix',
|
||||
@ -35,6 +41,9 @@ export function ConsoleLayout({ children }: { children: JSX.Element }) {
|
||||
</Stack>
|
||||
)
|
||||
},
|
||||
toolbarActions(_) {
|
||||
return <Box />
|
||||
},
|
||||
}}
|
||||
sidebarExpandedWidth={300}
|
||||
defaultSidebarCollapsed
|
||||
|
@ -30,7 +30,7 @@ export default function ConsoleLanding() {
|
||||
<Grid size={1}>
|
||||
<NextLink passHref href="/console/matrix">
|
||||
<CardActionArea>
|
||||
<Card sx={{ width: '100%' }} onClick={() => {}}>
|
||||
<Card sx={{ width: '100%' }}>
|
||||
<CardContent>
|
||||
<AppsIcon sx={{ fontSize: 32, mb: 1.5 }} />
|
||||
<Typography variant="h5" gutterBottom>
|
||||
|
@ -1,5 +1,9 @@
|
||||
import { ConsoleLayout, getConsoleStaticProps } from '@/components/layouts/ConsoleLayout'
|
||||
import { Typography, Container } from '@mui/material'
|
||||
import { MaProduct } from '@/services/matrix/product'
|
||||
import { sni } from '@/services/network'
|
||||
import { Typography, Container, Box, Button, Grid2 as Grid, Card, CardActionArea, CardContent } from '@mui/material'
|
||||
import NextLink from 'next/link'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
export async function getStaticProps() {
|
||||
return getConsoleStaticProps({
|
||||
@ -10,12 +14,52 @@ export async function getStaticProps() {
|
||||
}
|
||||
|
||||
export default function MatrixMarketplace() {
|
||||
const [products, setProducts] = useState<MaProduct[]>([])
|
||||
|
||||
async function fetchProducts() {
|
||||
const { data: resp } = await sni.get<{ data: MaProduct[] }>('/cgi/ma/products/created', {
|
||||
params: {
|
||||
take: 10,
|
||||
},
|
||||
})
|
||||
setProducts(resp.data)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
fetchProducts()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<ConsoleLayout>
|
||||
<Container sx={{ py: 16, display: 'flex', flexDirection: 'column', gap: 8 }}>
|
||||
<Container sx={{ py: 16, display: 'flex', flexDirection: 'column', gap: 4 }}>
|
||||
<Typography variant="h3" component="h1">
|
||||
Matrix Marketplace
|
||||
</Typography>
|
||||
|
||||
<Grid container columns={{ xs: 2, sm: 2, md: 3, lg: 4 }} spacing={4}>
|
||||
{products.map((p) => (
|
||||
<Grid size={1} key={p.id}>
|
||||
<NextLink passHref href="/console/matrix">
|
||||
<CardActionArea>
|
||||
<Card sx={{ width: '100%' }}>
|
||||
<CardContent>
|
||||
<Typography variant="h5" gutterBottom>
|
||||
{p.name}
|
||||
</Typography>
|
||||
<Typography variant="body1">{p.description}</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</CardActionArea>
|
||||
</NextLink>
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
|
||||
<Box>
|
||||
<NextLink passHref href="/console/matrix/products/new">
|
||||
<Button variant="contained">Create a product</Button>
|
||||
</NextLink>
|
||||
</Box>
|
||||
</Container>
|
||||
</ConsoleLayout>
|
||||
)
|
||||
|
82
src/pages/console/matrix/products/new.tsx
Normal file
82
src/pages/console/matrix/products/new.tsx
Normal file
@ -0,0 +1,82 @@
|
||||
import { ConsoleLayout, getConsoleStaticProps } from '@/components/layouts/ConsoleLayout'
|
||||
import { Typography, Container, Box, Button, TextField, Collapse, Alert } from '@mui/material'
|
||||
import { useForm } from 'react-hook-form'
|
||||
import { useState } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
import NextLink from 'next/link'
|
||||
import { sni } from '@/services/network'
|
||||
|
||||
import ErrorIcon from '@mui/icons-material/Error'
|
||||
|
||||
export async function getStaticProps() {
|
||||
return getConsoleStaticProps({
|
||||
props: {
|
||||
title: 'Matrix',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
interface MatrixProductNewForm {
|
||||
name: string
|
||||
alias: string
|
||||
description: string
|
||||
introduction: string
|
||||
}
|
||||
|
||||
export default function ProductNew() {
|
||||
const { handleSubmit, register } = useForm<MatrixProductNewForm>()
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
const [busy, setBusy] = useState<boolean>(false)
|
||||
|
||||
async function onSubmit(data: any) {
|
||||
try {
|
||||
setBusy(true)
|
||||
await sni.post('/cgi/ma/products', data)
|
||||
router.push('/console/matrix')
|
||||
} catch (err: any) {
|
||||
setError(err.toString())
|
||||
} finally {
|
||||
setBusy(false)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<ConsoleLayout>
|
||||
<Container sx={{ py: 16, display: 'flex', flexDirection: 'column', gap: 4 }}>
|
||||
<Typography variant="h3" component="h1">
|
||||
Create a product
|
||||
</Typography>
|
||||
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<Box display="flex" flexDirection="column" maxWidth="sm" gap={2.5}>
|
||||
<Collapse in={!!error} sx={{ width: '100%' }}>
|
||||
<Alert icon={<ErrorIcon fontSize="inherit" />} severity="error">
|
||||
{error}
|
||||
</Alert>
|
||||
</Collapse>
|
||||
|
||||
<TextField label="Name" {...register('name')} />
|
||||
|
||||
<TextField label="Alias" {...register('alias')} />
|
||||
|
||||
<TextField minRows={3} maxRows={3} multiline label="Description" {...register('description')} />
|
||||
|
||||
<TextField minRows={5} multiline label="Introduction" {...register('introduction')} />
|
||||
|
||||
<Box sx={{ mt: 5 }} display="flex" gap={2}>
|
||||
<Button variant="contained" type="submit" disabled={busy}>
|
||||
Create
|
||||
</Button>
|
||||
<NextLink passHref href="/console/matrix">
|
||||
<Button disabled={busy}>Cancel</Button>
|
||||
</NextLink>
|
||||
</Box>
|
||||
</Box>
|
||||
</form>
|
||||
</Container>
|
||||
</ConsoleLayout>
|
||||
)
|
||||
}
|
25
src/services/matrix/product.ts
Normal file
25
src/services/matrix/product.ts
Normal file
@ -0,0 +1,25 @@
|
||||
export interface MaProduct {
|
||||
id: number
|
||||
created_at: Date
|
||||
updated_at: Date
|
||||
deleted_at?: Date
|
||||
icon: string
|
||||
name: string
|
||||
alias: string
|
||||
description: string
|
||||
previews: string[]
|
||||
tags: string[]
|
||||
meta: MaProductMeta
|
||||
releases: null
|
||||
account_id: number
|
||||
}
|
||||
|
||||
export interface MaProductMeta {
|
||||
id: number
|
||||
created_at: Date
|
||||
updated_at: Date
|
||||
deleted_at?: Date
|
||||
introduction: string
|
||||
attachments: string[]
|
||||
product_id: number
|
||||
}
|
Loading…
Reference in New Issue
Block a user