From 6bcff5adaa528d29ac41b7db797a554c4f06ddad Mon Sep 17 00:00:00 2001 From: madsab Date: Mon, 5 Aug 2024 14:41:08 +0200 Subject: [PATCH 1/7] add PhoneInput component + validatePhoneNumber method --- packages/ui/package.json | 3 +- .../PhoneInput/PhoneInput.stories.tsx | 10 +++ .../src/components/PhoneInput/PhoneInput.tsx | 61 +++++++++++++++++++ .../ui/src/components/PhoneInput/index.tsx | 2 + packages/ui/src/index.ts | 16 ++--- 5 files changed, 83 insertions(+), 9 deletions(-) create mode 100644 packages/ui/src/components/PhoneInput/PhoneInput.stories.tsx create mode 100644 packages/ui/src/components/PhoneInput/PhoneInput.tsx create mode 100644 packages/ui/src/components/PhoneInput/index.tsx diff --git a/packages/ui/package.json b/packages/ui/package.json index b542c3258..582b9402c 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -22,13 +22,14 @@ "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-navigation-menu": "^1.1.4", "@radix-ui/react-radio-group": "^1.1.3", + "@radix-ui/react-select": "^1.2.2", "@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-tabs": "^1.0.4", - "@radix-ui/react-select": "^1.2.2", "clsx": "^2.0.0", "cva": "npm:class-variance-authority@^0.7.0", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-phone-number-input": "^3.4.5", "tailwind-merge": "^2.0.0" }, "devDependencies": { diff --git a/packages/ui/src/components/PhoneInput/PhoneInput.stories.tsx b/packages/ui/src/components/PhoneInput/PhoneInput.stories.tsx new file mode 100644 index 000000000..b431cea11 --- /dev/null +++ b/packages/ui/src/components/PhoneInput/PhoneInput.stories.tsx @@ -0,0 +1,10 @@ +import { useState } from "react"; +import { PhoneInput } from "./PhoneInput"; + +export default { + title: "PhoneInput", +}; +export const Default = () => { + const [phoneValue, setPhoneValue] = useState(); + return setPhoneValue} value={phoneValue} />; +}; diff --git a/packages/ui/src/components/PhoneInput/PhoneInput.tsx b/packages/ui/src/components/PhoneInput/PhoneInput.tsx new file mode 100644 index 000000000..d205f6891 --- /dev/null +++ b/packages/ui/src/components/PhoneInput/PhoneInput.tsx @@ -0,0 +1,61 @@ +"use client" +import { Component, FC, forwardRef, LegacyRef } from "react" +import PhoneInputWithCountry, { + DefaultInputComponentProps, + Props, + isValidPhoneNumber as isValidPhoneNumberOrigin, +} from "react-phone-number-input" +import { cn } from "../../utils" +import "react-phone-number-input/style.css" +import { Label } from "@radix-ui/react-label" +import { cva } from "cva" + +export interface CustomPhoneInputProps extends Props { + defaultValue?: string + label?: string + width?: string + error?: string +} + +const PhoneInput = forwardRef( + ({ defaultValue, label, width, error, ...props }, ref) => ( +
+ {label && ( + + )} + + {typeof error === "string" && {error}} +
+ ) +) + +const input = cva( + "border-solid border outline-none focus:border-blue-7 bg-white-3 hover:bg-white-4 active:bg-white-5 rounded-md p-2 focus:ring-2 focus:ring-brand", + { + variants: { + error: { + true: "text-red-11 border-red-7", + false: "text-slate-12 border-slate-6", + }, + disabled: { + true: "cursor-not-allowed text-slate-10", + }, + }, + } +) + +const isValidPhoneNumber = (phoneNumber: string) => { + return isValidPhoneNumberOrigin(phoneNumber) +} + +export { PhoneInput, isValidPhoneNumber } diff --git a/packages/ui/src/components/PhoneInput/index.tsx b/packages/ui/src/components/PhoneInput/index.tsx new file mode 100644 index 000000000..0d88c6e3a --- /dev/null +++ b/packages/ui/src/components/PhoneInput/index.tsx @@ -0,0 +1,2 @@ +export { PhoneInput, isValidPhoneNumber } from "./PhoneInput" +export type { CustomPhoneInputProps } from "./PhoneInput" diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index 73cdec2ed..664037e00 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -1,20 +1,20 @@ export * from "./components/Accordion" export * from "./components/Alert" +export * from "./components/Avatar" export * from "./components/Badge" export * from "./components/Button" export * from "./components/Card" +export * from "./components/Circle" export * from "./components/Checkbox" export * from "./components/Dialog" -export * from "./components/Textarea" -export * from "./components/Toggle" +export * from "./components/DropdownMenu" +export * from "./components/Icon" export * from "./components/Input" export * from "./components/Label" -export * from "./components/Icon" -export * from "./components/Avatar" -export * from "./components/Circle" -export * from "./components/Text" -export * from "./components/DropdownMenu" -export * from "./components/Accordion" +export * from "./components/PhoneInput" export * from "./components/Select" +export * from "./components/Text" +export * from "./components/Textarea" +export * from "./components/Toggle" export * from "./utils" From 9241ba510d08582d7e13d9351e3e5909ec318e25 Mon Sep 17 00:00:00 2001 From: madsab Date: Tue, 13 Aug 2024 19:56:19 +0200 Subject: [PATCH 2/7] set User-properties middlename and phonenumber to optional --- packages/db/src/db.generated.d.ts | 2 +- packages/types/src/user.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/db/src/db.generated.d.ts b/packages/db/src/db.generated.d.ts index 750c48a21..1682617f4 100644 --- a/packages/db/src/db.generated.d.ts +++ b/packages/db/src/db.generated.d.ts @@ -221,7 +221,7 @@ export interface OwUser { givenName: string id: Generated lastSyncedAt: Generated - middleName: string + middleName: string | null name: string phone: string | null picture: string | null diff --git a/packages/types/src/user.ts b/packages/types/src/user.ts index 286a3263f..be1bd4bbb 100644 --- a/packages/types/src/user.ts +++ b/packages/types/src/user.ts @@ -6,10 +6,10 @@ export const UserSchema = z.object({ email: z.string().email(), givenName: z.string(), familyName: z.string(), - middleName: z.string(), + middleName: z.string().nullable().optional(), gender: z.enum(["male", "female", "other"]), name: z.string(), - phone: z.string().nullable(), + phone: z.string().nullable().optional(), studyYear: z.number().int().min(-1).max(6), allergies: z.array(z.string()), picture: z.string().nullable(), From d97a83a62e2ab04f7774524bd14d951b9630fce0 Mon Sep 17 00:00:00 2001 From: madsab Date: Tue, 13 Aug 2024 20:05:34 +0200 Subject: [PATCH 3/7] fix(button): prevent `loading` prop from being passed as an HTML attribute --- packages/ui/src/components/Button/Button.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/ui/src/components/Button/Button.tsx b/packages/ui/src/components/Button/Button.tsx index e5c1dc7fd..23a6ad338 100644 --- a/packages/ui/src/components/Button/Button.tsx +++ b/packages/ui/src/components/Button/Button.tsx @@ -15,10 +15,10 @@ export interface ButtonProps extends React.ButtonHTMLAttributes((props, ref) => ( +export const Button = forwardRef(({ loading, icon, ...props }, ref) => (