Skip to content

Commit

Permalink
refactor(front): sqlite connection page
Browse files Browse the repository at this point in the history
  • Loading branch information
kareemmahlees committed Dec 10, 2023
1 parent 71b2704 commit 30698e5
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 123 deletions.
9 changes: 9 additions & 0 deletions public/bg-2.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
125 changes: 70 additions & 55 deletions src/app/connect/_components/sqlite-connection.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,28 @@
import { Button } from "@/components/ui/button"
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage
} from "@/components/ui/form"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { cn } from "@/lib/utils"
import { zodResolver } from "@hookform/resolvers/zod"
import { open } from "@tauri-apps/api/dialog"
import { useRouter } from "next/navigation"
import { useState } from "react"
import { useState, type FC } from "react"
import { useForm } from "react-hook-form"
import { z } from "zod"
import { connectSQLite, testSQLiteConnection } from "../actions"

const formSchema = z.object({
connName: z.string().min(1, { message: "Connection name is required" })
})

const SqliteConnectionDetails = () => {
const router = useRouter()
const [selectedPath, setSelectedPath] = useState("")
const {
handleSubmit,
register,
formState: { errors }
} = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema)
})

const onSubmit = (values: z.infer<typeof formSchema>) => {
connectSQLite(values.connName, selectedPath)
router.push("/connections")
}
const SqliteConnection = () => {
const [selectedPath, setSelectedPath] = useState<string | null>(null)

return (
<>
<Button
className="bg-blue-500 hover:bg-blue-700"
variant={"secondary"}
onClick={async () => {
const selected = await open({
multiple: false,
Expand All @@ -44,43 +33,69 @@ const SqliteConnectionDetails = () => {
}
]
})
setSelectedPath((selected as string) ?? "")
setSelectedPath((selected as string) ?? null)
}}
>
Select DB file
</Button>
{selectedPath !== "" && (
<form onSubmit={handleSubmit(onSubmit)} className="w-full space-y-10">
<div className="space-y-2">
<Label htmlFor="connName">Connection Name</Label>
<Input
className={cn("placeholder:text-muted-foreground text-black ", {
"focus-visible:ring-red-500": errors.connName
})}
{...register("connName")}
placeholder="e.g awesome project dev"
/>
{errors.connName && (
<p className="text-sm text-red-500">{errors.connName.message}</p>
)}
</div>
<pre>{selectedPath}</pre>
<div className="col-span-full flex justify-center items-center gap-x-4">
<Button variant={"secondary"} className="w-[100px]" type="submit">
Connect
</Button>
<Button
type="button"
className="bg-green-500 hover:bg-green-700 w-[100px]"
onClick={() => testSQLiteConnection(selectedPath)}
>
Test
</Button>
</div>
</form>
)}
{selectedPath && <ConnectionForm selectedPath={selectedPath} />}
</>
)
}

export default SqliteConnectionDetails
export default SqliteConnection

interface ConnectionFormProps {
selectedPath: string
}

const formSchema = z.object({
connName: z.string().min(1, { message: "Connection name is required" })
})

const ConnectionForm: FC<ConnectionFormProps> = ({ selectedPath }) => {
const router = useRouter()
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema)
})
const onSubmit = (values: z.infer<typeof formSchema>) => {
connectSQLite(values.connName, selectedPath as string)
router.push("/connections")
}
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
<FormField
control={form.control}
name="connName"
render={({ field }) => (
<FormItem>
<FormLabel>Connection Name</FormLabel>
<FormControl>
<Input
placeholder="e.g awesome project dev"
className="placeholder:text-muted-foreground placeholder:opacity-40 "
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<pre className="text-sm text-muted-foreground">{selectedPath}</pre>
<div className="col-span-full flex justify-center items-center gap-x-4">
<Button variant={"secondary"} className="w-[100px]" type="submit">
Connect
</Button>
<Button
type="button"
className="bg-green-500 hover:bg-green-700 w-[100px]"
onClick={() => testSQLiteConnection(selectedPath as string)}
>
Test
</Button>
</div>
</form>
</Form>
)
}
121 changes: 59 additions & 62 deletions src/app/connect/page.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
"use client"
import { Button } from "@/components/ui/button"
import {
Command,
CommandEmpty,
CommandGroup,
CommandItem
} from "@/components/ui/command"
import { Command, CommandGroup, CommandItem } from "@/components/ui/command"
import {
Popover,
PopoverContent,
PopoverTrigger
} from "@/components/ui/popover"
import { cn } from "@/lib/utils"
import { Check, ChevronsUpDown } from "lucide-react"
import Image from "next/image"
import { useState } from "react"
import ConnectionRadio from "./_components/conn-radio"
import SqliteConnectionDetails from "./_components/sqlite-connection"
import SqliteConnection from "./_components/sqlite-connection"

const frameworks = [
const drivers = [
{
value: "mysql",
label: "MySQL"
Expand All @@ -32,63 +28,64 @@ const frameworks = [
}
]

interface ConnectionParamsProps {
type: "mysql" | "psql"
}

const ConnectionPage = () => {
const [open, setOpen] = useState(false)
const [driver, setDriver] = useState("")
const [selectedDriver, setSelectedDriver] = useState<string | null>(null)
return (
<main className="h-full bg-primary text-white flex items-center justify-center bg-[url(/texture.svg)] bg-contain ">
<section className="flex flex-col items-center gap-y-10">
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<Button
variant={"secondary"}
role="combobox"
aria-expanded={open}
className="w-[200px] justify-between"
>
{driver
? frameworks.find((framework) => framework.value === driver)
?.label
: "Select a Database..."}
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
</Button>
</PopoverTrigger>
<PopoverContent className="w-[200px] p-0">
<Command>
{/* <CommandInput placeholder="Search database..." /> */}
<CommandEmpty>No framework found.</CommandEmpty>
<CommandGroup>
{frameworks.map((framework) => (
<CommandItem
key={framework.value}
value={framework.value}
onSelect={(currentValue) => {
setDriver(currentValue === driver ? "" : currentValue)
setOpen(false)
}}
>
<Check
className={cn(
"mr-2 h-4 w-4",
driver === framework.value ? "opacity-100" : "opacity-0"
)}
/>
{framework.label}
</CommandItem>
))}
</CommandGroup>
</Command>
</PopoverContent>
</Popover>
{driver === "sqlite" && <SqliteConnectionDetails />}
{(driver === "psql" || driver === "mysql") && (
<ConnectionRadio driver={driver} />
)}
</section>
<main className="relative h-full flex flex-col items-center gap-y-10 justify-center">
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<Button
role="combobox"
aria-expanded={open}
className="w-[230px] justify-between"
>
{selectedDriver
? drivers.find((driver) => driver.value === selectedDriver)?.label
: "Select a Database Driver"}
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
</Button>
</PopoverTrigger>
<PopoverContent className="w-[200px] p-0">
<Command>
<CommandGroup>
{drivers.map((driver) => (
<CommandItem
key={driver.value}
value={driver.value}
onSelect={(currentValue) => {
setSelectedDriver(
currentValue === selectedDriver ? null : currentValue
)
setOpen(false)
}}
>
<Check
className={cn(
"mr-2 h-4 w-4",
driver.value === selectedDriver
? "opacity-100"
: "opacity-0"
)}
/>
{driver.label}
</CommandItem>
))}
</CommandGroup>
</Command>
</PopoverContent>
</Popover>
{selectedDriver === "sqlite" && <SqliteConnection />}
{(selectedDriver === "psql" || selectedDriver === "mysql") && (
<ConnectionRadio driver={selectedDriver} />
)}
<Image
src={"/bg-2.svg"}
fill
alt="bg"
aria-hidden
className="object-cover -z-10 opacity-20"
/>
</main>
)
}
Expand Down
7 changes: 2 additions & 5 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,8 @@ html,
}
}

/* @layer base {
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
} */
}
7 changes: 6 additions & 1 deletion src/lib/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ const queryClient = new QueryClient()
const Providers = ({ children }: PropsWithChildren) => {
return (
<QueryClientProvider client={queryClient}>
<ThemeProvider attribute="class" defaultTheme="dark" enableSystem>
<ThemeProvider
attribute="class"
defaultTheme="dark"
enableSystem
disableTransitionOnChange
>
{children}
<Toaster />
</ThemeProvider>
Expand Down

0 comments on commit 30698e5

Please sign in to comment.