Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions js/docs/frontend-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ js/src/
QueryProvider.tsx # TanStack Query provider
theme.tsx # Mantine theme
features/ # DOMAINS — one folder per bounded context
<domain>/ # e.g. pairings, profile, intake, admin
<domain>/ # e.g. pairings, profile, signup, admin
<Name>.page.tsx # a page (flat file until it grows)
<name>/ # page-FOLDER, only once the page gains local pieces
<Name>.page.tsx
Expand Down Expand Up @@ -65,7 +65,7 @@ js/src/
Keep the `.page.tsx` suffix inside page-folders — don't use `index.tsx`.
5. **Data layer split.** Global (`lib/api/`): generated OpenAPI types + typed fetch client +
QueryClient. Domain-owned (`features/<d>/api/`): per-endpoint query/mutation hooks + Zod
schemas. `useSubmitIntake` belongs to `intake`, not a global pile.
schemas. `useSubmitSignUp` belongs to `SignUp`, not a global pile.
Comment thread
Allimonae marked this conversation as resolved.
6. **Concern folders, on demand.** A domain has `components/` + `api/`; add `hooks/` /
`utils.ts` / `types.ts` only as they grow (flat file first, folder at 2–3 files). There is
no domain-level `lib/` — `lib/` means app infra only.
Expand Down
2 changes: 1 addition & 1 deletion js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"eslint": "eslint .",
"eslint:fix": "eslint . --fix",
"stylelint": "stylelint '**/*.css' --allow-empty-input",
"stylelint:fix": "stylelint '**/*.css' --fix",
"stylelint:fix": "stylelint '**/*.css' --fix --allow-empty-input",
Comment thread
Allimonae marked this conversation as resolved.
"prettier": "prettier --check .",
"prettier:fix": "prettier --write .",
"preview": "vite preview"
Expand Down
6 changes: 5 additions & 1 deletion js/src/app/router/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import EmailAdminPage from "@/features/emails/EmailAdminPage";
import HomePage from "@/features/home/Home.page";
import SamplePage from "@/features/sample/Sample.page";
import SampleAdminPage from "@/features/sample/SampleAdmin.page";
import { SignUpPage } from "@/features/sign-up/SignUp.page";
import { createBrowserRouter } from "react-router-dom";

export const router = createBrowserRouter([
Expand All @@ -18,7 +19,10 @@ export const router = createBrowserRouter([
// Public: no guard, public chrome.
{
element: <PublicLayout />,
children: [{ index: true, element: <HomePage /> }],
children: [
{ index: true, element: <HomePage /> },
{ path: "sign-up", element: <SignUpPage /> },
],
},

// Authenticated: guard -> layout -> page. Admin nests a second guard + layout.
Expand Down
3 changes: 3 additions & 0 deletions js/src/features/home/Home.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ export default function HomePage() {
<Text>
Monthly one-on-one coffee chat pairings for the Patina Network.
</Text>
<Anchor component={Link} to="/sign-up">
Complete the signup form
</Anchor>
<Anchor component={Link} to="/sample">
Go to the app
</Anchor>
Expand Down
13 changes: 13 additions & 0 deletions js/src/features/sign-up/SignUp.page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { IntroText } from "@/features/sign-up/components/IntroText";
import { SignUpForm } from "@/features/sign-up/components/SignUpForm";
import { Stack, Title } from "@mantine/core";

export function SignUpPage() {
return (
<Stack gap="xl">
<Title order={2}>PatChats Sign Up Form</Title>
<IntroText />
<SignUpForm />
</Stack>
);
}
37 changes: 37 additions & 0 deletions js/src/features/sign-up/api/schemas.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { z } from "zod";

export const signUpFormSchema = z.object({
fullName: z.string().min(1, "Full Name is required."),
email: z
.string()
.min(1, "Email Address is required.")
.email("Enter a valid email address."),
linkedin: z
.string()
.refine(
(value) =>
value === "" ||
value.startsWith("https://linkedin.com/in/") ||
value.startsWith("https://www.linkedin.com/in/"),
{
message:
"Enter a LinkedIn profile URL in the format linkedin.com/in/your-profile.",
},
),
introduction: z
.string()
.min(1, "Introduction is required.")
.max(300, "Introduction must be 300 characters or fewer."),
referralSource: z
.string()
.max(200, "Referral source must be 200 characters or fewer."),
matchingPreference: z.string(),
industry: z.string(),
role: z.string().max(200, "Role Preference must be 200 characters or fewer."),
talkingPoints: z
.string()
.max(200, "Talking points must be 200 characters or fewer."),
additionalInfo: z
.string()
.max(500, "Additional info must be 500 characters or fewer."),
});
28 changes: 28 additions & 0 deletions js/src/features/sign-up/components/IntroText.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Text } from "@mantine/core";

export function IntroText() {
return (
<>
<Text size="lg">
Hi everyone! Would you like to get to know other members of the Patina
community better?
<br />
<br />
PatChats is a program where every month you will get matched with
another Patina member, and find a time between the two of you to have a
30 minute video call or coffee chat! At the end, share your socials and
take a fun selfie or screenshot to share on the #pat-chats channel on
our Discord! <br />
<br />
Connect with other members within the Patina network to learn more about
each other and share our diverse backgrounds, professional journeys, and
career insights. Our goal is to foster a more positive, tight-knit
community where we can support one another in reaching our life and
career aspirations and have some fun while we're at it! <br />
<br />
Sign up here to be included in next month's cycle. We currently have 80
people signed up and looking to keep it growing!
</Text>
</>
);
}
Loading
Loading