diff --git a/actions/user.ts b/actions/user.ts new file mode 100644 index 0000000..3f01c50 --- /dev/null +++ b/actions/user.ts @@ -0,0 +1,24 @@ +"use server"; + +import { getSelf } from "@/lib/auth-service"; +import { db } from "@/lib/db"; +import { User } from "@prisma/client"; +import { revalidatePath } from "next/cache"; + +export const updateUser = async (values: Partial) => { + const self = await getSelf(); + + const validData = { + bio: values.bio, + }; + + const user = await db.user.update({ + where: { id: self.id }, + data: { ...validData }, + }); + + revalidatePath(`/${self.username}`); + revalidatePath(`/u/${self.username}`); + + return user; +}; diff --git a/components/stream-player/about-card.tsx b/components/stream-player/about-card.tsx new file mode 100644 index 0000000..6e66094 --- /dev/null +++ b/components/stream-player/about-card.tsx @@ -0,0 +1,47 @@ +"use client"; + +import React from "react"; +import { VerifiedMark } from "../verified-mark"; +import { BioModal } from "./bio-modal"; + +interface AboutCardProps { + hostName: string; + hostIdentity: string; + viewerIdentity: string; + bio: string | null; + followedByCount: number; +} + +export const AboutCard = ({ + hostName, + hostIdentity, + viewerIdentity, + bio, + followedByCount, +}: AboutCardProps) => { + const hostAsViewer = `host-${hostIdentity}`; + const isHost = viewerIdentity === hostAsViewer; + + const followedByLabel = followedByCount === 1 ? "Follower" : "Followers"; + + return ( +
+
+
+
+ About {hostName} + +
+ {isHost && } +
+
+ {followedByCount}{" "} + {followedByLabel} +
+

+ {bio || "This user prefers to keep an air of mystery about them."} +

+
+
+ ); +}; diff --git a/components/stream-player/bio-modal.tsx b/components/stream-player/bio-modal.tsx new file mode 100644 index 0000000..43dfe24 --- /dev/null +++ b/components/stream-player/bio-modal.tsx @@ -0,0 +1,73 @@ +"use client"; + +import { updateUser } from "@/actions/user"; +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogClose, + DialogContent, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog"; +import React, { ElementRef, useRef, useState, useTransition } from "react"; +import { toast } from "sonner"; +import { Textarea } from "../ui/textarea"; + +interface BioModalProps { + initialValue: string; +} + +export const BioModal = ({ initialValue }: BioModalProps) => { + const closeRef = useRef>(null); + + const [isPending, startTransition] = useTransition(); + const [value, setValue] = useState(initialValue || ""); + + const onSubmit = (e: React.FormEvent) => { + e.preventDefault(); + + startTransition(() => { + updateUser({ bio: value }) + .then(() => { + toast.success("Your Bio has successfully updated!"); + closeRef.current?.click(); + }) + .catch(() => toast.error("Something went wrong")); + }); + }; + + return ( + + + + + + + Edit user bio + +
+