feat: dashboard v2, esm, upgrades (#211)

* esm

* wip

* wip

* wip

* wip

* wip

* wip

* subscription notice

* wip

* wip

* wip

* fix envs

* fix: update docker build

* fix

* esm/types

* delete dashboard :D

* add patches to dockerfiles

* update packages + catalogs + ts

* wip

* remove native libs

* ts

* improvements

* fix redirects and fetching session

* try fix favicon

* fixes

* fix

* order and resize reportds within a dashboard

* improvements

* wip

* added userjot to dashboard

* fix

* add op

* wip

* different cache key

* improve date picker

* fix table

* event details loading

* redo onboarding completely

* fix login

* fix

* fix

* extend session, billing and improve bars

* fix

* reduce price on 10M
This commit is contained in:
Carl-Gerhard Lindesvärd
2025-10-16 12:27:44 +02:00
committed by GitHub
parent 436e81ecc9
commit 81a7e5d62e
741 changed files with 32695 additions and 16996 deletions

View File

@@ -0,0 +1,103 @@
'use client';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { Button } from '@/components/ui/button';
import { Widget, WidgetBody, WidgetHead } from '@/components/widget';
import { handleError, useTRPC } from '@/integrations/trpc/react';
import { showConfirm } from '@/modals';
import type { IServiceProjectWithClients } from '@openpanel/db';
import { useMutation } from '@tanstack/react-query';
import { useRouter } from '@tanstack/react-router';
import { addHours, format, startOfHour } from 'date-fns';
import { TrashIcon } from 'lucide-react';
import { toast } from 'sonner';
type Props = { project: IServiceProjectWithClients };
export default function DeleteProject({ project }: Props) {
const router = useRouter();
const trpc = useTRPC();
const mutation = useMutation(
trpc.project.delete.mutationOptions({
onError: handleError,
onSuccess: () => {
toast.success('Project updated');
router.invalidate();
},
}),
);
const cancelDeletionMutation = useMutation(
trpc.project.cancelDeletion.mutationOptions({
onError: handleError,
onSuccess: () => {
toast.success('Project updated');
router.invalidate();
},
}),
);
return (
<Widget className="max-w-screen-md w-full">
<WidgetHead>
<span className="title">Delete Project</span>
</WidgetHead>
<WidgetBody className="space-y-4">
<p>
Deleting your project will remove it from your organization and all of
its data. It'll be permanently deleted after 24 hours.
</p>
{project?.deleteAt && (
<Alert variant="destructive">
<AlertTitle>Project scheduled for deletion</AlertTitle>
<AlertDescription>
This project will be deleted on{' '}
<span className="font-medium">
{
// add 1 hour and round to the nearest hour
// Since we run cron once an hour
format(
startOfHour(addHours(project.deleteAt, 1)),
'yyyy-MM-dd HH:mm:ss',
)
}
</span>
. Any event associated with this project will be deleted.
</AlertDescription>
</Alert>
)}
<div className="flex gap-4 justify-start">
{project?.deleteAt && (
<Button
variant="outline"
onClick={() => {
cancelDeletionMutation.mutate({ projectId: project.id });
}}
loading={cancelDeletionMutation.isPending}
>
Cancel deletion
</Button>
)}
<Button
disabled={!!project?.deleteAt}
variant="destructive"
icon={TrashIcon}
loading={mutation.isPending}
onClick={() => {
showConfirm({
title: 'Delete Project',
text: 'Are you sure you want to delete this project?',
onConfirm: () => {
mutation.mutate({ projectId: project.id });
},
});
}}
>
Delete Project
</Button>
</div>
</WidgetBody>
</Widget>
);
}