diff --git a/components/atoms/Avatar/avatar.tsx b/components/atoms/Avatar/avatar.tsx index 034bc6559..26baee1ea 100644 --- a/components/atoms/Avatar/avatar.tsx +++ b/components/atoms/Avatar/avatar.tsx @@ -28,7 +28,7 @@ const Avatar = (props: AvatarProps): JSX.Element => { case "string": return ; case "number": - return ; + return ; default: return invalid avatar size props!!!; diff --git a/components/atoms/Checkbox/checkbox.tsx b/components/atoms/Checkbox/checkbox.tsx index 1a3bebccd..b8f88503d 100644 --- a/components/atoms/Checkbox/checkbox.tsx +++ b/components/atoms/Checkbox/checkbox.tsx @@ -9,7 +9,9 @@ interface CheckboxProps extends React.ComponentProps = (props) => { return ( *]:!bg-orange-500 !text-orange-500 ${props.className || ""}`} + className={`checked:[&>*]:!bg-orange-500 disabled:[&>*]:!cursor-not-allowed !text-orange-500 ${ + props.className || "" + }`} {...props} /> ); diff --git a/components/atoms/TextInput/text-input.tsx b/components/atoms/TextInput/text-input.tsx index 0494e4811..9dd695da3 100644 --- a/components/atoms/TextInput/text-input.tsx +++ b/components/atoms/TextInput/text-input.tsx @@ -45,7 +45,7 @@ const TextInput = ({ "flex-1 px-3 text-light-slate-12 bg-white shadow-input border transition rounded-lg py-1 flex items-center", borderless && "!border-none", state === "invalid" ? " focus-within:border-light-red-10 " : "focus-within:border-light-orange-9 ", - disabled && "bg-light-slate-3", + disabled && "bg-light-slate-3 text-light-slate-6", classNames )} > @@ -57,18 +57,24 @@ const TextInput = ({ placeholder={placeholder || ""} onChange={onChange} value={value} - className={`flex-1 focus:outline-none ${classNames}`} + className={`flex-1 focus:outline-none ${classNames} ${ + disabled && "bg-light-slate-3 cursor-not-allowed text-light-slate-9" + }`} autoFocus={autoFocus} disabled={disabled} /> - {state === "valid" ? ( - - ) : !!value ? ( - handleResetInput()}> - - - ) : ( - "" + {!disabled && ( + <> + {state === "valid" ? ( + + ) : !!value ? ( + handleResetInput()}> + + + ) : ( + "" + )} + )} diff --git a/components/molecules/AuthSection/auth-section.tsx b/components/molecules/AuthSection/auth-section.tsx index 337616564..a2a5f2a35 100644 --- a/components/molecules/AuthSection/auth-section.tsx +++ b/components/molecules/AuthSection/auth-section.tsx @@ -1,4 +1,13 @@ import Image from "next/image"; +import Link from "next/link"; + +import { FiLogOut, FiSettings } from "react-icons/fi"; +import { Divider } from "@supabase/ui"; + +import useSession from "lib/hooks/useSession"; +import useSupabaseAuth from "../../../lib/hooks/useSupabaseAuth"; + +import PersonIcon from "img/icons/person-icon.svg"; import notifications from "../../../img/notifications.svg"; import downArrow from "../../../img/chevron-down.svg"; import Avatar from "components/atoms/Avatar/avatar"; @@ -7,12 +16,8 @@ import userAvatar from "../../../img/ellipse-1.png"; import OnboardingButton from "../OnboardingButton/onboarding-button"; import DropdownList from "../DropdownList/dropdown-list"; import Text from "components/atoms/Typography/text"; -import { Divider } from "@supabase/ui"; -import useSupabaseAuth from "../../../lib/hooks/useSupabaseAuth"; -import { FiLogOut } from "react-icons/fi"; import GitHubIcon from "img/icons/github-icon.svg"; import Icon from "components/atoms/Icon/icon"; -import useSession from "lib/hooks/useSession"; const AuthSection: React.FC = ({}) => { const { signIn, signOut, user } = useSupabaseAuth(); @@ -20,6 +25,24 @@ const AuthSection: React.FC = ({}) => { const authMenu = { authed: [ + +
+ Icon +
+ {user?.user_metadata.user_name} + , + + + Settings + , await signOut()} key="authorized" diff --git a/components/organisms/ContributorProfilePage/contributor-profile-page.tsx b/components/organisms/ContributorProfilePage/contributor-profile-page.tsx index 48ea6fb5e..98db368ea 100644 --- a/components/organisms/ContributorProfilePage/contributor-profile-page.tsx +++ b/components/organisms/ContributorProfilePage/contributor-profile-page.tsx @@ -90,7 +90,7 @@ const ContributorProfilePage = ({

Languages

- +
diff --git a/components/organisms/UserSettingsPage/user-settings-page.tsx b/components/organisms/UserSettingsPage/user-settings-page.tsx index 5af5caef0..69f6a9b9f 100644 --- a/components/organisms/UserSettingsPage/user-settings-page.tsx +++ b/components/organisms/UserSettingsPage/user-settings-page.tsx @@ -1,4 +1,6 @@ -import React, { useState } from "react"; +import React, { useState, useEffect } from "react"; + +import { User } from "@supabase/supabase-js"; import Button from "components/atoms/Button/button"; import Checkbox from "components/atoms/Checkbox/checkbox"; @@ -8,10 +10,56 @@ import Select from "components/atoms/Select/select"; import SelectOption from "components/atoms/Select/select-option"; import LanguagePill from "components/atoms/LanguagePill/LanguagePill"; -const UserSettingsPage = () => { +import { updateUser } from "lib/hooks/update-user"; +import { ToastTrigger } from "lib/utils/toast-trigger"; +import { authSession } from "lib/hooks/authSession"; +import { validateEmail } from "lib/utils/validate-email"; +import { timezones } from "lib/utils/timezones"; +import { updateEmailPreferences } from "lib/hooks/updateEmailPreference"; +import { useFetchUser } from "lib/hooks/useFetchUser"; + +interface userSettingsPageProps { + user: User | null; +} + +type EmailPreferenceType = { + display_email?: boolean; + receive_collaboration?: boolean; +}; +const UserSettingsPage = ({ user }: userSettingsPageProps) => { + const { data: insightsUser } = useFetchUser(user?.user_metadata.user_name); + + const [isValidEmail, setIsValidEmail] = useState(true); + const [userInfo, setUserInfo] = useState(); + const [email, setEmail] = useState(userInfo?.email || user?.email); + const [emailPreference, setEmailPreference] = useState({ + // eslint-disable-next-line camelcase + display_email: false, + // eslint-disable-next-line camelcase + receive_collaboration: false + }); const [selectedInterest, setSelectedInterest] = useState([]); const interestArray = ["javascript", "python", "rust", "ML", "AI", "react"]; + useEffect(() => { + async function fetchAuthSession() { + const response = await authSession(); + if (response !== false) setUserInfo(response); + } + + if (user) setEmail(user.email); + if (insightsUser) { + setEmailPreference({ + // eslint-disable-next-line camelcase + display_email: insightsUser?.display_email, + // eslint-disable-next-line camelcase + receive_collaboration: insightsUser?.receive_collaboration + }); + setSelectedInterest(insightsUser?.interests.split(",")); + } + fetchAuthSession(); + }, [user, insightsUser]); + const handleSelectInterest = (interest: string) => { if (selectedInterest.length > 0 && selectedInterest.includes(interest)) { setSelectedInterest((prev) => prev.filter((item) => item !== interest)); @@ -20,23 +68,65 @@ const UserSettingsPage = () => { } }; + const handleUpdateEmailPreference = async () => { + const data = await updateEmailPreferences({ ...emailPreference }); + if (data) { + ToastTrigger({ message: "Updated successfully", type: "success" }); + } else { + ToastTrigger({ message: "An error occured!!!", type: "error" }); + } + }; + + const handleUpdateInterest = async () => { + const data = await updateUser({ + data: { interests: selectedInterest }, + params: "interests" + }); + if (data) { + ToastTrigger({ message: "Updated successfully", type: "success" }); + } else { + ToastTrigger({ message: "An error occured!!!", type: "error" }); + } + }; + const handleUpdateProfile = async () => { + const data = await updateUser({ + data: { email } + }); + if (data) { + ToastTrigger({ message: "Updated successfully", type: "success" }); + } else { + ToastTrigger({ message: "An error occured!!!", type: "error" }); + } + }; + return (
-
+
Public profile -
+ e.preventDefault()} className="flex flex-col gap-6 mt-6"> { + setEmail(e.target.value); + if (validateEmail(e.target.value)) { + setIsValidEmail(true); + } else { + setIsValidEmail(false); + } + }} label="Email*" + value={email} /> {/* Bio section */} @@ -45,31 +135,43 @@ const UserSettingsPage = () => {
- + Other users will see the time difference from their local time. @@ -77,10 +179,17 @@ const UserSettingsPage = () => {
- +
@@ -98,19 +207,42 @@ const UserSettingsPage = () => { /> ))}
- +
- - + setEmailPreference((prev) => ({ ...prev, display_email: !prev.display_email }))} + checked={emailPreference.display_email} + title="profile email" + label="Display email on profile" + /> + + // eslint-disable-next-line camelcase + setEmailPreference((prev) => ({ ...prev, receive_collaboration: !prev.receive_collaboration })) + } + checked={emailPreference.receive_collaboration} + title="collaboration requests" + label="Receive collaboration requests" + />
- +
diff --git a/lib/hooks/authSession.ts b/lib/hooks/authSession.ts new file mode 100644 index 000000000..741799f88 --- /dev/null +++ b/lib/hooks/authSession.ts @@ -0,0 +1,24 @@ +import { supabase } from "lib/utils/supabase"; + +const baseUrl = process.env.NEXT_PUBLIC_API_URL; +export interface UserResponse extends DbUser {} +const authSession = async () => { + const sessionResponse = await supabase.auth.getSession(); + const sessionToken = sessionResponse?.data.session?.access_token; + // const { data, error } = useSWR("auth/session", publicApiFetcher as Fetcher); + const response = await fetch(`${baseUrl}/auth/session`, { + headers: { + Accept: "application/json", + "Content-Type": "application/json", + Authorization: `Bearer ${sessionToken}` + } + }); + + if (response.status === 200) { + return response.json(); + } else { + return false; + } +}; + +export { authSession }; diff --git a/lib/hooks/update-user.ts b/lib/hooks/update-user.ts new file mode 100644 index 000000000..e771cebfd --- /dev/null +++ b/lib/hooks/update-user.ts @@ -0,0 +1,33 @@ +import { supabase } from "lib/utils/supabase"; + +interface useUpdateUserProps { + data: { email?: string; interests?: string[] }; + params?: string; +} + +const baseUrl = process.env.NEXT_PUBLIC_API_URL; +const updateUser = async ({ data, params }: useUpdateUserProps) => { + const sessionResponse = await supabase.auth.getSession(); + const sessionToken = sessionResponse?.data.session?.access_token; + try { + const res = await fetch(`${baseUrl}/auth/profile${params ? `/${params}` : ""}`, { + headers: { + Accept: "application/json", + "Content-Type": "application/json", + Authorization: `Bearer ${sessionToken}` + }, + method: "PATCH", + body: JSON.stringify({ ...data }) + }); + + if (res.status === 200) { + return res.json(); + } else { + return false; + } + } catch (e) { + return false; + } +}; + +export { updateUser }; diff --git a/lib/hooks/updateEmailPreference.ts b/lib/hooks/updateEmailPreference.ts new file mode 100644 index 000000000..7c33d9869 --- /dev/null +++ b/lib/hooks/updateEmailPreference.ts @@ -0,0 +1,31 @@ +import { supabase } from "lib/utils/supabase"; + +interface UpdateEmailProps { + display_email?: boolean; + receive_collaboration?: boolean; +} + +const baseUrl = process.env.NEXT_PUBLIC_API_URL; +const updateEmailPreferences = async (data: UpdateEmailProps) => { + const sessionResponse = await supabase.auth.getSession(); + const sessionToken = sessionResponse?.data.session?.access_token; + try { + const res = await fetch(`${baseUrl}/auth/profile/email`, { + headers: { + Accept: "application/json", + "Content-Type": "application/json", + Authorization: `Bearer ${sessionToken}` + }, + method: "PATCH", + body: JSON.stringify({ ...data }) + }); + + if (res.status === 200) { + return res.json(); + } + } catch (e) { + return false; + } +}; + +export { updateEmailPreferences }; diff --git a/lib/hooks/useFetchUser.ts b/lib/hooks/useFetchUser.ts index 58fc92dd8..60948f7fb 100644 --- a/lib/hooks/useFetchUser.ts +++ b/lib/hooks/useFetchUser.ts @@ -1,7 +1,7 @@ import publicApiFetcher from "lib/utils/public-api-fetcher"; import useSWR, { Fetcher } from "swr"; -interface UserResponse extends DbUser {} +export interface UserResponse extends DbUser {} const useFetchUser = (username: string) => { const { data, error } = useSWR( username ? `users/${username}` : null, diff --git a/lib/utils/timezones.ts b/lib/utils/timezones.ts new file mode 100644 index 000000000..737abb42a --- /dev/null +++ b/lib/utils/timezones.ts @@ -0,0 +1,1179 @@ +export const timezones = [ + { + value: "Dateline Standard Time", + abbr: "DST", + offset: -12, + isdst: false, + text: "(UTC-12:00) International Date Line West", + utc: ["Etc/GMT+12"] + }, + { + value: "UTC-11", + abbr: "U", + offset: -11, + isdst: false, + text: "(UTC-11:00) Coordinated Universal Time-11", + utc: ["Etc/GMT+11", "Pacific/Midway", "Pacific/Niue", "Pacific/Pago_Pago"] + }, + { + value: "Hawaiian Standard Time", + abbr: "HST", + offset: -10, + isdst: false, + text: "(UTC-10:00) Hawaii", + utc: ["Etc/GMT+10", "Pacific/Honolulu", "Pacific/Johnston", "Pacific/Rarotonga", "Pacific/Tahiti"] + }, + { + value: "Alaskan Standard Time", + abbr: "AKDT", + offset: -8, + isdst: true, + text: "(UTC-09:00) Alaska", + utc: ["America/Anchorage", "America/Juneau", "America/Nome", "America/Sitka", "America/Yakutat"] + }, + { + value: "Pacific Standard Time (Mexico)", + abbr: "PDT", + offset: -7, + isdst: true, + text: "(UTC-08:00) Baja California", + utc: ["America/Santa_Isabel"] + }, + { + value: "Pacific Daylight Time", + abbr: "PDT", + offset: -7, + isdst: true, + text: "(UTC-07:00) Pacific Daylight Time (US & Canada)", + utc: ["America/Los_Angeles", "America/Tijuana", "America/Vancouver"] + }, + { + value: "Pacific Standard Time", + abbr: "PST", + offset: -8, + isdst: false, + text: "(UTC-08:00) Pacific Standard Time (US & Canada)", + utc: ["America/Los_Angeles", "America/Tijuana", "America/Vancouver", "PST8PDT"] + }, + { + value: "US Mountain Standard Time", + abbr: "UMST", + offset: -7, + isdst: false, + text: "(UTC-07:00) Arizona", + utc: [ + "America/Creston", + "America/Dawson", + "America/Dawson_Creek", + "America/Hermosillo", + "America/Phoenix", + "America/Whitehorse", + "Etc/GMT+7" + ] + }, + { + value: "Mountain Standard Time (Mexico)", + abbr: "MDT", + offset: -6, + isdst: true, + text: "(UTC-07:00) Chihuahua, La Paz, Mazatlan", + utc: ["America/Chihuahua", "America/Mazatlan"] + }, + { + value: "Mountain Standard Time", + abbr: "MDT", + offset: -6, + isdst: true, + text: "(UTC-07:00) Mountain Time (US & Canada)", + utc: [ + "America/Boise", + "America/Cambridge_Bay", + "America/Denver", + "America/Edmonton", + "America/Inuvik", + "America/Ojinaga", + "America/Yellowknife", + "MST7MDT" + ] + }, + { + value: "Central America Standard Time", + abbr: "CAST", + offset: -6, + isdst: false, + text: "(UTC-06:00) Central America", + utc: [ + "America/Belize", + "America/Costa_Rica", + "America/El_Salvador", + "America/Guatemala", + "America/Managua", + "America/Tegucigalpa", + "Etc/GMT+6", + "Pacific/Galapagos" + ] + }, + { + value: "Central Standard Time", + abbr: "CDT", + offset: -5, + isdst: true, + text: "(UTC-06:00) Central Time (US & Canada)", + utc: [ + "America/Chicago", + "America/Indiana/Knox", + "America/Indiana/Tell_City", + "America/Matamoros", + "America/Menominee", + "America/North_Dakota/Beulah", + "America/North_Dakota/Center", + "America/North_Dakota/New_Salem", + "America/Rainy_River", + "America/Rankin_Inlet", + "America/Resolute", + "America/Winnipeg", + "CST6CDT" + ] + }, + { + value: "Central Standard Time (Mexico)", + abbr: "CDT", + offset: -5, + isdst: true, + text: "(UTC-06:00) Guadalajara, Mexico City, Monterrey", + utc: ["America/Bahia_Banderas", "America/Cancun", "America/Merida", "America/Mexico_City", "America/Monterrey"] + }, + { + value: "Canada Central Standard Time", + abbr: "CCST", + offset: -6, + isdst: false, + text: "(UTC-06:00) Saskatchewan", + utc: ["America/Regina", "America/Swift_Current"] + }, + { + value: "SA Pacific Standard Time", + abbr: "SPST", + offset: -5, + isdst: false, + text: "(UTC-05:00) Bogota, Lima, Quito", + utc: [ + "America/Bogota", + "America/Cayman", + "America/Coral_Harbour", + "America/Eirunepe", + "America/Guayaquil", + "America/Jamaica", + "America/Lima", + "America/Panama", + "America/Rio_Branco", + "Etc/GMT+5" + ] + }, + { + value: "Eastern Standard Time", + abbr: "EST", + offset: -5, + isdst: false, + text: "(UTC-05:00) Eastern Time (US & Canada)", + utc: [ + "America/Detroit", + "America/Havana", + "America/Indiana/Petersburg", + "America/Indiana/Vincennes", + "America/Indiana/Winamac", + "America/Iqaluit", + "America/Kentucky/Monticello", + "America/Louisville", + "America/Montreal", + "America/Nassau", + "America/New_York", + "America/Nipigon", + "America/Pangnirtung", + "America/Port-au-Prince", + "America/Thunder_Bay", + "America/Toronto" + ] + }, + { + value: "Eastern Daylight Time", + abbr: "EDT", + offset: -4, + isdst: true, + text: "(UTC-04:00) Eastern Daylight Time (US & Canada)", + utc: [ + "America/Detroit", + "America/Havana", + "America/Indiana/Petersburg", + "America/Indiana/Vincennes", + "America/Indiana/Winamac", + "America/Iqaluit", + "America/Kentucky/Monticello", + "America/Louisville", + "America/Montreal", + "America/Nassau", + "America/New_York", + "America/Nipigon", + "America/Pangnirtung", + "America/Port-au-Prince", + "America/Thunder_Bay", + "America/Toronto" + ] + }, + { + value: "US Eastern Standard Time", + abbr: "UEDT", + offset: -5, + isdst: false, + text: "(UTC-05:00) Indiana (East)", + utc: ["America/Indiana/Marengo", "America/Indiana/Vevay", "America/Indianapolis"] + }, + { + value: "Venezuela Standard Time", + abbr: "VST", + offset: -4.5, + isdst: false, + text: "(UTC-04:30) Caracas", + utc: ["America/Caracas"] + }, + { + value: "Paraguay Standard Time", + abbr: "PYT", + offset: -4, + isdst: false, + text: "(UTC-04:00) Asuncion", + utc: ["America/Asuncion"] + }, + { + value: "Atlantic Standard Time", + abbr: "ADT", + offset: -3, + isdst: true, + text: "(UTC-04:00) Atlantic Time (Canada)", + utc: [ + "America/Glace_Bay", + "America/Goose_Bay", + "America/Halifax", + "America/Moncton", + "America/Thule", + "Atlantic/Bermuda" + ] + }, + { + value: "Central Brazilian Standard Time", + abbr: "CBST", + offset: -4, + isdst: false, + text: "(UTC-04:00) Cuiaba", + utc: ["America/Campo_Grande", "America/Cuiaba"] + }, + { + value: "SA Western Standard Time", + abbr: "SWST", + offset: -4, + isdst: false, + text: "(UTC-04:00) Georgetown, La Paz, Manaus, San Juan", + utc: [ + "America/Anguilla", + "America/Antigua", + "America/Aruba", + "America/Barbados", + "America/Blanc-Sablon", + "America/Boa_Vista", + "America/Curacao", + "America/Dominica", + "America/Grand_Turk", + "America/Grenada", + "America/Guadeloupe", + "America/Guyana", + "America/Kralendijk", + "America/La_Paz", + "America/Lower_Princes", + "America/Manaus", + "America/Marigot", + "America/Martinique", + "America/Montserrat", + "America/Port_of_Spain", + "America/Porto_Velho", + "America/Puerto_Rico", + "America/Santo_Domingo", + "America/St_Barthelemy", + "America/St_Kitts", + "America/St_Lucia", + "America/St_Thomas", + "America/St_Vincent", + "America/Tortola", + "Etc/GMT+4" + ] + }, + { + value: "Pacific SA Standard Time", + abbr: "PSST", + offset: -4, + isdst: false, + text: "(UTC-04:00) Santiago", + utc: ["America/Santiago", "Antarctica/Palmer"] + }, + { + value: "Newfoundland Standard Time", + abbr: "NDT", + offset: -2.5, + isdst: true, + text: "(UTC-03:30) Newfoundland", + utc: ["America/St_Johns"] + }, + { + value: "E. South America Standard Time", + abbr: "ESAST", + offset: -3, + isdst: false, + text: "(UTC-03:00) Brasilia", + utc: ["America/Sao_Paulo"] + }, + { + value: "Argentina Standard Time", + abbr: "AST", + offset: -3, + isdst: false, + text: "(UTC-03:00) Buenos Aires", + utc: [ + "America/Argentina/La_Rioja", + "America/Argentina/Rio_Gallegos", + "America/Argentina/Salta", + "America/Argentina/San_Juan", + "America/Argentina/San_Luis", + "America/Argentina/Tucuman", + "America/Argentina/Ushuaia", + "America/Buenos_Aires", + "America/Catamarca", + "America/Cordoba", + "America/Jujuy", + "America/Mendoza" + ] + }, + { + value: "SA Eastern Standard Time", + abbr: "SEST", + offset: -3, + isdst: false, + text: "(UTC-03:00) Cayenne, Fortaleza", + utc: [ + "America/Araguaina", + "America/Belem", + "America/Cayenne", + "America/Fortaleza", + "America/Maceio", + "America/Paramaribo", + "America/Recife", + "America/Santarem", + "Antarctica/Rothera", + "Atlantic/Stanley", + "Etc/GMT+3" + ] + }, + { + value: "Greenland Standard Time", + abbr: "GDT", + offset: -3, + isdst: true, + text: "(UTC-03:00) Greenland", + utc: ["America/Godthab"] + }, + { + value: "Montevideo Standard Time", + abbr: "MST", + offset: -3, + isdst: false, + text: "(UTC-03:00) Montevideo", + utc: ["America/Montevideo"] + }, + { + value: "Bahia Standard Time", + abbr: "BST", + offset: -3, + isdst: false, + text: "(UTC-03:00) Salvador", + utc: ["America/Bahia"] + }, + { + value: "UTC-02", + abbr: "U", + offset: -2, + isdst: false, + text: "(UTC-02:00) Coordinated Universal Time-02", + utc: ["America/Noronha", "Atlantic/South_Georgia", "Etc/GMT+2"] + }, + { + value: "Mid-Atlantic Standard Time", + abbr: "MDT", + offset: -1, + isdst: true, + text: "(UTC-02:00) Mid-Atlantic - Old", + utc: [] + }, + { + value: "Azores Standard Time", + abbr: "ADT", + offset: 0, + isdst: true, + text: "(UTC-01:00) Azores", + utc: ["America/Scoresbysund", "Atlantic/Azores"] + }, + { + value: "Cape Verde Standard Time", + abbr: "CVST", + offset: -1, + isdst: false, + text: "(UTC-01:00) Cape Verde Is.", + utc: ["Atlantic/Cape_Verde", "Etc/GMT+1"] + }, + { + value: "Morocco Standard Time", + abbr: "MDT", + offset: 1, + isdst: true, + text: "(UTC) Casablanca", + utc: ["Africa/Casablanca", "Africa/El_Aaiun"] + }, + { + value: "UTC", + abbr: "UTC", + offset: 0, + isdst: false, + text: "(UTC) Coordinated Universal Time", + utc: ["America/Danmarkshavn", "Etc/GMT"] + }, + { + value: "GMT Standard Time", + abbr: "GMT", + offset: 0, + isdst: false, + text: "(UTC) Edinburgh, London", + utc: ["Europe/Isle_of_Man", "Europe/Guernsey", "Europe/Jersey", "Europe/London"] + }, + { + value: "British Summer Time", + abbr: "BST", + offset: 1, + isdst: true, + text: "(UTC+01:00) Edinburgh, London", + utc: ["Europe/Isle_of_Man", "Europe/Guernsey", "Europe/Jersey", "Europe/London"] + }, + { + value: "GMT Standard Time", + abbr: "GDT", + offset: 1, + isdst: true, + text: "(UTC) Dublin, Lisbon", + utc: ["Atlantic/Canary", "Atlantic/Faeroe", "Atlantic/Madeira", "Europe/Dublin", "Europe/Lisbon"] + }, + { + value: "Greenwich Standard Time", + abbr: "GST", + offset: 0, + isdst: false, + text: "(UTC) Monrovia, Reykjavik", + utc: [ + "Africa/Abidjan", + "Africa/Accra", + "Africa/Bamako", + "Africa/Banjul", + "Africa/Bissau", + "Africa/Conakry", + "Africa/Dakar", + "Africa/Freetown", + "Africa/Lome", + "Africa/Monrovia", + "Africa/Nouakchott", + "Africa/Ouagadougou", + "Africa/Sao_Tome", + "Atlantic/Reykjavik", + "Atlantic/St_Helena" + ] + }, + { + value: "W. Europe Standard Time", + abbr: "WEDT", + offset: 2, + isdst: true, + text: "(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna", + utc: [ + "Arctic/Longyearbyen", + "Europe/Amsterdam", + "Europe/Andorra", + "Europe/Berlin", + "Europe/Busingen", + "Europe/Gibraltar", + "Europe/Luxembourg", + "Europe/Malta", + "Europe/Monaco", + "Europe/Oslo", + "Europe/Rome", + "Europe/San_Marino", + "Europe/Stockholm", + "Europe/Vaduz", + "Europe/Vatican", + "Europe/Vienna", + "Europe/Zurich" + ] + }, + { + value: "Central Europe Standard Time", + abbr: "CEDT", + offset: 2, + isdst: true, + text: "(UTC+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague", + utc: [ + "Europe/Belgrade", + "Europe/Bratislava", + "Europe/Budapest", + "Europe/Ljubljana", + "Europe/Podgorica", + "Europe/Prague", + "Europe/Tirane" + ] + }, + { + value: "Romance Standard Time", + abbr: "RDT", + offset: 2, + isdst: true, + text: "(UTC+01:00) Brussels, Copenhagen, Madrid, Paris", + utc: ["Africa/Ceuta", "Europe/Brussels", "Europe/Copenhagen", "Europe/Madrid", "Europe/Paris"] + }, + { + value: "Central European Standard Time", + abbr: "CEDT", + offset: 2, + isdst: true, + text: "(UTC+01:00) Sarajevo, Skopje, Warsaw, Zagreb", + utc: ["Europe/Sarajevo", "Europe/Skopje", "Europe/Warsaw", "Europe/Zagreb"] + }, + { + value: "W. Central Africa Standard Time", + abbr: "WCAST", + offset: 1, + isdst: false, + text: "(UTC+01:00) West Central Africa", + utc: [ + "Africa/Algiers", + "Africa/Bangui", + "Africa/Brazzaville", + "Africa/Douala", + "Africa/Kinshasa", + "Africa/Lagos", + "Africa/Libreville", + "Africa/Luanda", + "Africa/Malabo", + "Africa/Ndjamena", + "Africa/Niamey", + "Africa/Porto-Novo", + "Africa/Tunis", + "Etc/GMT-1" + ] + }, + { + value: "Namibia Standard Time", + abbr: "NST", + offset: 1, + isdst: false, + text: "(UTC+01:00) Windhoek", + utc: ["Africa/Windhoek"] + }, + { + value: "GTB Standard Time", + abbr: "GDT", + offset: 3, + isdst: true, + text: "(UTC+02:00) Athens, Bucharest", + utc: ["Asia/Nicosia", "Europe/Athens", "Europe/Bucharest", "Europe/Chisinau"] + }, + { + value: "Middle East Standard Time", + abbr: "MEDT", + offset: 3, + isdst: true, + text: "(UTC+02:00) Beirut", + utc: ["Asia/Beirut"] + }, + { + value: "Egypt Standard Time", + abbr: "EST", + offset: 2, + isdst: false, + text: "(UTC+02:00) Cairo", + utc: ["Africa/Cairo"] + }, + { + value: "Syria Standard Time", + abbr: "SDT", + offset: 3, + isdst: true, + text: "(UTC+02:00) Damascus", + utc: ["Asia/Damascus"] + }, + { + value: "E. Europe Standard Time", + abbr: "EEDT", + offset: 3, + isdst: true, + text: "(UTC+02:00) E. Europe", + utc: [ + "Asia/Nicosia", + "Europe/Athens", + "Europe/Bucharest", + "Europe/Chisinau", + "Europe/Helsinki", + "Europe/Kiev", + "Europe/Mariehamn", + "Europe/Nicosia", + "Europe/Riga", + "Europe/Sofia", + "Europe/Tallinn", + "Europe/Uzhgorod", + "Europe/Vilnius", + "Europe/Zaporozhye" + ] + }, + { + value: "South Africa Standard Time", + abbr: "SAST", + offset: 2, + isdst: false, + text: "(UTC+02:00) Harare, Pretoria", + utc: [ + "Africa/Blantyre", + "Africa/Bujumbura", + "Africa/Gaborone", + "Africa/Harare", + "Africa/Johannesburg", + "Africa/Kigali", + "Africa/Lubumbashi", + "Africa/Lusaka", + "Africa/Maputo", + "Africa/Maseru", + "Africa/Mbabane", + "Etc/GMT-2" + ] + }, + { + value: "FLE Standard Time", + abbr: "FDT", + offset: 3, + isdst: true, + text: "(UTC+02:00) Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius", + utc: [ + "Europe/Helsinki", + "Europe/Kiev", + "Europe/Mariehamn", + "Europe/Riga", + "Europe/Sofia", + "Europe/Tallinn", + "Europe/Uzhgorod", + "Europe/Vilnius", + "Europe/Zaporozhye" + ] + }, + { + value: "Turkey Standard Time", + abbr: "TDT", + offset: 3, + isdst: false, + text: "(UTC+03:00) Istanbul", + utc: ["Europe/Istanbul"] + }, + { + value: "Israel Standard Time", + abbr: "JDT", + offset: 3, + isdst: true, + text: "(UTC+02:00) Jerusalem", + utc: ["Asia/Jerusalem"] + }, + { + value: "Libya Standard Time", + abbr: "LST", + offset: 2, + isdst: false, + text: "(UTC+02:00) Tripoli", + utc: ["Africa/Tripoli"] + }, + { + value: "Jordan Standard Time", + abbr: "JST", + offset: 3, + isdst: false, + text: "(UTC+03:00) Amman", + utc: ["Asia/Amman"] + }, + { + value: "Arabic Standard Time", + abbr: "AST", + offset: 3, + isdst: false, + text: "(UTC+03:00) Baghdad", + utc: ["Asia/Baghdad"] + }, + { + value: "Kaliningrad Standard Time", + abbr: "KST", + offset: 3, + isdst: false, + text: "(UTC+02:00) Kaliningrad", + utc: ["Europe/Kaliningrad"] + }, + { + value: "Arab Standard Time", + abbr: "AST", + offset: 3, + isdst: false, + text: "(UTC+03:00) Kuwait, Riyadh", + utc: ["Asia/Aden", "Asia/Bahrain", "Asia/Kuwait", "Asia/Qatar", "Asia/Riyadh"] + }, + { + value: "E. Africa Standard Time", + abbr: "EAST", + offset: 3, + isdst: false, + text: "(UTC+03:00) Nairobi", + utc: [ + "Africa/Addis_Ababa", + "Africa/Asmera", + "Africa/Dar_es_Salaam", + "Africa/Djibouti", + "Africa/Juba", + "Africa/Kampala", + "Africa/Khartoum", + "Africa/Mogadishu", + "Africa/Nairobi", + "Antarctica/Syowa", + "Etc/GMT-3", + "Indian/Antananarivo", + "Indian/Comoro", + "Indian/Mayotte" + ] + }, + { + value: "Moscow Standard Time", + abbr: "MSK", + offset: 3, + isdst: false, + text: "(UTC+03:00) Moscow, St. Petersburg, Volgograd, Minsk", + utc: ["Europe/Kirov", "Europe/Moscow", "Europe/Simferopol", "Europe/Volgograd", "Europe/Minsk"] + }, + { + value: "Samara Time", + abbr: "SAMT", + offset: 4, + isdst: false, + text: "(UTC+04:00) Samara, Ulyanovsk, Saratov", + utc: ["Europe/Astrakhan", "Europe/Samara", "Europe/Ulyanovsk"] + }, + { + value: "Iran Standard Time", + abbr: "IDT", + offset: 4.5, + isdst: true, + text: "(UTC+03:30) Tehran", + utc: ["Asia/Tehran"] + }, + { + value: "Arabian Standard Time", + abbr: "AST", + offset: 4, + isdst: false, + text: "(UTC+04:00) Abu Dhabi, Muscat", + utc: ["Asia/Dubai", "Asia/Muscat", "Etc/GMT-4"] + }, + { + value: "Azerbaijan Standard Time", + abbr: "ADT", + offset: 5, + isdst: true, + text: "(UTC+04:00) Baku", + utc: ["Asia/Baku"] + }, + { + value: "Mauritius Standard Time", + abbr: "MST", + offset: 4, + isdst: false, + text: "(UTC+04:00) Port Louis", + utc: ["Indian/Mahe", "Indian/Mauritius", "Indian/Reunion"] + }, + { + value: "Georgian Standard Time", + abbr: "GET", + offset: 4, + isdst: false, + text: "(UTC+04:00) Tbilisi", + utc: ["Asia/Tbilisi"] + }, + { + value: "Caucasus Standard Time", + abbr: "CST", + offset: 4, + isdst: false, + text: "(UTC+04:00) Yerevan", + utc: ["Asia/Yerevan"] + }, + { + value: "Afghanistan Standard Time", + abbr: "AST", + offset: 4.5, + isdst: false, + text: "(UTC+04:30) Kabul", + utc: ["Asia/Kabul"] + }, + { + value: "West Asia Standard Time", + abbr: "WAST", + offset: 5, + isdst: false, + text: "(UTC+05:00) Ashgabat, Tashkent", + utc: [ + "Antarctica/Mawson", + "Asia/Aqtau", + "Asia/Aqtobe", + "Asia/Ashgabat", + "Asia/Dushanbe", + "Asia/Oral", + "Asia/Samarkand", + "Asia/Tashkent", + "Etc/GMT-5", + "Indian/Kerguelen", + "Indian/Maldives" + ] + }, + { + value: "Yekaterinburg Time", + abbr: "YEKT", + offset: 5, + isdst: false, + text: "(UTC+05:00) Yekaterinburg", + utc: ["Asia/Yekaterinburg"] + }, + { + value: "Pakistan Standard Time", + abbr: "PKT", + offset: 5, + isdst: false, + text: "(UTC+05:00) Islamabad, Karachi", + utc: ["Asia/Karachi"] + }, + { + value: "India Standard Time", + abbr: "IST", + offset: 5.5, + isdst: false, + text: "(UTC+05:30) Chennai, Kolkata, Mumbai, New Delhi", + utc: ["Asia/Kolkata", "Asia/Calcutta"] + }, + { + value: "Sri Lanka Standard Time", + abbr: "SLST", + offset: 5.5, + isdst: false, + text: "(UTC+05:30) Sri Jayawardenepura", + utc: ["Asia/Colombo"] + }, + { + value: "Nepal Standard Time", + abbr: "NST", + offset: 5.75, + isdst: false, + text: "(UTC+05:45) Kathmandu", + utc: ["Asia/Kathmandu"] + }, + { + value: "Central Asia Standard Time", + abbr: "CAST", + offset: 6, + isdst: false, + text: "(UTC+06:00) Nur-Sultan (Astana)", + utc: [ + "Antarctica/Vostok", + "Asia/Almaty", + "Asia/Bishkek", + "Asia/Qyzylorda", + "Asia/Urumqi", + "Etc/GMT-6", + "Indian/Chagos" + ] + }, + { + value: "Bangladesh Standard Time", + abbr: "BST", + offset: 6, + isdst: false, + text: "(UTC+06:00) Dhaka", + utc: ["Asia/Dhaka", "Asia/Thimphu"] + }, + { + value: "Myanmar Standard Time", + abbr: "MST", + offset: 6.5, + isdst: false, + text: "(UTC+06:30) Yangon (Rangoon)", + utc: ["Asia/Rangoon", "Indian/Cocos"] + }, + { + value: "SE Asia Standard Time", + abbr: "SAST", + offset: 7, + isdst: false, + text: "(UTC+07:00) Bangkok, Hanoi, Jakarta", + utc: [ + "Antarctica/Davis", + "Asia/Bangkok", + "Asia/Hovd", + "Asia/Jakarta", + "Asia/Phnom_Penh", + "Asia/Pontianak", + "Asia/Saigon", + "Asia/Vientiane", + "Etc/GMT-7", + "Indian/Christmas" + ] + }, + { + value: "N. Central Asia Standard Time", + abbr: "NCAST", + offset: 7, + isdst: false, + text: "(UTC+07:00) Novosibirsk", + utc: ["Asia/Novokuznetsk", "Asia/Novosibirsk", "Asia/Omsk"] + }, + { + value: "China Standard Time", + abbr: "CST", + offset: 8, + isdst: false, + text: "(UTC+08:00) Beijing, Chongqing, Hong Kong, Urumqi", + utc: ["Asia/Hong_Kong", "Asia/Macau", "Asia/Shanghai"] + }, + { + value: "North Asia Standard Time", + abbr: "NAST", + offset: 8, + isdst: false, + text: "(UTC+08:00) Krasnoyarsk", + utc: ["Asia/Krasnoyarsk"] + }, + { + value: "Singapore Standard Time", + abbr: "MPST", + offset: 8, + isdst: false, + text: "(UTC+08:00) Kuala Lumpur, Singapore", + utc: [ + "Asia/Brunei", + "Asia/Kuala_Lumpur", + "Asia/Kuching", + "Asia/Makassar", + "Asia/Manila", + "Asia/Singapore", + "Etc/GMT-8" + ] + }, + { + value: "W. Australia Standard Time", + abbr: "WAST", + offset: 8, + isdst: false, + text: "(UTC+08:00) Perth", + utc: ["Antarctica/Casey", "Australia/Perth"] + }, + { + value: "Taipei Standard Time", + abbr: "TST", + offset: 8, + isdst: false, + text: "(UTC+08:00) Taipei", + utc: ["Asia/Taipei"] + }, + { + value: "Ulaanbaatar Standard Time", + abbr: "UST", + offset: 8, + isdst: false, + text: "(UTC+08:00) Ulaanbaatar", + utc: ["Asia/Choibalsan", "Asia/Ulaanbaatar"] + }, + { + value: "North Asia East Standard Time", + abbr: "NAEST", + offset: 8, + isdst: false, + text: "(UTC+08:00) Irkutsk", + utc: ["Asia/Irkutsk"] + }, + { + value: "Japan Standard Time", + abbr: "JST", + offset: 9, + isdst: false, + text: "(UTC+09:00) Osaka, Sapporo, Tokyo", + utc: ["Asia/Dili", "Asia/Jayapura", "Asia/Tokyo", "Etc/GMT-9", "Pacific/Palau"] + }, + { + value: "Korea Standard Time", + abbr: "KST", + offset: 9, + isdst: false, + text: "(UTC+09:00) Seoul", + utc: ["Asia/Pyongyang", "Asia/Seoul"] + }, + { + value: "Cen. Australia Standard Time", + abbr: "CAST", + offset: 9.5, + isdst: false, + text: "(UTC+09:30) Adelaide", + utc: ["Australia/Adelaide", "Australia/Broken_Hill"] + }, + { + value: "AUS Central Standard Time", + abbr: "ACST", + offset: 9.5, + isdst: false, + text: "(UTC+09:30) Darwin", + utc: ["Australia/Darwin"] + }, + { + value: "E. Australia Standard Time", + abbr: "EAST", + offset: 10, + isdst: false, + text: "(UTC+10:00) Brisbane", + utc: ["Australia/Brisbane", "Australia/Lindeman"] + }, + { + value: "AUS Eastern Standard Time", + abbr: "AEST", + offset: 10, + isdst: false, + text: "(UTC+10:00) Canberra, Melbourne, Sydney", + utc: ["Australia/Melbourne", "Australia/Sydney"] + }, + { + value: "West Pacific Standard Time", + abbr: "WPST", + offset: 10, + isdst: false, + text: "(UTC+10:00) Guam, Port Moresby", + utc: [ + "Antarctica/DumontDUrville", + "Etc/GMT-10", + "Pacific/Guam", + "Pacific/Port_Moresby", + "Pacific/Saipan", + "Pacific/Truk" + ] + }, + { + value: "Tasmania Standard Time", + abbr: "TST", + offset: 10, + isdst: false, + text: "(UTC+10:00) Hobart", + utc: ["Australia/Currie", "Australia/Hobart"] + }, + { + value: "Yakutsk Standard Time", + abbr: "YST", + offset: 9, + isdst: false, + text: "(UTC+09:00) Yakutsk", + utc: ["Asia/Chita", "Asia/Khandyga", "Asia/Yakutsk"] + }, + { + value: "Central Pacific Standard Time", + abbr: "CPST", + offset: 11, + isdst: false, + text: "(UTC+11:00) Solomon Is., New Caledonia", + utc: [ + "Antarctica/Macquarie", + "Etc/GMT-11", + "Pacific/Efate", + "Pacific/Guadalcanal", + "Pacific/Kosrae", + "Pacific/Noumea", + "Pacific/Ponape" + ] + }, + { + value: "Vladivostok Standard Time", + abbr: "VST", + offset: 11, + isdst: false, + text: "(UTC+11:00) Vladivostok", + utc: ["Asia/Sakhalin", "Asia/Ust-Nera", "Asia/Vladivostok"] + }, + { + value: "New Zealand Standard Time", + abbr: "NZST", + offset: 12, + isdst: false, + text: "(UTC+12:00) Auckland, Wellington", + utc: ["Antarctica/McMurdo", "Pacific/Auckland"] + }, + { + value: "UTC+12", + abbr: "U", + offset: 12, + isdst: false, + text: "(UTC+12:00) Coordinated Universal Time+12", + utc: [ + "Etc/GMT-12", + "Pacific/Funafuti", + "Pacific/Kwajalein", + "Pacific/Majuro", + "Pacific/Nauru", + "Pacific/Tarawa", + "Pacific/Wake", + "Pacific/Wallis" + ] + }, + { + value: "Fiji Standard Time", + abbr: "FST", + offset: 12, + isdst: false, + text: "(UTC+12:00) Fiji", + utc: ["Pacific/Fiji"] + }, + { + value: "Magadan Standard Time", + abbr: "MST", + offset: 12, + isdst: false, + text: "(UTC+12:00) Magadan", + utc: ["Asia/Anadyr", "Asia/Kamchatka", "Asia/Magadan", "Asia/Srednekolymsk"] + }, + { + value: "Kamchatka Standard Time", + abbr: "KDT", + offset: 13, + isdst: true, + text: "(UTC+12:00) Petropavlovsk-Kamchatsky - Old", + utc: ["Asia/Kamchatka"] + }, + { + value: "Tonga Standard Time", + abbr: "TST", + offset: 13, + isdst: false, + text: "(UTC+13:00) Nuku'alofa", + utc: ["Etc/GMT-13", "Pacific/Enderbury", "Pacific/Fakaofo", "Pacific/Tongatapu"] + }, + { + value: "Samoa Standard Time", + abbr: "SST", + offset: 13, + isdst: false, + text: "(UTC+13:00) Samoa", + utc: ["Pacific/Apia"] + } +]; diff --git a/lib/utils/toast-trigger.ts b/lib/utils/toast-trigger.ts new file mode 100644 index 000000000..2b3818237 --- /dev/null +++ b/lib/utils/toast-trigger.ts @@ -0,0 +1,25 @@ +import toast from "react-hot-toast"; + +export declare interface ToastTriggerProps { + message: string; + type: "success" | "error" | "custom" | ""; +} + +// notifier function trigger +export const ToastTrigger = ({ message, type }: ToastTriggerProps) => { + switch (type) { + case "success": + toast.success(message); + break; + case "error": + toast.error(message); + break; + + // pass custom type only if your message is a jsx template + case "custom": + toast.custom(message); + break; + default: + toast(message); + } +}; \ No newline at end of file diff --git a/lib/utils/validate-email.ts b/lib/utils/validate-email.ts new file mode 100644 index 000000000..0c576a2f3 --- /dev/null +++ b/lib/utils/validate-email.ts @@ -0,0 +1,7 @@ +export const validateEmail = (email: string) => { + return String(email) + .toLowerCase() + .match( + /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ + ); +}; diff --git a/next-types.d.ts b/next-types.d.ts index 72537c480..b1d9aed7d 100644 --- a/next-types.d.ts +++ b/next-types.d.ts @@ -110,6 +110,7 @@ interface DbUserInsightRepo { } interface DbUser { + readonly email: string; readonly id: number; readonly open_issues: number; readonly is_private: boolean; @@ -120,4 +121,12 @@ interface DbUser { readonly is_onboarded: boolean; readonly is_waitlisted: boolean; readonly role: number; + readonly name: string; + readonly location: string; + readonly twitter_username: string; + readonly company: string; + readonly bio: string; + readonly interests: string; + readonly receive_collaboration: boolean; + readonly display_email: boolean; } diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 9be41b398..24070093c 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -42,6 +42,7 @@ "react": "^18.2.0", "react-csv": "^2.2.2", "react-dom": "^18.2.0", + "react-hot-toast": "^2.4.0", "react-icons": "^4.4.0", "react-loading-skeleton": "^3.1.0", "react-spring": "^9.5.5", @@ -21889,6 +21890,14 @@ "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", "dev": true }, + "node_modules/goober": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.11.tgz", + "integrity": "sha512-5SS2lmxbhqH0u9ABEWq7WPU69a4i2pYcHeCxqaNq6Cw3mnrF0ghWNM4tEGid4dKy8XNIAUbuThuozDHHKJVh3A==", + "peerDependencies": { + "csstype": "^3.0.10" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -29050,6 +29059,21 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, + "node_modules/react-hot-toast": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.4.0.tgz", + "integrity": "sha512-qnnVbXropKuwUpriVVosgo8QrB+IaPJCpL8oBI6Ov84uvHZ5QQcTp2qg6ku2wNfgJl6rlQXJIQU5q+5lmPOutA==", + "dependencies": { + "goober": "^2.1.10" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, "node_modules/react-icons": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.4.0.tgz", diff --git a/package.json b/package.json index 9945906ff..b911d978c 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "react": "^18.2.0", "react-csv": "^2.2.2", "react-dom": "^18.2.0", + "react-hot-toast": "^2.4.0", "react-icons": "^4.4.0", "react-loading-skeleton": "^3.1.0", "react-spring": "^9.5.5", diff --git a/pages/_app.tsx b/pages/_app.tsx index 6d875f08b..993be9867 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -17,6 +17,7 @@ import changeCapitalization from "lib/utils/change-capitalization"; import apiFetcher from "lib/hooks/useSWR"; import { initiateAnalytics } from "lib/utils/analytics"; import { supabase } from "lib/utils/supabase"; +import { Toaster } from "react-hot-toast"; type ComponentWithPageLayout = AppProps & { Component: AppProps["Component"] & { @@ -99,6 +100,7 @@ function MyApp({ Component, pageProps }: ComponentWithPageLayout) { provider: localStorageProvider }} > + {Component.PageLayout ? ( diff --git a/pages/user/settings.tsx b/pages/user/settings.tsx new file mode 100644 index 000000000..2f11a98b2 --- /dev/null +++ b/pages/user/settings.tsx @@ -0,0 +1,23 @@ +import useSupabaseAuth from "lib/hooks/useSupabaseAuth"; + +import UserSettingsPage from "components/organisms/UserSettingsPage/user-settings-page"; +import ProfileLayout from "layouts/profile"; + +const ProfileSettings = (): JSX.Element => { + const { user } = useSupabaseAuth(); + + return ( + <> + {user ? ( +
+ +
+ ) : ( + "" + )} + + ); +}; + +ProfileSettings.PageLayout = ProfileLayout; +export default ProfileSettings; diff --git a/stories/organisms/user-settings-page.stories.tsx b/stories/organisms/user-settings-page.stories.tsx index 2a6e554a3..e579832b7 100644 --- a/stories/organisms/user-settings-page.stories.tsx +++ b/stories/organisms/user-settings-page.stories.tsx @@ -6,6 +6,6 @@ const StoryConfig = { }; export default StoryConfig; -const UserSettingsPageTemplate: ComponentStory = () => ; +const UserSettingsPageTemplate: ComponentStory = () => ; export const Default = UserSettingsPageTemplate.bind({});