update next, try fix next nav issue, minor improvements
# Conflicts: # apps/dashboard/src/middleware.ts # packages/db/src/services/organization.service.ts # pnpm-lock.yaml
This commit is contained in:
committed by
Carl-Gerhard Lindesvärd
parent
04375807d0
commit
4b50fed1dc
@@ -113,7 +113,7 @@ export function EventListItem(props: EventListItemProps) {
|
||||
|
||||
<Tooltiper asChild content={createdAt.toLocaleString()}>
|
||||
<div className="text-sm text-muted-foreground">
|
||||
{createdAt.toLocaleTimeString()}
|
||||
{createdAt.toLocaleString()}
|
||||
</div>
|
||||
</Tooltiper>
|
||||
</div>
|
||||
|
||||
@@ -2,13 +2,9 @@ import { FullPageEmptyState } from '@/components/full-page-empty-state';
|
||||
import FullWidthNavbar from '@/components/full-width-navbar';
|
||||
import { ProjectCard } from '@/components/projects/project-card';
|
||||
import SignOutButton from '@/components/sign-out-button';
|
||||
import { notFound, redirect } from 'next/navigation';
|
||||
import { redirect } from 'next/navigation';
|
||||
|
||||
import {
|
||||
getCurrentOrganizations,
|
||||
getCurrentProjects,
|
||||
getOrganizationBySlug,
|
||||
} from '@openpanel/db';
|
||||
import { getCurrentOrganizations, getCurrentProjects } from '@openpanel/db';
|
||||
|
||||
interface PageProps {
|
||||
params: {
|
||||
|
||||
@@ -4,7 +4,7 @@ import LiveEvents from './live-events';
|
||||
|
||||
const LiveEventsServer = async () => {
|
||||
const events = await getEvents(
|
||||
'SELECT * FROM events ORDER BY created_at LIMIT 30'
|
||||
'SELECT * FROM events ORDER BY created_at DESC LIMIT 30'
|
||||
);
|
||||
return <LiveEvents events={events.map(transformMinimalEvent)} />;
|
||||
};
|
||||
|
||||
@@ -3,70 +3,21 @@
|
||||
import { useEffect } from 'react';
|
||||
import AnimateHeight from '@/components/animate-height';
|
||||
import { ButtonContainer } from '@/components/button-container';
|
||||
import { CheckboxItem } from '@/components/forms/checkbox-item';
|
||||
import { InputWithLabel } from '@/components/forms/input-with-label';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Switch } from '@/components/ui/switch';
|
||||
import { api, handleError } from '@/trpc/client';
|
||||
import { cn } from '@/utils/cn';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import type { LucideIcon } from 'lucide-react';
|
||||
import { MonitorIcon, ServerIcon, SmartphoneIcon } from 'lucide-react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import type { ControllerRenderProps, SubmitHandler } from 'react-hook-form';
|
||||
import type { SubmitHandler } from 'react-hook-form';
|
||||
import { Controller, useForm, useWatch } from 'react-hook-form';
|
||||
import type { z } from 'zod';
|
||||
|
||||
import type { IServiceOrganization } from '@openpanel/db';
|
||||
import { zOnboardingProject } from '@openpanel/validation';
|
||||
|
||||
import OnboardingLayout, { OnboardingDescription } from '../onboarding-layout';
|
||||
|
||||
function CheckboxGroup({
|
||||
label,
|
||||
description,
|
||||
Icon,
|
||||
children,
|
||||
onChange,
|
||||
value,
|
||||
disabled,
|
||||
error,
|
||||
}: {
|
||||
label: string;
|
||||
description: string;
|
||||
Icon: LucideIcon;
|
||||
children?: React.ReactNode;
|
||||
error?: string;
|
||||
} & ControllerRenderProps) {
|
||||
const randId = Math.random().toString(36).substring(7);
|
||||
return (
|
||||
<div>
|
||||
<label
|
||||
className={cn(
|
||||
'flex items-center gap-4 px-4 py-6 transition-colors hover:bg-slate-100',
|
||||
disabled && 'cursor-not-allowed opacity-50'
|
||||
)}
|
||||
htmlFor={randId}
|
||||
>
|
||||
{Icon && <div className="w-6 shrink-0">{<Icon />}</div>}
|
||||
<div className="flex-1">
|
||||
<div className="font-medium">{label}</div>
|
||||
<div className="text-sm text-muted-foreground">{description}</div>
|
||||
{error && <div className="text-xs text-red-600">{error}</div>}
|
||||
</div>
|
||||
<div>
|
||||
<Switch
|
||||
disabled={disabled}
|
||||
checked={!!value}
|
||||
onCheckedChange={onChange}
|
||||
id={randId}
|
||||
/>
|
||||
</div>
|
||||
</label>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
type IForm = z.infer<typeof zOnboardingProject>;
|
||||
|
||||
const Tracking = () => {
|
||||
@@ -149,7 +100,7 @@ const Tracking = () => {
|
||||
name="website"
|
||||
control={form.control}
|
||||
render={({ field }) => (
|
||||
<CheckboxGroup
|
||||
<CheckboxItem
|
||||
error={form.formState.errors.website?.message}
|
||||
Icon={MonitorIcon}
|
||||
label="Website"
|
||||
@@ -167,14 +118,14 @@ const Tracking = () => {
|
||||
/>
|
||||
</div>
|
||||
</AnimateHeight>
|
||||
</CheckboxGroup>
|
||||
</CheckboxItem>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
name="app"
|
||||
control={form.control}
|
||||
render={({ field }) => (
|
||||
<CheckboxGroup
|
||||
<CheckboxItem
|
||||
error={form.formState.errors.app?.message}
|
||||
disabled={isWebsite}
|
||||
Icon={SmartphoneIcon}
|
||||
@@ -188,7 +139,7 @@ const Tracking = () => {
|
||||
name="backend"
|
||||
control={form.control}
|
||||
render={({ field }) => (
|
||||
<CheckboxGroup
|
||||
<CheckboxItem
|
||||
error={form.formState.errors.backend?.message}
|
||||
Icon={ServerIcon}
|
||||
label="Backend / API"
|
||||
|
||||
54
apps/dashboard/src/components/forms/checkbox-item.tsx
Normal file
54
apps/dashboard/src/components/forms/checkbox-item.tsx
Normal file
@@ -0,0 +1,54 @@
|
||||
import { forwardRef } from 'react';
|
||||
import { cn } from '@/utils/cn';
|
||||
import { slug } from '@/utils/slug';
|
||||
import type { LucideIcon } from 'lucide-react';
|
||||
import type { ControllerRenderProps } from 'react-hook-form';
|
||||
|
||||
import { Switch } from '../ui/switch';
|
||||
|
||||
type Props = {
|
||||
label: string;
|
||||
description: string;
|
||||
Icon: LucideIcon;
|
||||
children?: React.ReactNode;
|
||||
error?: string;
|
||||
} & ControllerRenderProps;
|
||||
|
||||
export const CheckboxItem = forwardRef<HTMLButtonElement, Props>(
|
||||
(
|
||||
{ label, description, Icon, children, onChange, value, disabled, error },
|
||||
ref
|
||||
) => {
|
||||
const id = slug(label);
|
||||
return (
|
||||
<div>
|
||||
<label
|
||||
className={cn(
|
||||
'flex items-center gap-4 px-4 py-6 transition-colors hover:bg-slate-100',
|
||||
disabled && 'cursor-not-allowed opacity-50'
|
||||
)}
|
||||
htmlFor={id}
|
||||
>
|
||||
{Icon && <div className="w-6 shrink-0">{<Icon />}</div>}
|
||||
<div className="flex-1">
|
||||
<div className="font-medium">{label}</div>
|
||||
<div className="text-sm text-muted-foreground">{description}</div>
|
||||
{error && <div className="text-xs text-red-600">{error}</div>}
|
||||
</div>
|
||||
<div>
|
||||
<Switch
|
||||
ref={ref}
|
||||
disabled={disabled}
|
||||
checked={!!value}
|
||||
onCheckedChange={onChange}
|
||||
id={id}
|
||||
/>
|
||||
</div>
|
||||
</label>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
CheckboxItem.displayName = 'CheckboxItem';
|
||||
@@ -1,3 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import { cn } from '@/utils/cn';
|
||||
|
||||
import { Logo } from './logo';
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { shortNumber } from '@/hooks/useNumerFormatter';
|
||||
import Link from 'next/link';
|
||||
import { escape } from 'sqlstring';
|
||||
|
||||
import type { IServiceProject } from '@openpanel/db';
|
||||
@@ -18,7 +17,7 @@ export async function ProjectCard({
|
||||
),
|
||||
chQuery<{ total: number; month: number; day: number }>(
|
||||
`
|
||||
SELECT
|
||||
SELECT
|
||||
(
|
||||
SELECT count(DISTINCT profile_id) as count FROM events WHERE project_id = ${escape(id)}
|
||||
) as total,
|
||||
@@ -32,8 +31,11 @@ export async function ProjectCard({
|
||||
),
|
||||
]);
|
||||
|
||||
// For some unknown reason I get when navigating back to this page when using <Link />
|
||||
// Should be solved: https://github.com/vercel/next.js/issues/61336
|
||||
// But still get the error
|
||||
return (
|
||||
<Link
|
||||
<a
|
||||
href={`/${organizationSlug}/${id}`}
|
||||
className="card inline-flex flex-col gap-2 p-4 transition-transform hover:-translate-y-1"
|
||||
>
|
||||
@@ -64,6 +66,6 @@ export async function ProjectCard({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user