mirror of
https://github.com/Portabase/portabase.git
synced 2026-07-14 11:16:13 +02:00
Working on project front side.
This commit is contained in:
+31
@@ -0,0 +1,31 @@
|
||||
"use client"
|
||||
import {ButtonWithConfirm} from "@/components/wrappers/Button/ButtonWithConfirm/ButtonWithConfirm";
|
||||
import {Trash2} from "lucide-react";
|
||||
|
||||
export type ButtonDeleteProjectProps = {
|
||||
text? : string
|
||||
}
|
||||
|
||||
export const ButtonDeleteProject = (props: ButtonDeleteProjectProps) => {
|
||||
|
||||
// const mutation = useMutation({
|
||||
// mutationFn: () => deleteUserAction(""),
|
||||
// onSuccess: async () => {
|
||||
// await signOutAction();
|
||||
// },
|
||||
// })
|
||||
|
||||
return (
|
||||
<ButtonWithConfirm
|
||||
text={props.text ? props.text : ""}
|
||||
onClick={() => {
|
||||
// mutation.mutate()
|
||||
console.log("ok")
|
||||
}}
|
||||
variant={"destructive"}
|
||||
// isPending={mutation.isPending}
|
||||
className="gap-2"
|
||||
icon={<Trash2/>}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
"use client";
|
||||
|
||||
import {Card, CardContent, CardHeader} from "@/components/ui/card";
|
||||
import Link from "next/link";
|
||||
import Image from "next/image"
|
||||
import {ConnectionCircle} from "@/components/wrappers/connection-circle";
|
||||
import {formatDateLastContact} from "@/utils/date-formatting";
|
||||
|
||||
export type projectDatabaseCardProps = {
|
||||
data: any,
|
||||
extendedProps: any
|
||||
}
|
||||
|
||||
export const ProjectDatabaseCard = (props: projectDatabaseCardProps) => {
|
||||
const {data: database, extendedProps: extendedProps} = props;
|
||||
return (
|
||||
<Link href={`/dashboard/projects/${extendedProps.id}/database/${database.id}`}>
|
||||
<Card className="flex flex-row justify-between">
|
||||
<div className="flex flex-row items-center gap-2">
|
||||
<Image
|
||||
src="/PostgreSQL.png"
|
||||
alt="Database type Icon"
|
||||
width={60}
|
||||
height={60}
|
||||
className="object-cover ml-4"
|
||||
/>
|
||||
<div >
|
||||
<CardHeader>Name : {database.name}</CardHeader>
|
||||
<CardContent>
|
||||
Last contact: {formatDateLastContact(database.lastContact)}
|
||||
</CardContent>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-3 mr-3">
|
||||
<ConnectionCircle date={database.lastContact}/>
|
||||
</div>
|
||||
</Card>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
+2
-2
@@ -14,8 +14,8 @@ import {Input} from "@/components/ui/input";
|
||||
import {Form} from "@/components/ui/form"
|
||||
import {Button} from "@/components/ui/button";
|
||||
import {useMutation} from "@tanstack/react-query";
|
||||
import {ProjectSchema, ProjectType} from "@/components/wrappers/Project/ProjectForm.schema";
|
||||
import {createProjectAction, updateProjectAction} from "@/components/wrappers/Project/project-form.action";
|
||||
import {ProjectSchema, ProjectType} from "@/components/wrappers/Dashboard/Projects/ProjectsForm/ProjectForm.schema";
|
||||
import {createProjectAction, updateProjectAction} from "@/components/wrappers/Dashboard/Projects/ProjectsForm/project-form.action";
|
||||
import {useRouter} from "next/navigation";
|
||||
import {Database, Organization, Project, Projects} from "@prisma/client"
|
||||
import {MultiSelect} from "@/components/wrappers/MultiSelect/MultiSelect";
|
||||
+5
-5
@@ -2,7 +2,7 @@
|
||||
|
||||
import {userAction} from "@/safe-actions";
|
||||
import {prisma} from "@/prisma";
|
||||
import {ProjectSchema} from "@/components/wrappers/Project/ProjectForm.schema";
|
||||
import {ProjectSchema} from "@/components/wrappers/Dashboard/Projects/ProjectsForm/ProjectForm.schema";
|
||||
import {z} from "zod";
|
||||
import {ServerActionResult} from "@/types/action-type";
|
||||
import {Projects} from "@prisma/client";
|
||||
@@ -42,7 +42,7 @@ export const createProjectAction = userAction
|
||||
success: true,
|
||||
value: project,
|
||||
actionSuccess: {
|
||||
message: "Project has been successfully created.",
|
||||
message: "ProjectsForm has been successfully created.",
|
||||
messageParams: {projectName: parsedInput.data.name},
|
||||
},
|
||||
};
|
||||
@@ -50,7 +50,7 @@ export const createProjectAction = userAction
|
||||
return {
|
||||
success: false,
|
||||
actionError: {
|
||||
message: "Failed to create Project.",
|
||||
message: "Failed to create ProjectsForm.",
|
||||
status: 500, // Optional: Use a meaningful status code
|
||||
cause: error instanceof Error ? error.message : "Unknown error",
|
||||
messageParams: {projectName: parsedInput.data.name},
|
||||
@@ -130,7 +130,7 @@ export const updateProjectAction = userAction
|
||||
success: true,
|
||||
value: updatedProject,
|
||||
actionSuccess: {
|
||||
message: "Project has been successfully updated.",
|
||||
message: "ProjectsForm has been successfully updated.",
|
||||
messageParams: {projectName: parsedInput.data.name},
|
||||
},
|
||||
};
|
||||
@@ -138,7 +138,7 @@ export const updateProjectAction = userAction
|
||||
return {
|
||||
success: false,
|
||||
actionError: {
|
||||
message: "Failed to update Project.",
|
||||
message: "Failed to update ProjectsForm.",
|
||||
status: 500, // Optional: Use a meaningful status code
|
||||
cause: error instanceof Error ? error.message : "Unknown error",
|
||||
messageParams: {projectName: parsedInput.data.name},
|
||||
@@ -5,7 +5,7 @@ import Link from "next/link";
|
||||
import {SidebarMenu, SidebarMenuAction, SidebarMenuButton, SidebarMenuItem} from "@/components/ui/sidebar";
|
||||
import {cn} from "@/lib/utils";
|
||||
import {buttonVariants} from "@/components/ui/button";
|
||||
import {ChartArea, FolderKanban, Home, Settings, ShieldHalf} from "lucide-react";
|
||||
import {ChartArea, FolderKanban, Home, Layers, Settings, ShieldHalf} from "lucide-react";
|
||||
import {usePathname} from "next/navigation";
|
||||
|
||||
export type SidebarMenuCustomProps = {}
|
||||
@@ -24,7 +24,7 @@ export const SidebarMenuCustom = (props: SidebarMenuCustomProps) => {
|
||||
{
|
||||
title: "Projects",
|
||||
url: "projects",
|
||||
icon: FolderKanban,
|
||||
icon: Layers,
|
||||
},
|
||||
{
|
||||
title: "Agents",
|
||||
|
||||
@@ -12,6 +12,7 @@ export type cardsWithPaginationProps = {
|
||||
cardsPerPage?: number
|
||||
numberOfColumns?: number
|
||||
maxVisiblePages?: number
|
||||
extendedProps?: any
|
||||
}
|
||||
|
||||
|
||||
@@ -40,12 +41,11 @@ export const CardsWithPagination = (props: cardsWithPaginationProps) => {
|
||||
goToPage(Math.min(totalPages, currentPage + 1))
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div className={cn("flex flex-col h-full justify-between", className)}>
|
||||
<div className={cn(`grid h-max auto-rows-min gap-4 md:grid-cols-${numberOfColumns}`)}>
|
||||
{currentCards.map((card, key) => (
|
||||
<CardItem key={key} data={card}/>
|
||||
<CardItem key={key} data={card} extendedProps={props.extendedProps} />
|
||||
))}
|
||||
</div>
|
||||
<PaginationNavigation
|
||||
|
||||
@@ -8,9 +8,7 @@ export type connectionCircleProps = {
|
||||
export const ConnectionCircle = ({date}: connectionCircleProps) => {
|
||||
|
||||
let style = "";
|
||||
|
||||
const interval = new Date().getTime() - new Date(date).getTime()
|
||||
|
||||
if (interval < 10000) {
|
||||
style = "bg-green-400 border-green-600"
|
||||
} else if (1000 <= interval && interval <= 20000) {
|
||||
|
||||
@@ -7,4 +7,10 @@ export function humanReadableDate(rawDate: string | number | Date) {
|
||||
export function timeAgo(rawDate: string | number | Date) {
|
||||
const date = new Date(rawDate)
|
||||
return "Not implemented"
|
||||
}
|
||||
|
||||
export function formatDateLastContact(lastContact: string | number | Date | null) {
|
||||
return lastContact
|
||||
? format(new Date(lastContact), 'dd/MM/yyyy HH:mm')
|
||||
: "Never connected."
|
||||
}
|
||||
Reference in New Issue
Block a user