@@ -12,12 +12,15 @@ import {
1212 getAnalyticsConfig ,
1313 updateAnalyticsConfig ,
1414} from "@/lib/settings" ;
15+ import { Card , CardContent , CardHeader , CardTitle } from "@/components/ui/card" ;
1516import { useMutation , useQuery , useQueryClient } from "@tanstack/react-query" ;
16- import { useState } from "react" ;
17+ import { ChartColumn , CircleX } from "lucide-react" ;
18+ import { useEffect , useState } from "react" ;
1719import { toast } from "sonner" ;
1820import { useReadOnlyMode } from "../providers/SessionProvider" ;
1921import { BaseTable } from "../baseTable" ;
2022import AddAnalyticsConfigForm from "../forms/AddAnalyticsConfigForm" ;
23+ import { Alert } from "../ui/alert" ;
2124import { Button } from "../ui/button" ;
2225import { DialogFooter , DialogHeader } from "../ui/dialog" ;
2326import { analyticsConfigColumns } from "./columns" ;
@@ -29,7 +32,6 @@ interface AnalyticsConfigTableProps {
2932export function AnalyticsConfigTable ( { projectId } : AnalyticsConfigTableProps ) {
3033 const [ isAddConfigDialogOpen , setIsAddConfigDialogOpen ] = useState ( false ) ;
3134 const [ isDeleteDialogOpen , setIsDeleteDialogOpen ] = useState ( false ) ;
32- const [ selectedRows , setSelectedRows ] = useState ( [ ] ) ;
3335 const isReadOnly = useReadOnlyMode ( ) ;
3436
3537 const queryClient = useQueryClient ( ) ;
@@ -41,21 +43,16 @@ export function AnalyticsConfigTable({ projectId }: AnalyticsConfigTableProps) {
4143
4244 const analyticsConfigRowData = [ data ] . filter ( ( config ) => config ) ;
4345
44- if ( isError ) {
45- toast . error ( "Error" , {
46- description : `Failed to fetch analytics config: ${ error . message } ` ,
47- } ) ;
48- }
49-
50- const deleteAnalyticsConfigHandler = useMutation ( {
51- mutationFn : ( ) => {
52- const deletePromises = selectedRows . map ( async ( row ) => {
53- const projectId = row . id ;
54- return deleteAnalyticsConfig ( projectId ) ;
46+ useEffect ( ( ) => {
47+ if ( isError && error ) {
48+ toast . error ( "Error" , {
49+ description : `Failed to fetch analytics config: ${ error . message } ` ,
5550 } ) ;
51+ }
52+ } , [ isError , error ] ) ;
5653
57- return Promise . all ( deletePromises ) ;
58- } ,
54+ const deleteAnalyticsConfigHandler = useMutation ( {
55+ mutationFn : async ( ) => deleteAnalyticsConfig ( projectId ) ,
5956 onSuccess : ( ) => {
6057 toast . success ( "Success" , {
6158 description : `Successfully deleted analytics configs.` ,
@@ -135,11 +132,11 @@ export function AnalyticsConfigTable({ projectId }: AnalyticsConfigTableProps) {
135132 < Dialog open = { isDeleteDialogOpen } onOpenChange = { setIsDeleteDialogOpen } >
136133 < DialogContent >
137134 < DialogHeader >
138- < DialogTitle > Delete Selected Analytics Config </ DialogTitle >
135+ < DialogTitle > Delete Analytics Configuration </ DialogTitle >
139136 < DialogDescription >
140- Are you sure you want to delete { selectedRows . length } selected
141- config { selectedRows . length > 1 ? "s" : "" } ? This action cannot be
142- undone.
137+ Are you sure you want to delete the analytics configuration for
138+ this project? This will remove all analytics tracking settings and
139+ cannot be undone.
143140 </ DialogDescription >
144141 </ DialogHeader >
145142 < DialogFooter >
@@ -163,48 +160,79 @@ export function AnalyticsConfigTable({ projectId }: AnalyticsConfigTableProps) {
163160 </ DialogContent >
164161 </ Dialog >
165162 < h1 className = "text-lg font-bold" > Analytics Configurations</ h1 >
166- < BaseTable
167- data = { analyticsConfigRowData }
168- columns = { analyticsConfigColumns (
169- Number ( projectId ) ,
170- addAnalyticsConfigHandler . isPending ,
171- (
172- projectId : number ,
173- keys : {
174- serverAnalyticsKey : string ;
175- clientAnalyticsKey : string ;
163+ { isError && (
164+ < Alert variant = "destructive" >
165+ < CircleX className = "h-4 w-4" />
166+ < span className = "text-sm" >
167+ Couldn't load analytics config: { error . message }
168+ </ span >
169+ </ Alert >
170+ ) }
171+ { isError ? null : ! isLoading && analyticsConfigRowData . length === 0 ? (
172+ < Card className = "max-w-full sm:max-w-md" >
173+ < CardHeader >
174+ < div className = "flex items-center gap-3" >
175+ < ChartColumn className = "h-5 w-5 text-muted-foreground" />
176+ < CardTitle > No Analytics Configuration</ CardTitle >
177+ </ div >
178+ </ CardHeader >
179+ < CardContent >
180+ < p className = "text-sm text-muted-foreground mb-4" >
181+ Project { projectId } has no analytics configuration yet. Add a
182+ server key and a client key to start tracking user interactions,
183+ visits, clicks, and custom events using Juno.
184+ </ p >
185+ < Button
186+ onClick = { ( ) => setIsAddConfigDialogOpen ( true ) }
187+ disabled = { isReadOnly || addAnalyticsConfigHandler . isPending }
188+ >
189+ Set up analytics
190+ </ Button >
191+ </ CardContent >
192+ </ Card >
193+ ) : (
194+ < BaseTable
195+ data = { analyticsConfigRowData }
196+ columns = { analyticsConfigColumns (
197+ Number ( projectId ) ,
198+ addAnalyticsConfigHandler . isPending ,
199+ (
200+ projectId : number ,
201+ keys : {
202+ serverAnalyticsKey : string ;
203+ clientAnalyticsKey : string ;
204+ } ,
205+ ) => {
206+ const { serverAnalyticsKey, clientAnalyticsKey } = keys ;
207+ updateAnalyticsConfigHandler . mutate ( {
208+ projectId,
209+ serverAnalyticsKey,
210+ clientAnalyticsKey,
211+ } ) ;
212+ setIsAddConfigDialogOpen ( false ) ;
176213 } ,
177- ) => {
178- const { serverAnalyticsKey, clientAnalyticsKey } = keys ;
179- updateAnalyticsConfigHandler . mutate ( {
180- projectId,
181- serverAnalyticsKey,
182- clientAnalyticsKey,
183- } ) ;
184- setIsAddConfigDialogOpen ( false ) ;
185- } ,
186- isReadOnly ,
187- ) }
188- isLoading = { isLoading }
189- filterParams = { {
190- placeholder : "Filter by environment..." ,
191- filterColumn : "environment" ,
192- } }
193- onAddNewRow = { ( ) => {
194- if ( analyticsConfigRowData . length === 0 ) {
195- setIsAddConfigDialogOpen ( true ) ;
196- } else {
197- toast . error ( "Error" , {
198- description :
199- "Project can have at most 1 analytics configuration per environment" ,
200- } ) ;
201- }
202- } }
203- onDeleteRow = { ( rows ) => {
204- setSelectedRows ( rows ) ;
205- setIsDeleteDialogOpen ( true ) ;
206- } }
207- />
214+ isReadOnly ,
215+ ) }
216+ isLoading = { isLoading }
217+ filterParams = { {
218+ placeholder : "Filter by environment..." ,
219+ filterColumn : "environment" ,
220+ } }
221+ onAddNewRow = { ( ) => {
222+ if ( analyticsConfigRowData . length === 0 ) {
223+ setIsAddConfigDialogOpen ( true ) ;
224+ } else {
225+ toast . error ( "Error" , {
226+ description :
227+ "Project can have at most 1 analytics configuration per environment" ,
228+ } ) ;
229+ }
230+ } }
231+ onDeleteRow = { ( ) => {
232+ setIsDeleteDialogOpen ( true ) ;
233+ } }
234+ />
235+ ) }
208236 </ div >
209237 ) ;
210238}
0 commit comments