Skip to content

Commit

Permalink
🥇🍥 ↝ Temporary UI changes to social component, dynamic profile state …
Browse files Browse the repository at this point in the history
…management added

There's an issue with loading the Avatars in the PostCard component -> we need to match them to the post id & the user who created the post [id] however it seems there's an endless loop that's been established where the client is constantly trying to communicate with the server (Supabase). The key to fixing this issue is getting the Avatar data to be passed in the same way as it is in the PostFormCard component (which is not experiencing any problems)

Signal-K/sytizen#16
  • Loading branch information
Gizmotronn committed Feb 7, 2023
1 parent b535706 commit 22cb700
Show file tree
Hide file tree
Showing 9 changed files with 190 additions and 32 deletions.
Binary file modified .DS_Store
Binary file not shown.
59 changes: 49 additions & 10 deletions components/PostCard.js → components/PostCard.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,76 @@
import Avatar from "./Avatar";
import Card from "./Card";
import ClickOutHandler from 'react-clickout-handler'
import {useState} from "react";
import React, { useEffect,useState } from "react";
import Link from "next/link";
import AccountAvatar from "./AccountAvatar";
import { Database } from "../utils/database.types";
import { useSession, useSupabaseClient } from "@supabase/auth-helpers-react";
import ReactTimeAgo from "react-time-ago";

type Profiles = Database['public']['Tables']['profiles']['Row'];

export default function PostCard ( { content, created_at, profiles:profile } ) {
const [loading, setLoading] = useState(false);
const [avatar_url, setAvatarUrl] = useState<Profiles['avatar_url']>();
const [profiles, setProfiles] = useState();
const supabase = useSupabaseClient();
const session = useSession();

export default function PostCard() {
const [dropdownOpen,setDropdownOpen] = useState(false);

function openDropdown(e) {
e.stopPropagation();
setDropdownOpen(true);
}

function handleClickOutsideDropdown(e) {
e.stopPropagation();
setDropdownOpen(false);
}

/*useEffect(() => {
supabase.from('profiles') // Fetch profile from user id matching session
.select()
.eq('id', session.user.id)
.then(result => {
if (result.data.length) {
setProfiles(result.data[0]);
}
});
}, []); */

/*useEffect(() => {
supabase.from('profiles')
.select(`avatar_url`)
.eq('id', session.user.id)
.then(result => {
setAvatarUrl(result.data[0].avatar_url) //console.log(result.data[0].avatar_url)
})
}, []);*/

return (
<Card>
<Card noPadding={false}>
<div className="flex gap-3">
<div>
<Link href={'/posts/profile'}>
<span className="cursor-pointer">
<Avatar />
<AccountAvatar uid={session.user!.id}
url={profile.avatar_url}
size={50} />
</span>
</Link>
</div>
<div className="grow">
<p>
<Link href={'/posts/profile'}>
<span className="mr-1 font-semibold cursor-pointer hover:underline">
John Doe
{profile?.username}
</span>
</Link>
shared a <a className="text-socialBlue">album</a>
shared a <a className="text-socialBlue">post</a>
</p>
<p className="text-gray-500 text-sm">2 hours ago</p>
<p className="text-gray-500 text-sm"><ReactTimeAgo date={created_at} /></p>
</div>
<div className="relative">
<button className="text-gray-400" onClick={openDropdown}>
Expand Down Expand Up @@ -81,7 +118,7 @@ export default function PostCard() {
</div>
</div>
<div>
<p className="my-3 text-sm">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores, cum cupiditate deleniti ducimus et eveniet ex excepturi fuga magnam, maiores nam pariatur quibusdam, recusandae reprehenderit sapiente sed sint veniam? Beatae.</p>
<p className="my-3 text-sm">{content}</p>
<div className="rounded-md overflow-hidden">
<img src="https://images.unsplash.com/photo-1530841377377-3ff06c0ca713?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80" alt=""/>
</div>
Expand All @@ -107,8 +144,10 @@ export default function PostCard() {
</button>
</div>
<div className="flex mt-4 gap-3">
<div>
<Avatar />
<div className="mt-1">
<AccountAvatar uid={session.user!.id}
url={profile.avatar_url}
size={45} />
</div>
<div className="border grow rounded-full relative">
<textarea className="block w-full p-3 px-4 overflow-hidden h-12 rounded-full" placeholder="Leave a comment"/>
Expand Down
40 changes: 26 additions & 14 deletions components/PostFormCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,45 @@ import { Database } from "../utils/database.types";

type Profiles = Database['public']['Tables']['profiles']['Row'];

export default function PostFormCard() {
export default function PostFormCard ( { onPost } ) {
const [profile, setProfile] = useState(null);
const supabase = useSupabaseClient();
const [content, setContent] = useState('');
const session = useSession();

const [loading, setLoading] = useState(false);
const [avatar_url, setAvatarUrl] = useState<Profiles['avatar_url']>(null);
const [avatar_url, setAvatarUrl] = useState<Profiles['avatar_url']>();

useEffect(() => {
supabase.from('profiles') // Fetch profile from user id matching session
.select()
.eq('id', session.user.id)
.then(result => {
if (result.data.length) {
setProfile(result.data[0]);
}
setProfile(result.data[0]);
});
}, []);

function createPost () {
supabase.from('posts').insert({
author: session.user.id, // This is validated via RLS so users can't pretend to be other user
content, // : content,
}).then(response => {
if (!response.error) {
alert(`Post ${content} created`);
setContent('');
if ( onPost ) {
onPost();
}
}
});
}

useEffect(() => {
supabase.from('profiles')
.select(`avatar_url`)
.eq('id', session.user.id)
.then(result => {
if (result.data.length) {
console.log(result.data[0].avatar_url)
setAvatarUrl(result.data[0].avatar_url)
}
setAvatarUrl(result.data[0].avatar_url) //console.log(result.data[0].avatar_url)
})
}, []);

Expand All @@ -50,8 +62,8 @@ export default function PostFormCard() {
}

if (data) {
console.log('Received')
setAvatarUrl(data.avatar_url);
console.log(avatar_url)
}
} catch (error) {
console.log(error);
Expand All @@ -66,9 +78,9 @@ export default function PostFormCard() {
<div>
<AccountAvatar uid={session.user!.id}
url={avatar_url}
size={75}/>
</div>
<textarea className="grow p-3 h-14" placeholder={'Whats on your mind, User?'} />
size={60}/>
</div> { profile && (
<textarea value={content} onChange={e => setContent(e.target.value)} className="grow p-3 h-14" placeholder={`What's on your mind, ${profile?.username}?`} /> )}
</div>
<div className="flex gap-5 items-center mt-2">
<div>
Expand Down Expand Up @@ -97,7 +109,7 @@ export default function PostFormCard() {
</button>
</div>
<div className="grow text-right">
<button className="bg-socialBlue text-white px-6 py-1 rounded-md">Share</button>
<button onClick={createPost} className="bg-socialBlue text-white px-6 py-1 rounded-md">Share</button>
</div>
</div>
</Card>
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@
"autoprefixer": "^10.4.13",
"eslint": "8.27.0",
"eslint-config-next": "13.0.2",
"javascript-time-ago": "^2.5.9",
"next": "13.0.2",
"postcss": "^8.4.18",
"react": "18.2.0",
"react-clickout-handler": "^1.2.1",
"react-dom": "18.2.0",
"react-time-ago": "^7.2.1",
"tailwindcss": "^3.2.2"
},
"devDependencies": {
Expand Down
4 changes: 4 additions & 0 deletions pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import { createBrowserSupabaseClient } from '@supabase/auth-helpers-nextjs';
import { SessionContextProvider } from '@supabase/auth-helpers-react';
import { useRouter } from 'next/router';

import TimeAgo from 'javascript-time-ago';
import en from 'javascript-time-ago/locale/en.json';
TimeAgo.addDefaultLocale(en);

function MyApp({ Component, pageProps }) {
const router = useRouter();
const [supabaseClient] = useState(() => createBrowserSupabaseClient());
Expand Down
28 changes: 26 additions & 2 deletions pages/posts/Profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ import Link from "next/link";
import PostCard from "../../components/PostCard";
import {useRouter} from "next/router";
import FriendInfo from "../../components/FriendInfo";
import React from "react";
import React, { useEffect, useState} from "react";
import { Database } from "../../utils/database.types";
import { useSupabaseClient, useSession } from "@supabase/auth-helpers-react";
import AccountAvatar from "../../components/AccountAvatar";

type Profiles = Database['public']['Tables']['profiles']['Row'];

export default function ProfilePage() {
const router = useRouter();
Expand All @@ -16,6 +21,23 @@ export default function ProfilePage() {
const isPhotos = pathname.includes('photos');
const tabClasses = 'flex gap-1 px-4 py-1 items-center border-b-4 border-b-white';
const activeTabClasses = 'flex gap-1 px-4 py-1 items-center border-socialBlue border-b-4 text-socialBlue font-bold';

const [avatar_url, setAvatarUrl] = useState<Profiles['avatar_url']>(null);
const [profiles, setProfiles] = useState(null);
const supabase = useSupabaseClient();
const session = useSession();

useEffect(() => {
supabase.from('profiles') // Fetch profile from user id matching session
.select()
.eq('id', session.user.id)
.then(result => {
if (result.data.length > 0) {
setProfiles(result.data[0]);
}
});
}, []);

return (
<Layout hideNavigation={false}>
<Card noPadding={true}>
Expand All @@ -24,7 +46,9 @@ export default function ProfilePage() {
<img src="https://images.unsplash.com/photo-1454789591675-556c287e39e2?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1472&q=80" alt=""/>
</div>
<div className="absolute top-40 left-4">
<Avatar size={'lg'} />
<AccountAvatar uid={session.user!.id}
url={profiles.avatar_url}
size={50} />
</div>
<div className="p-4 pt-0 md:pt-4 pb-0">
<div className="ml-24 md:ml-40">
Expand Down
41 changes: 35 additions & 6 deletions pages/posts/index.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,48 @@
import Layout from "../../components/Layout";
import PostFormCard from "../../components/PostFormCard";
import PostCard from "../../components/PostCard";
import React from "react";
import { useSession } from "@supabase/auth-helpers-react";
import React, { useEffect, useState } from "react";
import { useSession, useSupabaseClient } from "@supabase/auth-helpers-react";
import LoginPage from "../login/social-login";

export default function SocialGraphHome() {
const supabase = useSupabaseClient();
const session = useSession();
console.log(session);
const [posts, setPosts] = useState([]);

const [profile, setProfile] = useState(null);

if (!session) { return <LoginPage /> };

function fetchPosts () {
supabase.from('posts')
.select('id, content, created_at, profiles(id, avatar_url, username)') // Reset id on testing playground server later
.order('created_at', { ascending: false })
.then(result => { setPosts(result.data); })
}

function fetchProfile () {
supabase.from('profiles')
.select()
.eq('id', session.user.id)
.then(result => {
if (result.data) {
setProfile(result.data[0]);
}
})
}

fetchProfile();
fetchPosts();

/*useEffect(() => { */fetchPosts();// }, []);

return (
<Layout hideNavigation={false}>
<PostFormCard />
<PostCard />
<PostFormCard onPost={fetchPosts} />
{posts?.length > 0 && posts.map(post => (
<PostCard key = { post.id } {...post} />
))}
</Layout>
)
);
}
10 changes: 10 additions & 0 deletions supabase/rls/posts.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CREATE POLICY "Any user can create posts" ON "public"."posts"
AS PERMISSIVE FOR INSERT
TO public

WITH CHECK (author = auth.uid()) /* https://app.supabase.com/project/qwbufbmxkjfaikoloudl/auth/policies#27609 */

CREATE POLICY "Anyone can see all posts" ON "public"."posts"
AS PERMISSIVE FOR SELECT
TO public
USING (true)
Loading

0 comments on commit 22cb700

Please sign in to comment.