diff --git a/.env b/.env new file mode 100644 index 0000000..2049a66 --- /dev/null +++ b/.env @@ -0,0 +1,2 @@ +EXPO_PUBLIC_SUPABASE_URL=https://vaimftgbjqbylduffpkw.supabase.co +EXPO_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InZhaW1mdGdianFieWxkdWZmcGt3Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MjgwMDM3NzMsImV4cCI6MjA0MzU3OTc3M30.7uvkyKie49rkNr-fG0E77PsdMreHvAmb9hmSOIdh2Sc \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 3010811..d5eed80 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@react-navigation/native": "^6.1.18", "@react-navigation/native-stack": "^6.11.0", + "@supabase/supabase-js": "^2.45.4", "expo": "~51.0.34", "expo-status-bar": "~1.12.1", "react": "18.2.0", @@ -6365,6 +6366,80 @@ "@sinonjs/commons": "^3.0.0" } }, + "node_modules/@supabase/auth-js": { + "version": "2.65.0", + "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.65.0.tgz", + "integrity": "sha512-+wboHfZufAE2Y612OsKeVP4rVOeGZzzMLD/Ac3HrTQkkY4qXNjI6Af9gtmxwccE5nFvTiF114FEbIQ1hRq5uUw==", + "license": "MIT", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/functions-js": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.4.1.tgz", + "integrity": "sha512-8sZ2ibwHlf+WkHDUZJUXqqmPvWQ3UHN0W30behOJngVh/qHHekhJLCFbh0AjkE9/FqqXtf9eoVvmYgfCLk5tNA==", + "license": "MIT", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/node-fetch": { + "version": "2.6.15", + "resolved": "https://registry.npmjs.org/@supabase/node-fetch/-/node-fetch-2.6.15.tgz", + "integrity": "sha512-1ibVeYUacxWYi9i0cf5efil6adJ9WRyZBLivgjs+AUpewx1F3xPi7gLgaASI2SmIQxPoCEjAsLAzKPgMJVgOUQ==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/@supabase/postgrest-js": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.16.1.tgz", + "integrity": "sha512-EOSEZFm5pPuCPGCmLF1VOCS78DfkSz600PBuvBND/IZmMciJ1pmsS3ss6TkB6UkuvTybYiBh7gKOYyxoEO3USA==", + "license": "MIT", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/realtime-js": { + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.10.2.tgz", + "integrity": "sha512-qyCQaNg90HmJstsvr2aJNxK2zgoKh9ZZA8oqb7UT2LCh3mj9zpa3Iwu167AuyNxsxrUE8eEJ2yH6wLCij4EApA==", + "license": "MIT", + "dependencies": { + "@supabase/node-fetch": "^2.6.14", + "@types/phoenix": "^1.5.4", + "@types/ws": "^8.5.10", + "ws": "^8.14.2" + } + }, + "node_modules/@supabase/storage-js": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.7.0.tgz", + "integrity": "sha512-iZenEdO6Mx9iTR6T7wC7sk6KKsoDPLq8rdu5VRy7+JiT1i8fnqfcOr6mfF2Eaqky9VQzhP8zZKQYjzozB65Rig==", + "license": "MIT", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/supabase-js": { + "version": "2.45.4", + "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.45.4.tgz", + "integrity": "sha512-E5p8/zOLaQ3a462MZnmnz03CrduA5ySH9hZyL03Y+QZLIOO4/Gs8Rdy4ZCKDHsN7x0xdanVEWWFN3pJFQr9/hg==", + "license": "MIT", + "dependencies": { + "@supabase/auth-js": "2.65.0", + "@supabase/functions-js": "2.4.1", + "@supabase/node-fetch": "2.6.15", + "@supabase/postgrest-js": "1.16.1", + "@supabase/realtime-js": "2.10.2", + "@supabase/storage-js": "2.7.0" + } + }, "node_modules/@svgr/babel-plugin-add-jsx-attribute": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", @@ -6827,6 +6902,12 @@ "@types/node": "*" } }, + "node_modules/@types/phoenix": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.5.tgz", + "integrity": "sha512-xegpDuR+z0UqG9fwHqNoy3rI7JDlvaPh2TY47Fl80oq6g+hXT+c/LEuE43X48clZ6lOfANl5WrPur9fYO1RJ/w==", + "license": "MIT" + }, "node_modules/@types/prop-types": { "version": "15.7.12", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", @@ -6848,6 +6929,15 @@ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==" }, + "node_modules/@types/ws": { + "version": "8.5.12", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", + "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/yargs": { "version": "13.0.12", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", diff --git a/package.json b/package.json index 746fb32..3a80b08 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "dependencies": { "@react-navigation/native": "^6.1.18", "@react-navigation/native-stack": "^6.11.0", + "@supabase/supabase-js": "^2.45.4", "expo": "~51.0.34", "expo-status-bar": "~1.12.1", "react": "18.2.0", diff --git a/src/screens/PostScreen.tsx b/src/screens/PostScreen.tsx index 30e4da9..707a957 100644 --- a/src/screens/PostScreen.tsx +++ b/src/screens/PostScreen.tsx @@ -1,43 +1,117 @@ -import { Text, View } from 'react-native'; +import React, { useEffect, useState } from 'react'; +import { Image, Text, View } from 'react-native'; +import supabase from 'supabase/client'; import HeartIcon from '../../assets/heart-icon.svg'; import ShareIcon from '../../assets/messenger-icon.svg'; import ProfilePlaceholder from '../../assets/profile-placeholder-icon.svg'; import { styles } from './styles'; export default function PostScreen() { + interface Post { + id: number; + created_at: string; + description: string; + username: string; + image_url: string; + like_count: number; + } + + const getPostData = async (): Promise => { + const { data, error } = await supabase + .from('posts') + .select('*') + .eq('username', 'rbeggs'); + + if (error) { + throw new Error(`Error fetching post: ${error.message}`); + } + return data as Post[]; + }; + + const [postData, setPostData] = useState([]); + + useEffect(() => { + fetchPostData(); + }, []); + + const fetchPostData = async () => { + try { + const data = await getPostData(); + setPostData(data); + } catch (error) { + console.error('Error fetching data:', error); + } + }; + return ( - - rbeggs - September 19 - - In response to the growing homelessness crisis in San Francisco, a local - nonprofit organization, Code Tenderloin, has launched a comprehensive - initiative aimed at providing long-term solutions for individuals - experiencing homelessness. The organization, founded in 2015, is - dedicated to addressing both immediate needs and underlying causes of - homelessness through a combination of shelter services, job training - programs, and mental health support. read more online: - https://www.codetenderloin.org/ - - - Image URL: - 'https://cdn.britannica.com/51/178051-050-3B786A55/San-Francisco.jpg' - - - 256 Likes - - - philip_ye - September 20 - - This organization is doing amazing work tackling the complex root causes - of the issue. - - - vppraggie - September 21 - Thanks for sharing! + {postData.map(post => ( + + {/* Profile Header */} + + + + {post.username} + + + {new Date(post.created_at).toLocaleDateString('en-US', { + year: 'numeric', + month: 'long', + day: 'numeric', + })} + + + + {/* Post Text */} + + {post.description} + + + {/* Post Image */} + {post.image_url ? ( + + ) : null} + + {/* Interaction Row */} + + + + {post.like_count} Likes + + + + + {/* Comment Section */} + + {/* First Comment */} + + + + + philip_ye + September 20 + + + This organization is doing amazing work tackling the complex + root causes of the issue. + + + + + {/* Second Comment */} + + + + + vppraggie + September 21 + + Thanks for sharing! + + + + + ))} ); } diff --git a/src/screens/styles.ts b/src/screens/styles.ts index 09f352c..48fc40b 100644 --- a/src/screens/styles.ts +++ b/src/screens/styles.ts @@ -4,7 +4,103 @@ export const styles = StyleSheet.create({ container: { flex: 1, flexDirection: 'column', - alignItems: 'center', backgroundColor: 'white', + padding: 10, + }, + profileHeader: { + flexDirection: 'row', + alignItems: 'center', + marginBottom: 8, + justifyContent: 'space-between', + }, + profileName: { + fontWeight: 'bold', + fontSize: 16, + marginLeft: 8, + }, + postDate: { + color: 'gray', + paddingLeft: 120, + }, + postTextContainer: { + marginBottom: 10, + }, + postText: { + fontSize: 14, + lineHeight: 20, + }, + inlineLink: { + fontSize: 14, + color: 'black', + }, + linkText: { + color: '#1E90FF', + textDecorationLine: 'underline', + }, + postImage: { + width: '100%', + height: 200, + borderRadius: 10, + marginVertical: 10, + }, + interactionRow: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + marginVertical: 10, + width: '100%', + }, + icon: { + marginRight: 8, + }, + likesText: { + marginLeft: 5, + }, + commentSection: { + borderTopWidth: 1, + borderTopColor: '#ccc', + paddingTop: 10, + marginTop: 20, + paddingRight: 10, + }, + commentIcon: { + width: 30, + height: 30, + marginRight: 10, + }, + commentBody: { + flex: 1, + }, + profileIcon: { + width: 40, + }, + comment: { + flexDirection: 'row', + alignItems: 'flex-start', + marginBottom: 10, + paddingRight: 10, + }, + commentHeader: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + width: '100%', + columnGap: 10, + }, + commentName: { + fontWeight: 'bold', + fontSize: 14, + }, + commentDate: { + color: 'gray', + paddingRight: 12, + }, + commentTextContainer: { + marginTop: 4, + }, + commentText: { + marginTop: 2, + fontSize: 14, + lineHeight: 18, }, }); diff --git a/supabase/.gitignore b/supabase/.gitignore new file mode 100644 index 0000000..e346b91 --- /dev/null +++ b/supabase/.gitignore @@ -0,0 +1,2 @@ +#supabase +.env \ No newline at end of file diff --git a/supabase/client.ts b/supabase/client.ts new file mode 100644 index 0000000..255116b --- /dev/null +++ b/supabase/client.ts @@ -0,0 +1,13 @@ +import { createClient } from '@supabase/supabase-js'; + +if ( + !process.env.EXPO_PUBLIC_SUPABASE_URL || + !process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY +) { + throw new Error('Supabase environment variables are not defined.'); +} +const supabase = createClient( + process.env.EXPO_PUBLIC_SUPABASE_URL, + process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY, +); +export default supabase;