diff --git a/apps/member-profile/app/routes/_profile.home.tsx b/apps/member-profile/app/routes/_profile.home.tsx index 3ee586911..fa2e5018e 100644 --- a/apps/member-profile/app/routes/_profile.home.tsx +++ b/apps/member-profile/app/routes/_profile.home.tsx @@ -172,9 +172,9 @@ async function getStudent(id: string) { 'students.lastName', 'students.number', (eb) => { - return eb('onboardingSessionAttendees.id', 'is not', null).as( - 'attendedOnboardingSession' - ); + return eb('onboardingSessionAttendees.id', 'is', null) + .and('students.acceptedAt', '>=', new Date('2025-09-01')) + .as('showOnboardingSessionCard'); }, ]) .where('students.id', '=', id) @@ -235,6 +235,7 @@ export default function HomeLayout() {
+ {student.showOnboardingSessionCard && }
@@ -328,6 +329,30 @@ function ActiveStatusCard() { ); } +function OnboardingSessionCard() { + return ( + + Attend an Onboarding Session + + + Learn more about ColorStack, meet other members and gain access to our + Slack workspace! + + + + + + Book Onboarding Session + + + + + ); +} + function MessagesSentCard() { const { messagesSentCount } = useLoaderData(); @@ -424,13 +449,6 @@ function ImportantResourcesCard() { Important Resources
    - - Slack - - - - GitHub - - - + ); diff --git a/apps/member-profile/app/routes/onboarding.slack.tsx b/apps/member-profile/app/routes/onboarding.slack.tsx deleted file mode 100644 index ab9ff9503..000000000 --- a/apps/member-profile/app/routes/onboarding.slack.tsx +++ /dev/null @@ -1,83 +0,0 @@ -import { - type ActionFunctionArgs, - Form, - type LoaderFunctionArgs, - redirect, - useActionData, - useLoaderData, -} from 'react-router'; - -import { job } from '@oyster/core/bull'; -import { db } from '@oyster/db'; -import { ErrorMessage, getErrors } from '@oyster/ui'; - -import { - OnboardingBackButton, - OnboardingButtonGroup, - OnboardingContinueButton, - OnboardingSectionDescription, - OnboardingSectionTitle, -} from '@/routes/onboarding'; -import { Route } from '@/shared/constants'; -import { ensureUserAuthenticated, user } from '@/shared/session.server'; - -export async function loader({ request }: LoaderFunctionArgs) { - const session = await ensureUserAuthenticated(request); - - const member = await db - .selectFrom('students') - .select('email') - .where('id', '=', user(session)) - .executeTakeFirstOrThrow(); - - return { - email: member.email, - }; -} - -export async function action({ request }: ActionFunctionArgs) { - const session = await ensureUserAuthenticated(request); - - const member = await db - .updateTable('students') - .set({ onboardedAt: new Date() }) - .where('id', '=', user(session)) - .returning(['email', 'slackId']) - .executeTakeFirst(); - - if (member && !member.slackId) { - job('slack.invite', { email: member.email }); - } - - const url = new URL(request.url); - - url.pathname = Route['/home']; - url.searchParams.set('new', '1'); - - return redirect(url.toString()); -} - -export default function OnboardingSlackForm() { - const { email } = useLoaderData(); - const actionData = useActionData(); - const { error } = getErrors(actionData); - - return ( -
    - Slack - - - After you click "Finish", we'll send you a Slack invitation to your - email, {email}. Be sure to accept - that invitation right after you check out your Member Profile! 🎉 - - - {error} - - - - - -
    - ); -} diff --git a/apps/member-profile/app/routes/onboarding.tsx b/apps/member-profile/app/routes/onboarding.tsx index 6b5db87b4..85129d56c 100644 --- a/apps/member-profile/app/routes/onboarding.tsx +++ b/apps/member-profile/app/routes/onboarding.tsx @@ -65,19 +65,17 @@ function ProgressBar() { } return ( -
    +
    - -
    ); } -type ProgressStep = '1' | '2' | '3' | '4'; +type ProgressStep = '1' | '2' | '3'; type ProgressBarStepProps = { step: ProgressStep; @@ -113,14 +111,12 @@ const STEP_TO_ROUTE_MAP: Record = { '1': Route['/onboarding/general'], '2': Route['/onboarding/emails'], '3': Route['/onboarding/community'], - '4': Route['/onboarding/slack'], }; const STEP_LABEL_MAP: Record = { '1': 'General', '2': 'Email', '3': 'Community', - '4': 'Slack', }; function ProgressBarStepLabel({ step }: ProgressBarStepProps) { @@ -163,7 +159,6 @@ const ROUTE_TO_STEP_MAP: Record = { [Route['/onboarding/emails']]: '2', [Route['/onboarding/emails/verify']]: '2', [Route['/onboarding/community']]: '3', - [Route['/onboarding/slack']]: '4', }; type StepStatus = 'active' | 'completed' | 'inactive'; diff --git a/apps/member-profile/app/shared/constants.ts b/apps/member-profile/app/shared/constants.ts index 5b4d21375..a21da9943 100644 --- a/apps/member-profile/app/shared/constants.ts +++ b/apps/member-profile/app/shared/constants.ts @@ -28,7 +28,6 @@ const ROUTES = [ '/onboarding/emails', '/onboarding/emails/verify', '/onboarding/general', - '/onboarding/slack', '/offers', '/offers/full-time', '/offers/full-time/add', diff --git a/packages/core/src/modules/onboarding-sessions/use-cases/add-onboarding-session-attendees.ts b/packages/core/src/modules/onboarding-sessions/use-cases/add-onboarding-session-attendees.ts index 8bfb34924..9192af331 100644 --- a/packages/core/src/modules/onboarding-sessions/use-cases/add-onboarding-session-attendees.ts +++ b/packages/core/src/modules/onboarding-sessions/use-cases/add-onboarding-session-attendees.ts @@ -19,7 +19,7 @@ export async function addOnboardingSessionAttendees( .where('id', '=', onboardingSessionId) .executeTakeFirstOrThrow(); - await db.transaction().execute(async (trx) => { + const attendees = await db.transaction().execute(async (trx) => { await Promise.all( input.attendees.map(async (studentId) => { await trx @@ -40,12 +40,22 @@ export async function addOnboardingSessionAttendees( .execute(); }) ); + + return trx + .selectFrom('students') + .select(['email', 'id', 'slackId']) + .where('id', 'in', input.attendees) + .execute(); }); - input.attendees.forEach((studentId) => { + attendees.forEach((attendee) => { job('onboarding_session.attended', { onboardingSessionId, - studentId, + studentId: attendee.id, }); + + if (!attendee.slackId) { + job('slack.invite', { email: attendee.email }); + } }); } diff --git a/packages/core/src/modules/onboarding-sessions/use-cases/upload-onboarding-session.ts b/packages/core/src/modules/onboarding-sessions/use-cases/upload-onboarding-session.ts index 2574429b7..62d63a1be 100644 --- a/packages/core/src/modules/onboarding-sessions/use-cases/upload-onboarding-session.ts +++ b/packages/core/src/modules/onboarding-sessions/use-cases/upload-onboarding-session.ts @@ -16,7 +16,7 @@ export async function uploadOnboardingSession( ) { const onboardingSessionId = id(); - await db.transaction().execute(async (trx) => { + const attendees = await db.transaction().execute(async (trx) => { await trx .insertInto('onboardingSessions') .values({ @@ -45,12 +45,22 @@ export async function uploadOnboardingSession( .execute(); }) ); + + return trx + .selectFrom('students') + .select(['email', 'id', 'slackId']) + .where('id', 'in', input.attendees) + .execute(); }); - input.attendees.forEach((studentId) => { + attendees.forEach((attendee) => { job('onboarding_session.attended', { onboardingSessionId, - studentId, + studentId: attendee.id, }); + + if (!attendee.slackId) { + job('slack.invite', { email: attendee.email }); + } }); } diff --git a/packages/db/src/scripts/seed.ts b/packages/db/src/scripts/seed.ts index 72672727c..df7771c00 100644 --- a/packages/db/src/scripts/seed.ts +++ b/packages/db/src/scripts/seed.ts @@ -11,6 +11,8 @@ if (IS_PRODUCTION) { throw new Error('Cannot seed database in non-development environment.'); } +let email = ''; + main(); async function main() { @@ -37,8 +39,6 @@ async function main() { } } -let email = ''; - function setEmailFromCommandLine() { const answer = prompt( 'In order to log into the Member Profile and Admin Dashboard, you will need both a member record and an admin record. Please provide an email so we can create those for you.\n' +