Feedback, Ideas, and Troubleshooting

!! "A Brilliant Idea for creating/keeping Connections" !! - I'm pretty sure...
"I’ve met amazing people during Bootcamp(s), and I wish there were a way to keep supporting each other after it ends." -Me. Bootcamps build real learning communities, but when they end, those connections often fade… Ideas: 1/Connections: Add each other as “Connections” for easier reach. 2/Circles: Create a “Circle” for ongoing discussions. 3/Follow-Ups: Share notes or resources post-session. 4/Focus Tags: Tags in profiles (e.g., “SAT Math, aiming for 700+”). CODE SKETCH: P_1: prisma/schema.prisma enum ConnectionStatus{accepted pending rejected} model User{ id String @id @default(cuid()) email String @unique name String? focusTags String[] @default([]) connections Connection[] @relation("userConnections") received Connection[] @relation("userReceived") circles CircleMember[] followUps FollowUp[] } model Connection{ id String @id @default(cuid()) fromUserId String toUserId String fromUser User @relation("userConnections",fields:[fromUserId],references:[id]) toUser User @relation("userReceived",fields:[toUserId],references:[id]) createdAt DateTime @default(now()) status ConnectionStatus @default(pending) @@unique([fromUserId,toUserId]) @@index([fromUserId,toUserId]) } model Circle{ id String @id @default(cuid()) name String sessionId String? members CircleMember[] followUps FollowUp[] } model CircleMember{ id String @id @default(cuid()) circleId String userId String role String @default("member") circle Circle @relation(fields:[circleId],references:[id]) user User @relation(fields:[userId],references:[id]) @@unique([circleId,userId]) } model FollowUp{ id String @id @default(cuid()) circleId String? authorId String content String createdAt DateTime @default(now()) circle Circle? @relation(fields:[circleId],references:[id]) author User @relation(fields:[authorId],references:[id]) } P_2:/api/connections/check.ts import{NextApiRequest,NextApiResponse}from'next';import{prisma}from'../../../lib/prisma';export default async function handler(req:NextApiRequest,res:NextApiResponse){try{const{userId,targetId}=req.query;if(!userId||!targetId)return res.status(400).json({error:'Missing userId or targetId'});const sharedSessions=await prisma.sessionParticipant.count({where:{userId:String(userId),session:{participants:{some:{userId:String(targetId)}}}}});res.status(200).json({sharedSessions,canConnect:sharedSessions>=3})}catch(e){console.error('Error:',e);res.status(500).json({error:'Internal error'})}} P_3:/api/connections/create.ts import{NextApiRequest,NextApiResponse}from'next';import{prisma}from'../../../lib/prisma';export default async function handler(req:NextApiRequest,res:NextApiResponse){if(req.method!=='POST')return res.status(405).json({error:'Method not allowed'});try{const{fromUserId,toUserId}=req.body;if(!fromUserId||!toUserId)return res.status(400).json({error:'Missing IDs'});if(fromUserId===toUserId)return res.status(400).json({error:'Cannot connect to self'});const sharedSessions=await prisma.sessionParticipant.count({where:{userId:fromUserId,session:{participants:{some:{userId:toUserId}}}}});if(sharedSessions<3)return res.status(403).json({error:'Not eligible'});const connection=await prisma.connection.upsert({where:{fromUserId_toUserId:{fromUserId,toUserId}},update:{status:'accepted'},create:{fromUserId,toUserId,status:'accepted'}});res.status(200).json({connection})}catch(e){console.error('Error:',e);res.status(500).json({error:'Internal error'})}} P_4: components/ConnectionButton.tsx import React from'react';import useSWR from'swr';const fetcher=(u:string)=>fetch(u).then(r=>r.json());interface Props{meId:string;otherId:string}export default function ConnectionButton({meId,otherId}:Props){const{data,error}=useSWR( /api/connections/check?userId=${meId}&targetId=${otherId} ,fetcher);const[loading,setLoading]=React.useState(false);if(error)return<button disabled>Error</button>;if(!data)return<button disabled>Checking…</button>;if(!data.canConnect)return<button disabled>Connect (needs {Math.max(0,3-data.sharedSessions)} more)</button>;async function connect(){setLoading(true);try{const res=await fetch('/api/connections/create',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({fromUserId:meId,toUserId:otherId})});const result=await res.json();res.ok?alert('Connected! 🎉'):alert( Error: ${result.error} )}catch(e){console.error('Error:',e);alert('Unexpected error')}finally{setLoading(false)}}return<button onClick={connect} disabled={loading}>{loading?'Connecting…':'Add connection'}</button>} Extra: I dug around to see what the Schoolhouse public code footprint looks like, and Good news: They have several TypeScript/React-y repos (including a Zoom wrapper and React avatar components). In this light, I assessed that a TypeScript/React/Next.js/Node backend proposal might be credible/helpful to them. My aim isn’t to create a social platform but enhance motivation. -Devon J. H. (Or not, if this flops. o7)
1
Load More