From 195e8f11ef4a24ea433453d7d51e3df071bfd08a Mon Sep 17 00:00:00 2001 From: Adolfo Reyna Date: Sat, 5 Mar 2022 20:51:45 -0800 Subject: [PATCH] first commit in repo --- API.js | 251 ++++++++++++++++++++++++++++++++++++++++++++ App.js | 40 ++++--- components/Feed.js | 34 ++++++ components/Login.js | 49 +++++++++ 4 files changed, 360 insertions(+), 14 deletions(-) create mode 100644 API.js create mode 100644 components/Feed.js create mode 100644 components/Login.js diff --git a/API.js b/API.js new file mode 100644 index 0000000..4160970 --- /dev/null +++ b/API.js @@ -0,0 +1,251 @@ +const baseUrl = "https://api.emmint.com"; + +let getCall = async (path = "", params = {}) => { + let queryParams = "?"; + Object.keys(params).forEach(p => { + queryParams += p + "=" + params[p] + "&" + }); + return fetch(baseUrl + path + queryParams, { + method: 'GET', + mode: 'cors', + credentials: 'include', + headers: { + 'Content-Type': 'application/json', + } + }).then(response => response.json()).catch((error) => { + console.error(error); + }) +} + +let postCall = async (path, params) => { + return fetch(baseUrl + path, { + method: 'POST', + mode: 'cors', + credentials: 'include', + body: JSON.stringify(params), + headers: { + 'Content-Type': 'application/json', + } + }).then(response => response.json()).catch((error) => { + console.error(error); + }) +} + +let CurrentUserId; +let CurrentProfile; +let CurrentProfileData; +let userNameCache = {}; //save this on localstorage +let working_on = {}; //Promises +let getProfileFromCache = async (id, refresh=false) => { + if(!id) console.trace(); + if (userNameCache[id] && !refresh) + return userNameCache[id]; + if (working_on[id] && !refresh) + return working_on[id]; + console.log(id, "not in cache, getting...") + working_on[id] = getCall("/user/" + id) + return working_on[id]; +} + +const API = { + isLoggedIn: async () => { + return getCall().then((data) => { + console.log("isLoggedIn", data) + if (data && data.status && data.status === 'ok') { + CurrentUserId = data.userInfo._id; + CurrentProfile = data.profileInfo._id; + return true; + } + CurrentUserId = ''; + CurrentProfile = ''; + CurrentProfileData = undefined; + return false; + }) + }, + logIn: async (username, password) => { + return postCall("/login", { + username, + password + }).then((data) => { + if (data && data.status === "ok") { + CurrentUserId = data.user_sid; + CurrentProfile = data.profile_id; + } + return data; + }) + }, + async logout(){ + console.log("Logging out...") + return getCall("/logout").then(()=>{ + CurrentUserId = ''; + CurrentProfile = ''; + CurrentProfileData = undefined; + }); + }, + async signup(username, password, email, profile){ + return postCall("/signup", { + username, + password, + email, + profile + }).then((data) => { + console.log(data) + if (data && data.status === "ok") { + CurrentUserId = data.user_sid; + CurrentProfile = data.profile_id; + } + return data; + }); + }, + resetPassword(email){ + return postCall("/resetPassword", {username: email}); + }, + currentUserId() { + if (!CurrentUserId) this.isLoggedIn(); //replace with cookie + return CurrentUserId; + }, + addPaymentCard(cardInfo){ + return postCall("/payment/card", {cardInfo}); + }, + //Posts + getPosts(userid) { + if (userid) return getCall("/post/usr/" + userid); + return getCall("/post/"); + }, + newPost(content, toProfile) { + //Content is expected to be a string. + let params = { content }; + if (toProfile && CurrentUserId !== toProfile) + params.toProfile = toProfile; + return postCall("/post/", params); + }, + newPostReaction(postid) { + return postCall("/post/react", { postid }); + }, + removePostReaction(postid) { + return postCall("/post/unreact", { postid }); + }, + newPostBookmark(postid) { + return postCall("/post/bookmark", { postid }); + }, + removePostBookmark(postid) { + return postCall("/post/unbookmark", { postid }); + }, + newPostComment(postid, content) { + return postCall("/post/comment/", { postid, content }); + }, + newCommentReaction(postid, commentDate) { + return postCall("/post/comment/react", { postid, commentDate }); + }, + //Invitations + newInvitation(name, email){ + return postCall("/user/invite", { name, email }); + }, + getInvitation(email){ + return getCall("/user/invite", { email }); + }, + //Profiles + async getMe() { + if (!CurrentProfileData) + if(!CurrentProfile) await this.isLoggedIn(); + CurrentProfileData = await this.getUserProfile(CurrentProfile); + return CurrentProfileData; + }, + getMyProfiles() { + return getCall("/user/mine"); + }, + getMyProfile() { + return getCall("/user/" + CurrentProfile); + }, + updateMyProfile(profile) { + return postCall("/user/myProfile", profile); + }, + searchProfiles(query){ + return getCall("/user/search", query ? {query} : {}).then((data)=>{ + if(data.status == "ok"){ + data.profiles.forEach((p)=>{ + userNameCache[p._id] = p; + }); + return data + } + }); + }, + changeProfile(profileid){ + return postCall("/changeProfile", {profileid}).then((profile) =>{ + CurrentProfile = profileid; + CurrentProfileData = profile; + return profile; + }); + }, + getUserProfile(profileid, refresh=false) { + return getProfileFromCache(profileid, refresh); + }, + currentProfileId() { + if (!CurrentProfile) this.isLoggedIn(); //replace with cookie + return CurrentProfile; + }, + followProfile(profileid){ + return getCall("/user/" + profileid + "/follow"); + }, + unfollowProfile(profileid){ + return getCall("/user/" + profileid + "/unfollow"); + }, + setDataValue(key, value){ + return postCall("/user/setData", {key, value}); + }, + //Groups + newGroup(title, subtitle, description, isPrivate=false, isCourse=false) { + return postCall("/user/groups", { + profile: { + firstName: title, + lastName: subtitle, + description + }, + isPrivate, + isCourse + }); + }, + getRecentGroups() { + return getCall("/user/groups"); + }, + searchGroups(query){ + return getCall("/user/groups/search", query ? {query} : {}).then((data)=>{ + if(data.status == "ok"){ + data.groups.forEach((p)=>{ + userNameCache[p._id] = p; + }); + return data + } + }); + }, + getCourses() { + return getCall("/user/courses"); + }, + searchCourses(query){ + return getCall("/user/groups/search", query ? {query, courses: true} : {courses: true}).then((data)=>{ + if(data.status == "ok"){ + data.groups.forEach((p)=>{ + userNameCache[p._id] = p; + }); + return data + } + }); + }, + getGroup(groupid) { + return getCall("/user/groups/" + groupid); + }, + subscribeToGroup(groupid){ + return getCall("/user/groups/" + groupid + "/subscribe"); + }, + acceptGroupRequest(profileid, groupid){ + return postCall("/user/groups/accept", {profileid, groupid}); + }, + rejectGroupRequest(profileid, groupid){ + return postCall("/user/groups/reject", {profileid, groupid}); + }, + unsubscribeToGroup(groupid){ + return getCall("/user/groups/" + groupid + "/unsubscribe"); + } +} + +export default API; \ No newline at end of file diff --git a/App.js b/App.js index 181f3ce..882ef8a 100644 --- a/App.js +++ b/App.js @@ -1,21 +1,33 @@ import { StatusBar } from 'expo-status-bar'; -import React from 'react'; -import { StyleSheet, Text, View } from 'react-native'; +import React, { useEffect, useState } from 'react'; +import { StyleSheet, Text, View, TextInput } from 'react-native'; +import API from './API.js'; +import LoginForm from './components/Login.js'; +import Feed from './components/Feed.js'; export default function App() { - return ( - - Open up App.js to start working on your app! - - - ); + let [isLoggedIn, setIsLoggedIn] = useState(false); + + useEffect(async () => { + let r = await API.isLoggedIn(); + setIsLoggedIn(r); + }, []); + + return ( + + EMI Social LOGO + {!isLoggedIn && } + {isLoggedIn && } + + + ); } const styles = StyleSheet.create({ - container: { - flex: 1, - backgroundColor: '#fff', - alignItems: 'center', - justifyContent: 'center', - }, + container: { + flex: 1, + backgroundColor: '#fff', + alignItems: 'center', + justifyContent: 'center', + }, }); diff --git a/components/Feed.js b/components/Feed.js new file mode 100644 index 0000000..3d7af95 --- /dev/null +++ b/components/Feed.js @@ -0,0 +1,34 @@ +import { StatusBar } from 'expo-status-bar'; +import React, { useState, useEffect } from 'react'; +import { Text, View, ScrollView, Button } from 'react-native'; +import API from './../API.js'; + + +let Feed = () => { + let [Me, setMeProfile] = useState({}); + let [Posts, setPosts] = useState([]); + useEffect(async () => { + let r = await API.getMe(); + setMeProfile(r); + let posts = await API.getPosts(); + setPosts(posts) + //console.log(posts) + }, []); + + return ( + + + Hello: {Me.profile && Me.profile.firstName} {Me.profile && Me.profile.lastName} + { + Posts.map((post, i) => { + return ( + {post.content} + ) + }) + } + + + ); +} + +export default Feed; diff --git a/components/Login.js b/components/Login.js new file mode 100644 index 0000000..a088e00 --- /dev/null +++ b/components/Login.js @@ -0,0 +1,49 @@ +import { StatusBar } from 'expo-status-bar'; +import React, { useState } from 'react'; +import { Text, View, TextInput, Button } from 'react-native'; +import API from './../API.js'; + + +let LoginForm = ()=>{ + let [email, setEmail] = useState(''); + let [password, setPassword] = useState(''); + + return ( + + Log in + setEmail(text)} + defaultValue={email} + placeholder=" email" + /> + setPassword(text)} + defaultValue={password} + placeholder=" password" + textContentType="password" + secureTextEntry={true} + /> +