删除示例文件;更新docker服务文件
This commit is contained in:
16
docker/docker-compose_influxdb.yml
Normal file
16
docker/docker-compose_influxdb.yml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
version: '3.8'
|
||||||
|
services:
|
||||||
|
influxdb:
|
||||||
|
image: influxdb:2.7
|
||||||
|
container_name: influxdb
|
||||||
|
environment:
|
||||||
|
DOCKER_INFLUXDB_INIT_MODE: setup
|
||||||
|
DOCKER_INFLUXDB_INIT_USERNAME: tjwater
|
||||||
|
DOCKER_INFLUXDB_INIT_PASSWORD: Tjwater@123456
|
||||||
|
DOCKER_INFLUXDB_INIT_ORG: TJWATERORG
|
||||||
|
DOCKER_INFLUXDB_INIT_BUCKET: TJWATERBUCKET
|
||||||
|
DOCKER_INFLUXDB_INIT_ADMIN_TOKEN: kMPX2V5HsbzPpUT2B9HPBu1sTG1Emf-lPlT2UjxYnGAuocpXq_f_0lK4HHs-TbbKyjsZpICkMsyXG_V2D7P7yQ==
|
||||||
|
ports:
|
||||||
|
- "8086:8086"
|
||||||
|
volumes:
|
||||||
|
- C:\Users\admin\Documents\docker\influxdb\data:/var/lib/influxdb2
|
||||||
26
keycloak/.vscode/tasks.json
vendored
26
keycloak/.vscode/tasks.json
vendored
@@ -1,26 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "2.0.0",
|
|
||||||
"tasks": [
|
|
||||||
{
|
|
||||||
"label": "Docker Compose Up",
|
|
||||||
"type": "shell",
|
|
||||||
"command": "docker compose --project-name keycloak -f docker-compose.yml up -d --build",
|
|
||||||
"group": "build",
|
|
||||||
"problemMatcher": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Docker Compose Down",
|
|
||||||
"type": "shell",
|
|
||||||
"command": "docker compose --project-name keycloak -f docker-compose.yml down",
|
|
||||||
"group": "build",
|
|
||||||
"problemMatcher": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Docker Compose Restart",
|
|
||||||
"type": "shell",
|
|
||||||
"command": "docker compose --project-name keycloak -f docker-compose.yml restart",
|
|
||||||
"group": "build",
|
|
||||||
"problemMatcher": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
26
mapservice/.vscode/tasks.json
vendored
26
mapservice/.vscode/tasks.json
vendored
@@ -1,26 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "2.0.0",
|
|
||||||
"tasks": [
|
|
||||||
{
|
|
||||||
"label": "Docker Compose Up",
|
|
||||||
"type": "shell",
|
|
||||||
"command": "docker compose --project-name mapservice -f docker-compose.yml up -d --build",
|
|
||||||
"group": "build",
|
|
||||||
"problemMatcher": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Docker Compose Down",
|
|
||||||
"type": "shell",
|
|
||||||
"command": "docker compose --project-name mapservice -f docker-compose.yml down",
|
|
||||||
"group": "build",
|
|
||||||
"problemMatcher": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "Docker Compose Restart",
|
|
||||||
"type": "shell",
|
|
||||||
"command": "docker compose --project-name mapservice -f docker-compose.yml restart",
|
|
||||||
"group": "build",
|
|
||||||
"problemMatcher": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import { Autocomplete, Box, MenuItem, Select, TextField } from "@mui/material";
|
|
||||||
import { Create, useAutocomplete } from "@refinedev/mui";
|
|
||||||
import { useForm } from "@refinedev/react-hook-form";
|
|
||||||
import { Controller } from "react-hook-form";
|
|
||||||
|
|
||||||
export default function BlogPostCreate() {
|
|
||||||
const {
|
|
||||||
saveButtonProps,
|
|
||||||
refineCore: { formLoading, onFinish },
|
|
||||||
handleSubmit,
|
|
||||||
register,
|
|
||||||
control,
|
|
||||||
formState: { errors },
|
|
||||||
} = useForm({});
|
|
||||||
|
|
||||||
const { autocompleteProps: categoryAutocompleteProps } = useAutocomplete({
|
|
||||||
resource: "categories",
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Create isLoading={formLoading} saveButtonProps={saveButtonProps}>
|
|
||||||
<Box
|
|
||||||
component="form"
|
|
||||||
sx={{ display: "flex", flexDirection: "column" }}
|
|
||||||
autoComplete="off"
|
|
||||||
>
|
|
||||||
<TextField
|
|
||||||
{...register("title", {
|
|
||||||
required: "This field is required",
|
|
||||||
})}
|
|
||||||
error={!!(errors as any)?.title}
|
|
||||||
helperText={(errors as any)?.title?.message}
|
|
||||||
margin="normal"
|
|
||||||
fullWidth
|
|
||||||
InputLabelProps={{ shrink: true }}
|
|
||||||
type="text"
|
|
||||||
label={"Title"}
|
|
||||||
name="title"
|
|
||||||
/>
|
|
||||||
<TextField
|
|
||||||
{...register("content", {
|
|
||||||
required: "This field is required",
|
|
||||||
})}
|
|
||||||
error={!!(errors as any)?.content}
|
|
||||||
helperText={(errors as any)?.content?.message}
|
|
||||||
margin="normal"
|
|
||||||
fullWidth
|
|
||||||
InputLabelProps={{ shrink: true }}
|
|
||||||
multiline
|
|
||||||
label={"Content"}
|
|
||||||
name="content"
|
|
||||||
/>
|
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
name={"category.id"}
|
|
||||||
rules={{ required: "This field is required" }}
|
|
||||||
// eslint-disable-next-line
|
|
||||||
defaultValue={null as any}
|
|
||||||
render={({ field }) => (
|
|
||||||
<Autocomplete
|
|
||||||
{...categoryAutocompleteProps}
|
|
||||||
{...field}
|
|
||||||
onChange={(_, value) => {
|
|
||||||
field.onChange(value.id);
|
|
||||||
}}
|
|
||||||
getOptionLabel={(item) => {
|
|
||||||
return (
|
|
||||||
categoryAutocompleteProps?.options?.find((p) => {
|
|
||||||
const itemId =
|
|
||||||
typeof item === "object"
|
|
||||||
? item?.id?.toString()
|
|
||||||
: item?.toString();
|
|
||||||
const pId = p?.id?.toString();
|
|
||||||
return itemId === pId;
|
|
||||||
})?.title ?? ""
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
isOptionEqualToValue={(option, value) => {
|
|
||||||
const optionId = option?.id?.toString();
|
|
||||||
const valueId =
|
|
||||||
typeof value === "object"
|
|
||||||
? value?.id?.toString()
|
|
||||||
: value?.toString();
|
|
||||||
return value === undefined || optionId === valueId;
|
|
||||||
}}
|
|
||||||
renderInput={(params) => (
|
|
||||||
<TextField
|
|
||||||
{...params}
|
|
||||||
label={"Category"}
|
|
||||||
margin="normal"
|
|
||||||
variant="outlined"
|
|
||||||
error={!!(errors as any)?.category?.id}
|
|
||||||
helperText={(errors as any)?.category?.id?.message}
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Controller
|
|
||||||
name="status"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => {
|
|
||||||
return (
|
|
||||||
<Select
|
|
||||||
{...field}
|
|
||||||
value={field?.value || "draft"}
|
|
||||||
label={"Status"}
|
|
||||||
>
|
|
||||||
<MenuItem value="draft">Draft</MenuItem>
|
|
||||||
<MenuItem value="published">Published</MenuItem>
|
|
||||||
<MenuItem value="rejected">Rejected</MenuItem>
|
|
||||||
</Select>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</Create>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import { Autocomplete, Box, Select, TextField } from "@mui/material";
|
|
||||||
import MenuItem from "@mui/material/MenuItem";
|
|
||||||
import { Edit, useAutocomplete } from "@refinedev/mui";
|
|
||||||
import { useForm } from "@refinedev/react-hook-form";
|
|
||||||
import { Controller } from "react-hook-form";
|
|
||||||
|
|
||||||
export default function BlogPostEdit() {
|
|
||||||
const {
|
|
||||||
saveButtonProps,
|
|
||||||
refineCore: { query, formLoading, onFinish },
|
|
||||||
handleSubmit,
|
|
||||||
register,
|
|
||||||
control,
|
|
||||||
formState: { errors },
|
|
||||||
} = useForm({});
|
|
||||||
|
|
||||||
const blogPostsData = query?.data?.data;
|
|
||||||
|
|
||||||
const { autocompleteProps: categoryAutocompleteProps } = useAutocomplete({
|
|
||||||
resource: "categories",
|
|
||||||
defaultValue: blogPostsData?.category?.id,
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Edit isLoading={formLoading} saveButtonProps={saveButtonProps}>
|
|
||||||
<Box
|
|
||||||
component="form"
|
|
||||||
sx={{ display: "flex", flexDirection: "column" }}
|
|
||||||
autoComplete="off"
|
|
||||||
>
|
|
||||||
<TextField
|
|
||||||
{...register("title", {
|
|
||||||
required: "This field is required",
|
|
||||||
})}
|
|
||||||
error={!!(errors as any)?.title}
|
|
||||||
helperText={(errors as any)?.title?.message}
|
|
||||||
margin="normal"
|
|
||||||
fullWidth
|
|
||||||
InputLabelProps={{ shrink: true }}
|
|
||||||
type="text"
|
|
||||||
label={"Title"}
|
|
||||||
name="title"
|
|
||||||
/>
|
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
name={"category.id"}
|
|
||||||
rules={{ required: "This field is required" }}
|
|
||||||
// eslint-disable-next-line
|
|
||||||
defaultValue={null as any}
|
|
||||||
render={({ field }) => (
|
|
||||||
<Autocomplete
|
|
||||||
{...categoryAutocompleteProps}
|
|
||||||
{...field}
|
|
||||||
onChange={(_, value) => {
|
|
||||||
field.onChange(value.id);
|
|
||||||
}}
|
|
||||||
getOptionLabel={(item) => {
|
|
||||||
return (
|
|
||||||
categoryAutocompleteProps?.options?.find((p) => {
|
|
||||||
const itemId =
|
|
||||||
typeof item === "object"
|
|
||||||
? item?.id?.toString()
|
|
||||||
: item?.toString();
|
|
||||||
const pId = p?.id?.toString();
|
|
||||||
return itemId === pId;
|
|
||||||
})?.title ?? ""
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
isOptionEqualToValue={(option, value) => {
|
|
||||||
const optionId = option?.id?.toString();
|
|
||||||
const valueId =
|
|
||||||
typeof value === "object"
|
|
||||||
? value?.id?.toString()
|
|
||||||
: value?.toString();
|
|
||||||
return value === undefined || optionId === valueId;
|
|
||||||
}}
|
|
||||||
renderInput={(params) => (
|
|
||||||
<TextField
|
|
||||||
{...params}
|
|
||||||
label={"Category"}
|
|
||||||
margin="normal"
|
|
||||||
variant="outlined"
|
|
||||||
error={!!(errors as any)?.category?.id}
|
|
||||||
helperText={(errors as any)?.category?.id?.message}
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Controller
|
|
||||||
name="status"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => {
|
|
||||||
return (
|
|
||||||
<Select
|
|
||||||
{...field}
|
|
||||||
value={field?.value || "draft"}
|
|
||||||
label={"Status"}
|
|
||||||
>
|
|
||||||
<MenuItem value="draft">Draft</MenuItem>
|
|
||||||
<MenuItem value="published">Published</MenuItem>
|
|
||||||
<MenuItem value="rejected">Rejected</MenuItem>
|
|
||||||
</Select>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<TextField
|
|
||||||
{...register("content", {
|
|
||||||
required: "This field is required",
|
|
||||||
})}
|
|
||||||
error={!!(errors as any)?.content}
|
|
||||||
helperText={(errors as any)?.content?.message}
|
|
||||||
margin="normal"
|
|
||||||
fullWidth
|
|
||||||
InputLabelProps={{ shrink: true }}
|
|
||||||
multiline
|
|
||||||
label={"Content"}
|
|
||||||
name="content"
|
|
||||||
rows={4}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</Edit>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import authOptions from "@app/api/auth/[...nextauth]/options";
|
|
||||||
import { Header } from "@components/header";
|
|
||||||
import { ThemedLayout } from "@refinedev/mui";
|
|
||||||
import { getServerSession } from "next-auth/next";
|
|
||||||
import { redirect } from "next/navigation";
|
|
||||||
import React from "react";
|
|
||||||
|
|
||||||
export default async function Layout({ children }: React.PropsWithChildren) {
|
|
||||||
const data = await getData();
|
|
||||||
|
|
||||||
if (!data.session?.user) {
|
|
||||||
return redirect("/login");
|
|
||||||
}
|
|
||||||
|
|
||||||
return <ThemedLayout Header={Header}>{children}</ThemedLayout>;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getData() {
|
|
||||||
const session = await getServerSession(authOptions);
|
|
||||||
return {
|
|
||||||
session,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,130 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import { Typography } from "@mui/material";
|
|
||||||
import { DataGrid, type GridColDef } from "@mui/x-data-grid";
|
|
||||||
import { useMany } from "@refinedev/core";
|
|
||||||
import {
|
|
||||||
DateField,
|
|
||||||
DeleteButton,
|
|
||||||
EditButton,
|
|
||||||
List,
|
|
||||||
ShowButton,
|
|
||||||
useDataGrid,
|
|
||||||
} from "@refinedev/mui";
|
|
||||||
import React from "react";
|
|
||||||
|
|
||||||
export default function BlogPostList() {
|
|
||||||
const { result, dataGridProps } = useDataGrid({
|
|
||||||
syncWithLocation: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const {
|
|
||||||
result: { data: categories },
|
|
||||||
query: { isLoading: categoryIsLoading },
|
|
||||||
} = useMany({
|
|
||||||
resource: "categories",
|
|
||||||
ids:
|
|
||||||
result?.data?.map((item: any) => item?.category?.id).filter(Boolean) ??
|
|
||||||
[],
|
|
||||||
queryOptions: {
|
|
||||||
enabled: !!result?.data,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const columns = React.useMemo<GridColDef[]>(
|
|
||||||
() => [
|
|
||||||
{
|
|
||||||
field: "id",
|
|
||||||
headerName: "ID",
|
|
||||||
type: "number",
|
|
||||||
minWidth: 50,
|
|
||||||
display: "flex",
|
|
||||||
align: "left",
|
|
||||||
headerAlign: "left",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: "title",
|
|
||||||
headerName: "Title",
|
|
||||||
minWidth: 200,
|
|
||||||
display: "flex",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: "content",
|
|
||||||
flex: 1,
|
|
||||||
headerName: "Content",
|
|
||||||
minWidth: 250,
|
|
||||||
display: "flex",
|
|
||||||
renderCell: function render({ value }) {
|
|
||||||
if (!value) return "-";
|
|
||||||
return (
|
|
||||||
<Typography
|
|
||||||
component="p"
|
|
||||||
whiteSpace="pre"
|
|
||||||
overflow="hidden"
|
|
||||||
textOverflow="ellipsis"
|
|
||||||
>
|
|
||||||
{value}
|
|
||||||
</Typography>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: "category",
|
|
||||||
headerName: "Category",
|
|
||||||
minWidth: 160,
|
|
||||||
display: "flex",
|
|
||||||
valueGetter: (_, row) => {
|
|
||||||
const value = row?.category;
|
|
||||||
return value;
|
|
||||||
},
|
|
||||||
renderCell: function render({ value }) {
|
|
||||||
return categoryIsLoading ? (
|
|
||||||
<>Loading...</>
|
|
||||||
) : (
|
|
||||||
categories?.find((item) => item.id === value?.id)?.title
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: "status",
|
|
||||||
headerName: "Status",
|
|
||||||
minWidth: 80,
|
|
||||||
display: "flex",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: "createdAt",
|
|
||||||
headerName: "Created at",
|
|
||||||
minWidth: 120,
|
|
||||||
display: "flex",
|
|
||||||
renderCell: function render({ value }) {
|
|
||||||
return <DateField value={value} />;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: "actions",
|
|
||||||
headerName: "Actions",
|
|
||||||
align: "right",
|
|
||||||
headerAlign: "right",
|
|
||||||
minWidth: 120,
|
|
||||||
sortable: false,
|
|
||||||
display: "flex",
|
|
||||||
renderCell: function render({ row }) {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<EditButton hideText recordItemId={row.id} />
|
|
||||||
<ShowButton hideText recordItemId={row.id} />
|
|
||||||
<DeleteButton hideText recordItemId={row.id} />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[categories, categoryIsLoading]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<List>
|
|
||||||
<DataGrid {...dataGridProps} columns={columns} />
|
|
||||||
</List>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import { Stack, Typography } from "@mui/material";
|
|
||||||
import { useOne, useShow } from "@refinedev/core";
|
|
||||||
import {
|
|
||||||
DateField,
|
|
||||||
MarkdownField,
|
|
||||||
Show,
|
|
||||||
TextFieldComponent as TextField,
|
|
||||||
} from "@refinedev/mui";
|
|
||||||
|
|
||||||
export default function BlogPostShow() {
|
|
||||||
const { result: record, query } = useShow({});
|
|
||||||
|
|
||||||
const { isLoading } = query;
|
|
||||||
|
|
||||||
const {
|
|
||||||
result: category,
|
|
||||||
query: { isLoading: categoryIsLoading },
|
|
||||||
} = useOne({
|
|
||||||
resource: "categories",
|
|
||||||
id: record?.category?.id || "",
|
|
||||||
queryOptions: {
|
|
||||||
enabled: !!record,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Show isLoading={isLoading}>
|
|
||||||
<Stack gap={1}>
|
|
||||||
<Typography variant="body1" fontWeight="bold">
|
|
||||||
{"ID"}
|
|
||||||
</Typography>
|
|
||||||
<TextField value={record?.id} />
|
|
||||||
|
|
||||||
<Typography variant="body1" fontWeight="bold">
|
|
||||||
{"Title"}
|
|
||||||
</Typography>
|
|
||||||
<TextField value={record?.title} />
|
|
||||||
|
|
||||||
<Typography variant="body1" fontWeight="bold">
|
|
||||||
{"Content"}
|
|
||||||
</Typography>
|
|
||||||
<MarkdownField value={record?.content} />
|
|
||||||
|
|
||||||
<Typography variant="body1" fontWeight="bold">
|
|
||||||
{"Category"}
|
|
||||||
</Typography>
|
|
||||||
{categoryIsLoading ? <>Loading...</> : <>{category?.title}</>}
|
|
||||||
<Typography variant="body1" fontWeight="bold">
|
|
||||||
{"Status"}
|
|
||||||
</Typography>
|
|
||||||
<TextField value={record?.status} />
|
|
||||||
|
|
||||||
<Typography variant="body1" fontWeight="bold">
|
|
||||||
{"CreatedAt"}
|
|
||||||
</Typography>
|
|
||||||
<DateField value={record?.createdAt} />
|
|
||||||
</Stack>
|
|
||||||
</Show>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import { Box, TextField } from "@mui/material";
|
|
||||||
import { Create } from "@refinedev/mui";
|
|
||||||
import { useForm } from "@refinedev/react-hook-form";
|
|
||||||
|
|
||||||
export default function CategoryCreate() {
|
|
||||||
const {
|
|
||||||
saveButtonProps,
|
|
||||||
refineCore: { formLoading },
|
|
||||||
register,
|
|
||||||
formState: { errors },
|
|
||||||
} = useForm({});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Create isLoading={formLoading} saveButtonProps={saveButtonProps}>
|
|
||||||
<Box
|
|
||||||
component="form"
|
|
||||||
sx={{ display: "flex", flexDirection: "column" }}
|
|
||||||
autoComplete="off"
|
|
||||||
>
|
|
||||||
<TextField
|
|
||||||
{...register("title", {
|
|
||||||
required: "This field is required",
|
|
||||||
})}
|
|
||||||
error={!!(errors as any)?.title}
|
|
||||||
helperText={(errors as any)?.title?.message}
|
|
||||||
margin="normal"
|
|
||||||
fullWidth
|
|
||||||
InputLabelProps={{ shrink: true }}
|
|
||||||
type="text"
|
|
||||||
label={"Title"}
|
|
||||||
name="title"
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</Create>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import { Box, TextField } from "@mui/material";
|
|
||||||
import { Edit } from "@refinedev/mui";
|
|
||||||
import { useForm } from "@refinedev/react-hook-form";
|
|
||||||
|
|
||||||
export default function CategoryEdit() {
|
|
||||||
const {
|
|
||||||
saveButtonProps,
|
|
||||||
register,
|
|
||||||
formState: { errors },
|
|
||||||
} = useForm({});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Edit saveButtonProps={saveButtonProps}>
|
|
||||||
<Box
|
|
||||||
component="form"
|
|
||||||
sx={{ display: "flex", flexDirection: "column" }}
|
|
||||||
autoComplete="off"
|
|
||||||
>
|
|
||||||
<TextField
|
|
||||||
{...register("title", {
|
|
||||||
required: "This field is required",
|
|
||||||
})}
|
|
||||||
error={!!(errors as any)?.title}
|
|
||||||
helperText={(errors as any)?.title?.message}
|
|
||||||
margin="normal"
|
|
||||||
fullWidth
|
|
||||||
InputLabelProps={{ shrink: true }}
|
|
||||||
type="text"
|
|
||||||
label={"Title"}
|
|
||||||
name="title"
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</Edit>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import authOptions from "@app/api/auth/[...nextauth]/options";
|
|
||||||
import { Header } from "@components/header";
|
|
||||||
import { ThemedLayout } from "@refinedev/mui";
|
|
||||||
import { getServerSession } from "next-auth/next";
|
|
||||||
import { redirect } from "next/navigation";
|
|
||||||
import React from "react";
|
|
||||||
|
|
||||||
export default async function Layout({ children }: React.PropsWithChildren) {
|
|
||||||
const data = await getData();
|
|
||||||
|
|
||||||
if (!data.session?.user) {
|
|
||||||
return redirect("/login");
|
|
||||||
}
|
|
||||||
|
|
||||||
return <ThemedLayout Header={Header}>{children}</ThemedLayout>;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getData() {
|
|
||||||
const session = await getServerSession(authOptions);
|
|
||||||
return {
|
|
||||||
session,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import { DataGrid, type GridColDef } from "@mui/x-data-grid";
|
|
||||||
import {
|
|
||||||
DeleteButton,
|
|
||||||
EditButton,
|
|
||||||
List,
|
|
||||||
ShowButton,
|
|
||||||
useDataGrid,
|
|
||||||
} from "@refinedev/mui";
|
|
||||||
import React from "react";
|
|
||||||
|
|
||||||
export default function CategoryList() {
|
|
||||||
const { dataGridProps } = useDataGrid({});
|
|
||||||
|
|
||||||
const columns = React.useMemo<GridColDef[]>(
|
|
||||||
() => [
|
|
||||||
{
|
|
||||||
field: "id",
|
|
||||||
headerName: "ID",
|
|
||||||
type: "number",
|
|
||||||
minWidth: 50,
|
|
||||||
display: "flex",
|
|
||||||
align: "left",
|
|
||||||
headerAlign: "left",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: "title",
|
|
||||||
flex: 1,
|
|
||||||
headerName: "Title",
|
|
||||||
minWidth: 200,
|
|
||||||
display: "flex",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: "actions",
|
|
||||||
headerName: "Actions",
|
|
||||||
align: "right",
|
|
||||||
headerAlign: "right",
|
|
||||||
minWidth: 120,
|
|
||||||
sortable: false,
|
|
||||||
display: "flex",
|
|
||||||
renderCell: function render({ row }) {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<EditButton hideText recordItemId={row.id} />
|
|
||||||
<ShowButton hideText recordItemId={row.id} />
|
|
||||||
<DeleteButton hideText recordItemId={row.id} />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<List>
|
|
||||||
<DataGrid {...dataGridProps} columns={columns} />
|
|
||||||
</List>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import { Stack, Typography } from "@mui/material";
|
|
||||||
import { useShow } from "@refinedev/core";
|
|
||||||
import { Show, TextFieldComponent as TextField } from "@refinedev/mui";
|
|
||||||
|
|
||||||
export default function CategoryShow() {
|
|
||||||
const { query } = useShow({});
|
|
||||||
const { data, isLoading } = query;
|
|
||||||
|
|
||||||
const record = data?.data;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Show isLoading={isLoading}>
|
|
||||||
<Stack gap={1}>
|
|
||||||
<Typography variant="body1" fontWeight="bold">
|
|
||||||
{"ID"}
|
|
||||||
</Typography>
|
|
||||||
<TextField value={record?.id} />
|
|
||||||
<Typography variant="body1" fontWeight="bold">
|
|
||||||
{"Title"}
|
|
||||||
</Typography>
|
|
||||||
<TextField value={record?.title} />
|
|
||||||
</Stack>
|
|
||||||
</Show>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user