sharing logic
This commit is contained in:
parent
66a76eb0f9
commit
5ba1c03030
@ -36,6 +36,9 @@ export default {
|
||||
const id = params.get("id") as string;
|
||||
const res = await db.query.sandbox.findFirst({
|
||||
where: (sandbox, { eq }) => eq(sandbox.id, id),
|
||||
with: {
|
||||
usersToSandboxes: true,
|
||||
},
|
||||
});
|
||||
return json(res ?? {});
|
||||
} else {
|
||||
@ -99,9 +102,18 @@ export default {
|
||||
|
||||
const user = await db.query.user.findFirst({
|
||||
where: (user, { eq }) => eq(user.email, email),
|
||||
with: {
|
||||
usersToSandboxes: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) return invalidRequest;
|
||||
if (!user) {
|
||||
return new Response("No user associated with email.", { status: 400 });
|
||||
}
|
||||
|
||||
if (user.usersToSandboxes.find((uts) => uts.sandboxId === sandboxId)) {
|
||||
return new Response("User already has access.", { status: 400 });
|
||||
}
|
||||
|
||||
await db.insert(usersToSandboxes).values({ userId: user.id, sandboxId }).get();
|
||||
|
||||
|
@ -5,6 +5,10 @@ export type User = {
|
||||
name: string
|
||||
email: string
|
||||
sandbox: Sandbox[]
|
||||
usersToSandboxes: {
|
||||
userId: string
|
||||
sandboxId: string
|
||||
}[]
|
||||
}
|
||||
|
||||
export type Sandbox = {
|
||||
@ -13,6 +17,10 @@ export type Sandbox = {
|
||||
type: "react" | "node"
|
||||
visibility: "public" | "private"
|
||||
userId: string
|
||||
usersToSandboxes: {
|
||||
userId: string
|
||||
sandboxId: string
|
||||
}[]
|
||||
}
|
||||
|
||||
export type TFolder = {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import Navbar from "@/components/editor/navbar"
|
||||
import { Sandbox, User } from "@/lib/types"
|
||||
import { Sandbox, User, UsersToSandboxes } from "@/lib/types"
|
||||
import { currentUser } from "@clerk/nextjs"
|
||||
import dynamic from "next/dynamic"
|
||||
import { redirect } from "next/navigation"
|
||||
@ -20,6 +20,20 @@ const getSandboxData = async (id: string) => {
|
||||
return sandboxData
|
||||
}
|
||||
|
||||
const getSharedUsers = async (usersToSandboxes: UsersToSandboxes[]) => {
|
||||
const shared = await Promise.all(
|
||||
usersToSandboxes.map(async (user) => {
|
||||
const userRes = await fetch(
|
||||
`http://localhost:8787/api/user?id=${user.userId}`
|
||||
)
|
||||
const userData: User = await userRes.json()
|
||||
return { id: userData.id, name: userData.name }
|
||||
})
|
||||
)
|
||||
|
||||
return shared
|
||||
}
|
||||
|
||||
export default async function CodePage({ params }: { params: { id: string } }) {
|
||||
const user = await currentUser()
|
||||
const sandboxId = params.id
|
||||
@ -30,12 +44,13 @@ export default async function CodePage({ params }: { params: { id: string } }) {
|
||||
|
||||
const userData = await getUserData(user.id)
|
||||
const sandboxData = await getSandboxData(sandboxId)
|
||||
const shared = await getSharedUsers(sandboxData.usersToSandboxes)
|
||||
|
||||
return (
|
||||
<div className="overflow-hidden overscroll-none w-screen flex flex-col h-screen bg-background">
|
||||
<Navbar userData={userData} sandboxData={sandboxData} />
|
||||
<Navbar userData={userData} sandboxData={sandboxData} shared={shared} />
|
||||
<div className="w-screen flex grow">
|
||||
<CodeEditor userId={user.id} sandboxId={sandboxId} />
|
||||
<CodeEditor userData={userData} sandboxId={sandboxId} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
@ -30,12 +30,13 @@ import { processFileType, validateName } from "@/lib/utils"
|
||||
import { toast } from "sonner"
|
||||
import EditorTerminal from "./terminal"
|
||||
import { Button } from "../ui/button"
|
||||
import { User } from "@/lib/types"
|
||||
|
||||
export default function CodeEditor({
|
||||
userId,
|
||||
userData,
|
||||
sandboxId,
|
||||
}: {
|
||||
userId: string
|
||||
userData: User
|
||||
sandboxId: string
|
||||
}) {
|
||||
const clerk = useClerk()
|
||||
@ -54,7 +55,7 @@ export default function CodeEditor({
|
||||
const [terminals, setTerminals] = useState<string[]>([])
|
||||
|
||||
const socket = io(
|
||||
`http://localhost:4000?userId=${userId}&sandboxId=${sandboxId}`
|
||||
`http://localhost:4000?userId=${userData.id}&sandboxId=${sandboxId}`
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -14,9 +14,14 @@ import ShareSandboxModal from "./share"
|
||||
export default function Navbar({
|
||||
userData,
|
||||
sandboxData,
|
||||
shared,
|
||||
}: {
|
||||
userData: User
|
||||
sandboxData: Sandbox
|
||||
shared: {
|
||||
id: string
|
||||
name: string
|
||||
}[]
|
||||
}) {
|
||||
const [isEditOpen, setIsEditOpen] = useState(false)
|
||||
const [isShareOpen, setIsShareOpen] = useState(false)
|
||||
@ -32,6 +37,7 @@ export default function Navbar({
|
||||
open={isShareOpen}
|
||||
setOpen={setIsShareOpen}
|
||||
data={sandboxData}
|
||||
shared={shared}
|
||||
/>
|
||||
<div className="h-14 px-2 w-full flex items-center justify-between border-b border-border">
|
||||
<div className="flex items-center space-x-4">
|
||||
|
@ -30,8 +30,8 @@ import {
|
||||
SelectValue,
|
||||
} from "@/components/ui/select"
|
||||
import { Loader2, UserPlus, X } from "lucide-react"
|
||||
import { useState, useTransition } from "react"
|
||||
import { Sandbox } from "@/lib/types"
|
||||
import { useEffect, useState, useTransition } from "react"
|
||||
import { Sandbox, User } from "@/lib/types"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import Avatar from "@/components/ui/avatar"
|
||||
import { shareSandbox } from "@/lib/actions"
|
||||
@ -45,10 +45,15 @@ export default function ShareSandboxModal({
|
||||
open,
|
||||
setOpen,
|
||||
data,
|
||||
shared,
|
||||
}: {
|
||||
open: boolean
|
||||
setOpen: (open: boolean) => void
|
||||
data: Sandbox
|
||||
shared: {
|
||||
id: string
|
||||
name: string
|
||||
}[]
|
||||
}) {
|
||||
const [loading, setLoading] = useState(false)
|
||||
|
||||
@ -60,17 +65,12 @@ export default function ShareSandboxModal({
|
||||
})
|
||||
|
||||
async function onSubmit(values: z.infer<typeof formSchema>) {
|
||||
// if (!user.isSignedIn) return
|
||||
// const sandboxData = { type: selected, userId: user.user.id, ...values }
|
||||
// setLoading(true)
|
||||
// const id = await createSandbox(sandboxData)
|
||||
|
||||
console.log(values)
|
||||
|
||||
setLoading(true)
|
||||
const res = await shareSandbox(data.id, values.email)
|
||||
if (!res) {
|
||||
toast.error("Failed to share.")
|
||||
if (!res.success) {
|
||||
toast.error(res.message)
|
||||
} else {
|
||||
toast.success("Shared successfully.")
|
||||
}
|
||||
|
||||
setLoading(false)
|
||||
@ -121,15 +121,17 @@ export default function ShareSandboxModal({
|
||||
<DialogTitle>Manage Access</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center justify-between">
|
||||
{shared.map((user) => (
|
||||
<div key={user.id} className="flex items-center justify-between">
|
||||
<div className="flex items-center">
|
||||
<Avatar name="Ishaan Dey" className="mr-2" />
|
||||
Ishaan Dey
|
||||
<Avatar name={user.name} className="mr-2" />
|
||||
{user.name}
|
||||
</div>
|
||||
<Button variant="ghost" size="smIcon">
|
||||
<X className="w-4 h-4" />
|
||||
</Button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</DialogContent>
|
||||
|
@ -44,7 +44,6 @@ export async function deleteSandbox(id: string) {
|
||||
}
|
||||
|
||||
export async function shareSandbox(sandboxId: string, email: string) {
|
||||
try {
|
||||
const res = await fetch("http://localhost:8787/api/sandbox/share", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
@ -52,10 +51,12 @@ export async function shareSandbox(sandboxId: string, email: string) {
|
||||
},
|
||||
body: JSON.stringify({ sandboxId, email }),
|
||||
})
|
||||
const text = await res.text()
|
||||
|
||||
if (res.status !== 200) {
|
||||
return { success: false, message: text }
|
||||
}
|
||||
|
||||
revalidatePath(`/code/${sandboxId}`)
|
||||
return true
|
||||
} catch (err) {
|
||||
return false
|
||||
}
|
||||
return { success: true, message: "Shared successfully." }
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ export type User = {
|
||||
name: string
|
||||
email: string
|
||||
sandbox: Sandbox[]
|
||||
usersToSandboxes: UsersToSandboxes[]
|
||||
}
|
||||
|
||||
export type Sandbox = {
|
||||
@ -13,6 +14,12 @@ export type Sandbox = {
|
||||
type: "react" | "node"
|
||||
visibility: "public" | "private"
|
||||
userId: string
|
||||
usersToSandboxes: UsersToSandboxes[]
|
||||
}
|
||||
|
||||
export type UsersToSandboxes = {
|
||||
userId: string
|
||||
sandboxId: string
|
||||
}
|
||||
|
||||
export type R2Files = {
|
||||
|
Loading…
x
Reference in New Issue
Block a user