diff --git a/shatter-mobile/app/auth/callback.tsx b/shatter-mobile/app/auth/callback.tsx index bcfd73f..d270f78 100644 --- a/shatter-mobile/app/auth/callback.tsx +++ b/shatter-mobile/app/auth/callback.tsx @@ -11,7 +11,7 @@ import { ActivityIndicator, Text, View } from "react-native"; export default function AuthCallback() { const { code } = useLocalSearchParams<{ code: string }>(); - const { authenticate, authStorage } = useAuth(); + const { authenticate } = useAuth(); const [error, setError] = useState(""); useEffect(() => { @@ -28,11 +28,15 @@ export default function AuthCallback() { // Fetch full user profile using returned userId + token const userData = await userFetch(response.userId, response.token); + const existingSocialLinks = userData.user.socialLinks ?? {}; + const linkedinUrl = existingSocialLinks.linkedin + ?? `https://www.linkedin.com/in/${userData.user.name.toLowerCase().replace(/\s+/g, "-")}/`; + const user: User = { _id: response.userId, name: userData.user.name, email: userData.user.email, - socialLinks: userData.user.socialLinks ?? {}, + socialLinks: { ...existingSocialLinks, linkedin: linkedinUrl }, profilePhoto: userData.user.profilePhoto, isGuest: false, }; @@ -40,9 +44,8 @@ export default function AuthCallback() { // Store user + JWT in auth context await authenticate(user, response.token, false); - // Update stored user with LinkedIn data - const token = authStorage.accessToken; - userUpdate(response.userId, user, token); + // Persist LinkedIn URL to backend using the token from the exchange response + userUpdate(response.userId, user, response.token); router.replace("/JoinEventPage"); } catch (err) { setError((err as Error).message || "Authentication failed."); diff --git a/shatter-mobile/src/components/login-signup/SignupForm.tsx b/shatter-mobile/src/components/login-signup/SignupForm.tsx index fe9c5de..eec029d 100644 --- a/shatter-mobile/src/components/login-signup/SignupForm.tsx +++ b/shatter-mobile/src/components/login-signup/SignupForm.tsx @@ -1,6 +1,8 @@ //called by Profile.tsx for signing up import { User } from "@/src/interfaces/User"; +import { SocialLinks } from "@/src/interfaces/User"; import { userSignup, userUpdate } from "@/src/services/user.service"; +import { FontAwesome, Feather } from "@expo/vector-icons"; import { router, Stack } from "expo-router"; import * as WebBrowser from "expo-web-browser"; import { useState } from "react"; @@ -18,6 +20,7 @@ import { import { SafeAreaView } from "react-native-safe-area-context"; import { SignUpFormStyling as styles } from "../../styling/SignUpFormStyling.styles"; import { useAuth } from "../context/AuthContext"; +import { colors } from "@/src/styling/constants"; export default function SignUpForm() { const { authenticate } = useAuth(); @@ -26,6 +29,10 @@ export default function SignUpForm() { const [password, setPassword] = useState(""); const [loading, setLoading] = useState(false); const [err, setError] = useState(""); + const [selectedType, setSelectedType] = useState<"linkedin" | "github" | "other" | null>(null); + const [linkedin, setLinkedin] = useState(""); + const [github, setGithub] = useState(""); + const [other, setOther] = useState(""); const handleLinkedIn = async () => { await WebBrowser.openBrowserAsync( @@ -76,11 +83,16 @@ export default function SignUpForm() { setError("User info could not be created. Please try again later."); } + const socialLinks: SocialLinks = {}; + if (linkedin.trim()) socialLinks.linkedin = linkedin.trim(); + if (github.trim()) socialLinks.github = github.trim(); + if (other.trim()) socialLinks.other = [{ label: "Contact Link", url: other.trim() }]; + const user: User = { _id: userResponse.userId, name, email, - socialLinks: {}, + socialLinks, profilePhoto: profilePhoto, isGuest: false, }; @@ -147,6 +159,52 @@ export default function SignUpForm() { placeholderTextColor="#888" /> + Contact Link + + setSelectedType("linkedin")} + style={{ padding: 12, borderRadius: 12, backgroundColor: selectedType === "linkedin" ? "#0A66C2" : colors.lightGrey2, flex: 1, marginRight: 8, alignItems: "center" }} + > + + + setSelectedType("github")} + style={{ padding: 12, borderRadius: 12, backgroundColor: selectedType === "github" ? "#24292e" : colors.lightGrey2, flex: 1, marginRight: 8, alignItems: "center" }} + > + + + setSelectedType("other")} + style={{ padding: 12, borderRadius: 12, backgroundColor: selectedType === "other" ? "#6c63ff" : colors.lightGrey2, flex: 1, alignItems: "center" }} + > + + + + + {selectedType && ( + { + if (selectedType === "linkedin") setLinkedin(text); + else if (selectedType === "github") setGithub(text); + else setOther(text); + }} + autoCapitalize="none" + keyboardType="url" + /> + )} + + + Select a platform above, then enter your profile link. + + { + if (Platform.OS === "web") { + window.location.href = `${process.env.EXPO_PUBLIC_API_BASE}/api/auth/linkedin`; + return null; + } + const result = await WebBrowser.openAuthSessionAsync( `${process.env.EXPO_PUBLIC_API_BASE}/api/auth/linkedin?platform=mobile`, REDIRECT_SCHEME, diff --git a/shatter-mobile/src/styling/SignUpFormStyling.styles.ts b/shatter-mobile/src/styling/SignUpFormStyling.styles.ts index 872ee9e..77545f6 100644 --- a/shatter-mobile/src/styling/SignUpFormStyling.styles.ts +++ b/shatter-mobile/src/styling/SignUpFormStyling.styles.ts @@ -11,7 +11,7 @@ export const SignUpFormStyling = StyleSheet.create({ background: { flex: 1, width: "100%", - height: "50%", + height: "100%", }, safe: { flex: 1,