Skip to content

Commit

Permalink
added saved clips page
Browse files Browse the repository at this point in the history
  • Loading branch information
azizbecha committed Nov 5, 2024
1 parent b1e4a8c commit 634a495
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 13 deletions.
98 changes: 98 additions & 0 deletions app/saved/SavedClips.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
"use client";

import { useEffect, useState } from "react";

import { createClient } from "@/utils/supabase/client";

import { Button } from "@/components/ui/Button";
import ClipCard from "@/components/ClipCard";

import { FaFilter } from "react-icons/fa6";

import { Clip, UserProfile } from "@/interfaces";

interface Props {
id: string;
}

interface SavedClip {
clips: Clip;
profiles: UserProfile;
id: string;
saved_at: string;
saved_by: string;
clipId: string;
}

const supabase = createClient();

export const SavedClips: React.FC<Props> = ({ id }) => {
const [clips, setClips] = useState<SavedClip[]>([]);
const [loading, setLoading] = useState(true);

useEffect(() => {
const fetchData = async () => {
setLoading(true);

let queryBuilder = supabase
.from("savedClips")
.select(`
*,
clips (*),
profiles (full_name, username, avatar, verified)
`)
.eq("saved_by", id)
.order("saved_at", { ascending: false });

const { data, error } = await queryBuilder;

if (error) {
console.error("Error fetching saved clips:", error);
} else {
setClips(data as SavedClip[]);
}
setLoading(false);
};

fetchData();
}, [id]);

return (
<>
<div className="flex justify-between items-center mb-4">
<h3 className="text-white">Saved Clips</h3>
<Button size="small" color="primary" icon={<FaFilter />}>
Filter
</Button>
</div>

{/* Loader */}
{loading && (
<div className="flex justify-center items-center p-4">
<p>Loading...</p>
</div>
)}

{/* Clips List */}
{!loading && clips.length === 0 ? (
<div className="flex justify-center items-center flex-col h-full p-4">
<p className="text-xl">No results found</p>
<p className="text-base font-normal">Try searching with different keywords</p>
</div>
) : (
<div className="h-full overflow-y-auto w-full space-y-4 scrollbar-hide">
{clips.map((clip, key) => (
<ClipCard
key={key}
isActive={true}
clipData={{
...clip.clips, // Spread all properties from clip.clips
profiles: clip.profiles, // Embed profiles directly
}}
/>
))}
</div>
)}
</>
);
};
49 changes: 49 additions & 0 deletions app/saved/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Metadata, NextPage } from "next";

import { createClient } from "@/utils/supabase/server";

import WithAuth from "@/components/Auth/WithAuth";

import Navbar from "@/components/ui/Navbar";

import { GridProvider } from "@/components/ui/Grid/GridProvider";
import { LeftColumn } from "@/components/ui/Grid/LeftColumn";
import { MiddleColumn } from "@/components/ui/Grid/MiddleColumn";
import { RightColumn } from "@/components/ui/Grid/RightColumn";

import { UsersList } from "@/components/UsersList";
import { ProfileCard } from "@/components/ProfileCard";
import { SavedClips } from "./SavedClips";

import { Loader } from "@/components/ui/Loader";

export const metadata: Metadata = {
title: "Saved Clips • VoidCast",
}

const supabase = createClient();

const Saved: NextPage = async () => {

const { data: { user } } = await supabase.auth.getUser();

return (
<WithAuth>
<Navbar user={user} />
<GridProvider>
<LeftColumn>
<h3 className="text-white mb-4">People</h3>
<UsersList />
</LeftColumn>
<MiddleColumn>
{user ? <SavedClips id={user?.id} /> : <Loader />}
</MiddleColumn>
<RightColumn>
<ProfileCard user={user} />
</RightColumn>
</GridProvider>
</WithAuth>
)
}

export default Saved;
19 changes: 6 additions & 13 deletions components/ui/BaseDropdownSm.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import React from "react";
import { VscTriangleDown } from "react-icons/vsc";

type BaseDropdownSmItemProps = React.DetailedHTMLProps<
React.HTMLAttributes<HTMLOptionElement>,
HTMLOptionElement
> & {
type BaseDropdownSmItemProps = React.OptionHTMLAttributes<HTMLOptionElement> & {
children: React.ReactNode;
};

export const BaseDropdownSmItem: React.FC<BaseDropdownSmItemProps> = ({
children,
className,
className = "",
...props
}) => (
<option
Expand All @@ -21,26 +18,22 @@ export const BaseDropdownSmItem: React.FC<BaseDropdownSmItemProps> = ({
</option>
);

type BaseDropdownSmProps = React.DetailedHTMLProps<
React.HTMLAttributes<HTMLSelectElement>,
HTMLSelectElement
> & {
children: React.ReactNode[];
type BaseDropdownSmProps = React.SelectHTMLAttributes<HTMLSelectElement> & {
children: React.ReactNode;
};

export const BaseDropdownSm: React.FC<BaseDropdownSmProps> = ({
children,
className,
className = "",
...props
}) => (
<div className="relative rounded-8 w-full">
<div className="relative w-full">
<select
className={`w-full py-2 px-4 font-medium text-primary-100 placeholder-primary-300 focus:outline-none bg-primary-700 text-sm rounded-8 appearance-none pr-10 ${className}`}
{...props}
>
{children}
</select>

<div className="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
<VscTriangleDown size={15} className="text-primary-100" />
</div>
Expand Down
2 changes: 2 additions & 0 deletions components/ui/Navbar/UserItems.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { createClient } from "@/utils/supabase/client";
import { Menu, MenuButton, MenuItem, MenuItems } from "@headlessui/react";

import { FaBug, FaCog, FaSignOutAlt, FaUser } from "react-icons/fa";
import { FaBookmark } from "react-icons/fa6";

interface Props {
user: User | null;
Expand All @@ -20,6 +21,7 @@ export default function UserMenu({ user }: Props) {

const menuItems = [
{ label: "Profile", href: "/profile", icon: FaUser },
{ label: "Saved clips", href: "/saved", icon: FaBookmark },
{ label: "Settings", href: "/settings", icon: FaCog },
{ label: "Report a bug", href: "https://github.com/issues", icon: FaBug, blank: true },
];
Expand Down

0 comments on commit 634a495

Please sign in to comment.