Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion components/sql-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Editor } from "@monaco-editor/react";
import { Button } from "@/components/ui/button";
import { ResultsTable } from "@/components/results-table";
import { Label } from "@/components/ui/label";
import { useRunQuery } from "@/hooks/use-supabase-manager";
import { useRunQuery } from "@/hooks/use-run-query";
import {
ArrowUp,
Loader2,
Expand Down
7 changes: 2 additions & 5 deletions components/supabase-manager/auth.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
"use client";

import { DynamicForm } from "@/components/dynamic-form";
import {
useGetAuthConfig,
useUpdateAuthConfig,
} from "@/hooks/use-supabase-manager";
import { useGetAuthConfig, useUpdateAuthConfig } from "@/hooks/use-auth";
import {
authEmailProviderSchema,
authFieldLabels,
authGeneralSettingsSchema,
type AuthGeneralSettingsSchema,
authGoogleProviderSchema,
authPhoneProviderSchema,
} from "@/lib/schemas";
} from "@/lib/schemas/auth";
import { AlertTriangle, ChevronRight, Mail, Phone, User } from "lucide-react";
import { useCallback, useMemo } from "react";
import { z } from "zod";
Expand Down
3 changes: 2 additions & 1 deletion components/supabase-manager/database.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

import { useState, useMemo, useCallback } from "react";
import { z, type ZodTypeAny } from "zod";
import { useListTables, useRunQuery } from "@/hooks/use-supabase-manager";
import { useListTables } from "@/hooks/use-tables";
import { useRunQuery } from "@/hooks/use-run-query";
import { SqlEditor } from "@/components/sql-editor";
import { DynamicForm } from "@/components/dynamic-form";
import { toast } from "sonner";
Expand Down
79 changes: 41 additions & 38 deletions components/supabase-manager/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import { useState, ReactNode } from "react";
import { useState, ReactNode, useMemo } from "react";
import { Button } from "@/components/ui/button";
import {
Dialog,
Expand Down Expand Up @@ -68,43 +68,46 @@ function DialogView({
const currentView = stack[stack.length - 1];
const activeManager = stack.length > 0 ? stack[0].title : null;

const navigationItems = [
{
title: "Database",
icon: Database,
component: <DatabaseManager projectRef={projectRef} />,
},
{
title: "Storage",
icon: HardDrive,
component: <StorageManager projectRef={projectRef} />,
},
{
title: "Auth",
icon: Shield,
component: <AuthManager projectRef={projectRef} />,
},
{
title: "Users",
icon: Users,
component: <UsersManager projectRef={projectRef} />,
},
{
title: "Secrets",
icon: KeyRound,
component: <SecretsManager projectRef={projectRef} />,
},
{
title: "Logs",
icon: ScrollText,
component: <LogsManager projectRef={projectRef} />,
},
{
title: "Suggestions",
icon: Lightbulb,
component: <SuggestionsManager projectRef={projectRef} />,
},
];
const navigationItems = useMemo(
() => [
{
title: "Database",
icon: Database,
component: <DatabaseManager projectRef={projectRef} />,
},
{
title: "Storage",
icon: HardDrive,
component: <StorageManager projectRef={projectRef} />,
},
{
title: "Auth",
icon: Shield,
component: <AuthManager projectRef={projectRef} />,
},
{
title: "Users",
icon: Users,
component: <UsersManager projectRef={projectRef} />,
},
{
title: "Secrets",
icon: KeyRound,
component: <SecretsManager projectRef={projectRef} />,
},
{
title: "Logs",
icon: ScrollText,
component: <LogsManager projectRef={projectRef} />,
},
{
title: "Suggestions",
icon: Lightbulb,
component: <SuggestionsManager projectRef={projectRef} />,
},
],
[projectRef]
);

if (isMobile) {
return (
Expand Down
2 changes: 1 addition & 1 deletion components/supabase-manager/logs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import {
TableHeader,
TableRow,
} from "@/components/ui/table";
import { useGetLogs } from "@/hooks/use-supabase-manager";
import { useGetLogs } from "@/hooks/use-logs";
import { LogsTableName, genDefaultQuery } from "@/lib/logs";
import { cn } from "@/lib/utils";
import { Check, ChevronsUpDown, Logs, Terminal } from "lucide-react";
Expand Down
4 changes: 2 additions & 2 deletions components/supabase-manager/secrets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import {
useCreateSecrets,
useDeleteSecrets,
useGetSecrets,
} from "@/hooks/use-supabase-manager";
import { secretsSchema } from "@/lib/schemas";
} from "@/hooks/use-secrets";
import { secretsSchema } from "@/lib/schemas/secrets";
import { zodResolver } from "@hookform/resolvers/zod";
import { AlertTriangle, Minus, PlusIcon, Key } from "lucide-react";
import { useFieldArray, useForm } from "react-hook-form";
Expand Down
4 changes: 1 addition & 3 deletions components/supabase-manager/storage.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
"use client";

import { useCallback } from "react";
import { useSheetNavigation } from "../../contexts/SheetNavigationContext";
import { useGetBuckets, useListObjects } from "@/hooks/use-supabase-manager";
import { useGetBuckets } from "@/hooks/use-storage";
import { Skeleton } from "@/components/ui/skeleton";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
Expand Down
9 changes: 2 additions & 7 deletions components/supabase-manager/suggestions.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
"use client";

import { useGetSuggestions } from "@/hooks/use-supabase-manager";
import { useGetSuggestions } from "@/hooks/use-suggestions";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { Terminal } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { useMemo } from "react";
import { Button } from "@/components/ui/button";
import {
Tooltip,
TooltipTrigger,
TooltipContent,
} from "@/components/ui/tooltip";

import ReactMarkdown from "react-markdown";
import { Skeleton } from "@/components/ui/skeleton";

Expand Down
2 changes: 1 addition & 1 deletion components/supabase-manager/users-growth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
ChartTooltip,
ChartTooltipContent,
} from "@/components/ui/chart";
import { useGetUserCountsByDay } from "@/hooks/use-supabase-manager";
import { useGetUserCountsByDay } from "@/hooks/use-user-counts";
import { Skeleton } from "@/components/ui/skeleton";
import { AlertTriangle } from "lucide-react";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
Expand Down
71 changes: 71 additions & 0 deletions hooks/use-auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
"use client";

import { client } from "@/lib/management-api";
import type { components } from "@/lib/management-api-schema";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { type AxiosError } from "axios";
import { toast } from "sonner";

const getAuthConfig = async (projectRef: string) => {
const { data, error } = await client.GET("/v1/projects/{ref}/config/auth", {
params: {
path: { ref: projectRef },
},
});
if (error) {
throw error;
}

return data;
};

export const useGetAuthConfig = (projectRef: string) => {
return useQuery({
queryKey: ["auth-config", projectRef],
queryFn: () => getAuthConfig(projectRef),
enabled: !!projectRef,
retry: false,
});
};

// UPDATE Auth Config
const updateAuthConfig = async ({
projectRef,
payload,
}: {
projectRef: string;
payload: components["schemas"]["UpdateAuthConfigBody"];
}) => {
const { data, error } = await client.PATCH("/v1/projects/{ref}/config/auth", {
params: {
path: {
ref: projectRef,
},
},
body: payload,
});
if (error) {
throw error;
}

return data;
};

export const useUpdateAuthConfig = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: updateAuthConfig,
onSuccess: (data, variables) => {
toast.success(`Auth config updated.`);
queryClient.invalidateQueries({
queryKey: ["auth-config", variables.projectRef],
});
},
onError: (error: AxiosError<{ message: string }>) => {
toast.error(
error.response?.data?.message ||
"There was a problem with your request."
);
},
});
};
67 changes: 67 additions & 0 deletions hooks/use-logs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"use client";

import { client } from "@/lib/management-api";
import { useQuery } from "@tanstack/react-query";

// GET Logs
const getLogs = async ({
projectRef,
iso_timestamp_start,
iso_timestamp_end,
sql,
}: {
projectRef: string;
iso_timestamp_start?: string;
iso_timestamp_end?: string;
sql?: string;
}) => {
const { data, error } = await client.GET(
"/v1/projects/{ref}/analytics/endpoints/logs.all",
{
params: {
path: {
ref: projectRef,
},
query: {
iso_timestamp_start,
iso_timestamp_end,
sql,
},
},
}
);
if (error) {
throw error;
}

return data;
};

export const useGetLogs = (
projectRef: string,
params: {
iso_timestamp_start?: string;
iso_timestamp_end?: string;
sql?: string;
} = {}
) => {
const queryKey = ["logs", projectRef, params.sql];

return useQuery({
queryKey: queryKey,
queryFn: () => {
const now = new Date();
const oneHourAgo = new Date(now.getTime() - 60 * 60 * 1000);

const queryParams = {
sql: params.sql,
iso_timestamp_start:
params.iso_timestamp_start ?? oneHourAgo.toISOString(),
iso_timestamp_end: params.iso_timestamp_end ?? now.toISOString(),
};
return getLogs({ projectRef, ...queryParams });
},
enabled: !!projectRef,
retry: false,
});
};
51 changes: 51 additions & 0 deletions hooks/use-run-query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
"use client";

import { client } from "@/lib/management-api";
import type { components } from "@/lib/management-api-schema";
import { listTablesSql } from "@/lib/pg-meta";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { type AxiosError } from "axios";
import { toast } from "sonner";

// RUN SQL Query
export const runQuery = async ({
projectRef,
query,
readOnly,
}: {
projectRef: string;
query: string;
readOnly?: boolean;
}) => {
const { data, error } = await client.POST(
"/v1/projects/{ref}/database/query",
{
params: {
path: {
ref: projectRef,
},
},
body: {
query,
read_only: readOnly,
},
}
);

if (error) {
throw error;
}

return data as any;
};

export const useRunQuery = () => {
return useMutation({
mutationFn: runQuery,
onError: (error: AxiosError<{ message: string }>) => {
toast.error(
error.response?.data?.message || "There was a problem with your query."
);
},
});
};
Loading