diff --git a/.cspell.json b/.cspell.json index 7d1376961..f35fdc724 100644 --- a/.cspell.json +++ b/.cspell.json @@ -1,377 +1,378 @@ { - "version": "0.2", - "language": "en", - "caseSensitive": false, - "$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json", - "words": [ - "appdev", - "adipiscing", - "amet", - "aliqua", - "signin", - "APPSTORE", - "barcodes", - "binutils", - "buildjet", - "cacheable", - "camelcase", - "Chatwoot", - "chetwode", - "cloc", - "cloudinary", - "clsx", - "clsxm", - "opentelemetry", - "otlp", - "commitlint", - "DONT", - "greenkeeper", - "classpath", - "tsbuildinfo", - "sentryclirc", - "compodoc", - "consectetur", - "dolor", - "dolore", - "dummyimage", - "eiusmod", - "elit", - "envalid", - "everco", - "everteamsdesktop", - "exposdk", - "gcloud", - "graphicsmagick", - "gtag", - "headlessui", - "heroicons", - "Huhn", - "icnsutils", - "incididunt", - "isdragging", - "isdraggingfrom", - "isdropdisabled", - "ipsum", - "JITSU", - "kanban", - "kanbandata", - "Lorem", - "libappindicator", - "lucide", - "mathieudutour", - "ncipollo", - "nextjs", - "passcode", - "plasmo", - "precommit", - "RECAPTCHA", - "setuptools", - "setwin", - "snyk", - "stylelint", - "svgs", - "Tailess", - "tailess", - "tailwindcss", - "testid", - "Timesheet", - "tanstack", - "taskstatus", - "tempor", - "vcpu", - "Vercel", - "HUBSTAFF", - "UPWORK", - "runned", - "Timeslot", - "Isssue", - "datas", - "Changemail", - "Lask", - "publicactive", - "Formated", - "Btns", - "RESERVERD", - "shandow", - "UIUX", - "xlight", - "domutils", - "domhandler", - "hyperscript", - "nocheck", - "locatio", - "labore", - "falsey", - "unhang", - "popperjs", - "Isssue", - "inital", - "FULLNAME", - "extramenu", - "iuser", - "Pourtcent", - "Reconds", - "Pourtcent", - "combx", - "fomated", - "Hanlder", - "cmdk", - "sitekey", - "Loadtasks", - "Accordian", - "lgcard", - "dvalue", - "Codacy", - "codecov", - "huntr", - "Gitter", - "shadcn", - "Repobeats", - "Codementor", - "xlcard", - "wght", - "worksace", - "appkey", - "jitsi", - "accepte", - "Parens", - "pako", - "embla", - "excalidraw", - "Lngs", - "Transpiles", - "wasabisys", - "apistage", - "flaticon", - "VERSONS", - "vertificalline", - "Tongatapu", - "Moresby", - "Pago", - "Kosrae", - "Kiritimati", - "Fakaofo", - "Enderbury", - "Efate", - "Propf", - "mappagination", - "INAPP", - "INFOTMATION", - "nimg", - "strock", - "ISSUETYPE", - "borde", - "imlement", - "Invitatio", - "Synk", - "nimg", - "capitaliz", - "nimg", - "Settingfilter", - "recieve", - "Opena", - "TRANSFERT", - "choos", - "Darkmode", - "recieve", - "Vefified", - "Uturn", - "insted", - "Cmbx", - "hidde", - "invitationid", - "cheched", - "Dropown", - "imodal", - "Signle", - "Filder", - "outclick", - "Filder", - "skey", - "outclick", - "Xlarge", - "Permisson", - "noreferrer", - "errr", - "Instanciate", - "Varibales", - "ciphertext", - "discrepenancy", - "unoffic", - "implem", - "asel", - "Togger", - "Organizatio", - "Combox", - "unchild", - "signoff", - "Settingfilter", - "X", - "stackoverflow", - "payperiod", - "billrate", - "tnode", - "localstorage", - "millisencods", - "taskid", - "creatoe", - "setrole", - "lastest", - "immediatly", - "Verifiy", - "invdate", - "ianatz", - "uicolors", - "greppable", - "Andross", - "Bowser", - "Boilerplates", - "xcodeproj", - "gradlew", - "paren", - "iphonesimulator", - "xcworkspace", - "dropwdown", - "itask", - "xcodebuild", - "reactotron", - "fbjs", - "stylesheet", - "bootsplash", - "animatable", - "apisauce", - "grotesk", - "jsbundle", - "unimodules", - "mobx", - "typeof", - "loglevel", - "applesimutils", - "phraseapp", - "OSTYPE", - "pkill", - "yellowbox", - "miliseconds", - "Bugsnag", - "Neue", - "Defaul", - "Reactotron's", - "Worspace", - "Funtion", - "tinvitations", - "Authentificate", - "screenstatus", - "withteam", - "Invitions", - "lastlog", - "STMP", - "statut", - "statsus", - "simplecast", - "Ffeeds", - "smalltext", - "Pressible", - "Pressable", - "deserunt", - "longpress", - "endregion", - "checkcircleo", - "Entypo", - "Charaters", - "Ionicons", - "ellipsize", - "unasigned", - "progess", - "Icontent", - "arrowleft", - "Descrption", - "Swith", - "Chane", - "Plaholder", - "firstname", - "Isvalid", - "Chane", - "checkcircle", - "exclamationcircleo", - "contaniner", - "Galery", - "clockcircleo", - "filtmembers", - "comparision", - "Jamon", - "Chami", - "Mazen", - "Heinze", - "Kanbanboard", - "Kolkata", - "Holmgren", - "Jamon", - "Rickert", - "Metral", - "subsquently", - "Syle", - "teamtask", - "imagebutton", - "hwba", - "plasmohq", - "Proguard", - "horcrux", - "dimesions", - "Ordereds", - "uidotdev", - "usehooks", - "Personnal", - "SCREENSHOOTS", - "Screenshoot", - "screenshoots", - "tota", - "Intervall" - ], - "useGitignore": true, - "ignorePaths": [ - ".deploy/*", - ".git/*", - ".git/!{COMMIT_EDITMSG,EDITMSG}", - ".git/*/**", - ".yarn", - "**/*.jar", - ".pnp.js", - "**/.git/**", - ".vscode", - ".gitignore", - "action/lib/**", - "coverage", - ".cspell.json", - "cspell.json", - "__snapshots__", - "__recordings__", - "**/coverage/**", - "**/fixtures/**/*.json", - "**/fixtures/sampleCode/*errors/", - "**/node_modules/**", - "**/vscode-extension/**", - "package-lock.json", - "yarn.lock", - "**/assets/i18n/*.json", - "**/migrations/**", - "packages/**/*.seed.json", - "**/*.svg", - "tools/build/webpack.config.js", - "docker-compose.demo.yml", - "docker-compose.yml", - "wait", - "signin", - "Chatwoot", - "CHATWOOT", - "apps/web/messages/*.json", - "apps/web/public/locales/**", - "apps/web/lib/i18n/*.ts", - "apps/web/lib/settings/timezones.js", - "apps/mobile/app/screens/DemoShowroomScreen/demos/**", - "apps/mobile/app/i18n/*.ts", - "apps/mobile/android/**", - "apps/mobile/ios/**", - "apps/desktop/i18n/**", - "apps/**/*.{svg,css,scss}" - ] + "version": "0.2", + "language": "en", + "caseSensitive": false, + "$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json", + "words": [ + "appdev", + "gauzystage", + "adipiscing", + "amet", + "aliqua", + "signin", + "APPSTORE", + "barcodes", + "binutils", + "buildjet", + "cacheable", + "camelcase", + "Chatwoot", + "chetwode", + "cloc", + "cloudinary", + "clsx", + "clsxm", + "opentelemetry", + "otlp", + "commitlint", + "DONT", + "greenkeeper", + "classpath", + "tsbuildinfo", + "sentryclirc", + "compodoc", + "consectetur", + "dolor", + "dolore", + "dummyimage", + "eiusmod", + "elit", + "envalid", + "everco", + "everteamsdesktop", + "exposdk", + "gcloud", + "graphicsmagick", + "gtag", + "headlessui", + "heroicons", + "Huhn", + "icnsutils", + "incididunt", + "isdragging", + "isdraggingfrom", + "isdropdisabled", + "ipsum", + "JITSU", + "kanban", + "kanbandata", + "Lorem", + "libappindicator", + "lucide", + "mathieudutour", + "ncipollo", + "nextjs", + "passcode", + "plasmo", + "precommit", + "RECAPTCHA", + "setuptools", + "setwin", + "snyk", + "stylelint", + "svgs", + "Tailess", + "tailess", + "tailwindcss", + "testid", + "Timesheet", + "tanstack", + "taskstatus", + "tempor", + "vcpu", + "Vercel", + "HUBSTAFF", + "UPWORK", + "runned", + "Timeslot", + "Isssue", + "datas", + "Changemail", + "Lask", + "publicactive", + "Formated", + "Btns", + "RESERVERD", + "shandow", + "UIUX", + "xlight", + "domutils", + "domhandler", + "hyperscript", + "nocheck", + "locatio", + "labore", + "falsey", + "unhang", + "popperjs", + "Isssue", + "inital", + "FULLNAME", + "extramenu", + "iuser", + "Pourtcent", + "Reconds", + "Pourtcent", + "combx", + "fomated", + "Hanlder", + "cmdk", + "sitekey", + "Loadtasks", + "Accordian", + "lgcard", + "dvalue", + "Codacy", + "codecov", + "huntr", + "Gitter", + "shadcn", + "Repobeats", + "Codementor", + "xlcard", + "wght", + "worksace", + "appkey", + "jitsi", + "accepte", + "Parens", + "pako", + "embla", + "excalidraw", + "Lngs", + "Transpiles", + "wasabisys", + "apistage", + "flaticon", + "VERSONS", + "vertificalline", + "Tongatapu", + "Moresby", + "Pago", + "Kosrae", + "Kiritimati", + "Fakaofo", + "Enderbury", + "Efate", + "Propf", + "mappagination", + "INAPP", + "INFOTMATION", + "nimg", + "strock", + "ISSUETYPE", + "borde", + "imlement", + "Invitatio", + "Synk", + "nimg", + "capitaliz", + "nimg", + "Settingfilter", + "recieve", + "Opena", + "TRANSFERT", + "choos", + "Darkmode", + "recieve", + "Vefified", + "Uturn", + "insted", + "Cmbx", + "hidde", + "invitationid", + "cheched", + "Dropown", + "imodal", + "Signle", + "Filder", + "outclick", + "Filder", + "skey", + "outclick", + "Xlarge", + "Permisson", + "noreferrer", + "errr", + "Instanciate", + "Varibales", + "ciphertext", + "discrepenancy", + "unoffic", + "implem", + "asel", + "Togger", + "Organizatio", + "Combox", + "unchild", + "signoff", + "Settingfilter", + "X", + "stackoverflow", + "payperiod", + "billrate", + "tnode", + "localstorage", + "millisencods", + "taskid", + "creatoe", + "setrole", + "lastest", + "immediatly", + "Verifiy", + "invdate", + "ianatz", + "uicolors", + "greppable", + "Andross", + "Bowser", + "Boilerplates", + "xcodeproj", + "gradlew", + "paren", + "iphonesimulator", + "xcworkspace", + "dropwdown", + "itask", + "xcodebuild", + "reactotron", + "fbjs", + "stylesheet", + "bootsplash", + "animatable", + "apisauce", + "grotesk", + "jsbundle", + "unimodules", + "mobx", + "typeof", + "loglevel", + "applesimutils", + "phraseapp", + "OSTYPE", + "pkill", + "yellowbox", + "miliseconds", + "Bugsnag", + "Neue", + "Defaul", + "Reactotron's", + "Worspace", + "Funtion", + "tinvitations", + "Authentificate", + "screenstatus", + "withteam", + "Invitions", + "lastlog", + "STMP", + "statut", + "statsus", + "simplecast", + "Ffeeds", + "smalltext", + "Pressible", + "Pressable", + "deserunt", + "longpress", + "endregion", + "checkcircleo", + "Entypo", + "Charaters", + "Ionicons", + "ellipsize", + "unasigned", + "progess", + "Icontent", + "arrowleft", + "Descrption", + "Swith", + "Chane", + "Plaholder", + "firstname", + "Isvalid", + "Chane", + "checkcircle", + "exclamationcircleo", + "contaniner", + "Galery", + "clockcircleo", + "filtmembers", + "comparision", + "Jamon", + "Chami", + "Mazen", + "Heinze", + "Kanbanboard", + "Kolkata", + "Holmgren", + "Jamon", + "Rickert", + "Metral", + "subsquently", + "Syle", + "teamtask", + "imagebutton", + "hwba", + "plasmohq", + "Proguard", + "horcrux", + "dimesions", + "Ordereds", + "uidotdev", + "usehooks", + "Personnal", + "SCREENSHOOTS", + "Screenshoot", + "screenshoots", + "tota", + "Intervall" + ], + "useGitignore": true, + "ignorePaths": [ + ".deploy/*", + ".git/*", + ".git/!{COMMIT_EDITMSG,EDITMSG}", + ".git/*/**", + ".yarn", + "**/*.jar", + ".pnp.js", + "**/.git/**", + ".vscode", + ".gitignore", + "action/lib/**", + "coverage", + ".cspell.json", + "cspell.json", + "__snapshots__", + "__recordings__", + "**/coverage/**", + "**/fixtures/**/*.json", + "**/fixtures/sampleCode/*errors/", + "**/node_modules/**", + "**/vscode-extension/**", + "package-lock.json", + "yarn.lock", + "**/assets/i18n/*.json", + "**/migrations/**", + "packages/**/*.seed.json", + "**/*.svg", + "tools/build/webpack.config.js", + "docker-compose.demo.yml", + "docker-compose.yml", + "wait", + "signin", + "Chatwoot", + "CHATWOOT", + "apps/web/messages/*.json", + "apps/web/public/locales/**", + "apps/web/lib/i18n/*.ts", + "apps/web/lib/settings/timezones.js", + "apps/mobile/app/screens/DemoShowroomScreen/demos/**", + "apps/mobile/app/i18n/*.ts", + "apps/mobile/android/**", + "apps/mobile/ios/**", + "apps/desktop/i18n/**", + "apps/**/*.{svg,css,scss}" + ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 711854ee5..ba689581a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,36 +1,41 @@ { - "cSpell.userWords": [], - "cSpell.enabled": true, - "typescript.tsdk": "node_modules/typescript/lib", - "typescript.enablePromptUseWorkspaceTsdk": true, - "npm.packageManager": "yarn", - "prettier.trailingComma": "none", - "prettier.singleQuote": true, - "editor.formatOnSave": true, - "eslint.format.enable": true, - "editor.tabSize": 4, - "files.insertFinalNewline": true, - "files.trimFinalNewlines": true, - "files.trimTrailingWhitespace": true, - "editor.codeActionsOnSave": { - "source.fixAll": "explicit" - }, - "vsicons.presets.angular": true, - "deepscan.enable": true, - "cSpell.words": [], - "files.exclude": { - "**/.git": true, - "**/.DS_Store": true, - "**/node_modules": false, - "**/public/**/*.png": true, - "**/public/**/*.jpg": true, - "**/public/**/*.pdf": true, - }, - "search.exclude": { - "**/node_modules": true, - "**/bower_components": true, - "**/*.code-search": true, - "**/web/components/**": true, - }, - "docwriter.style": "Auto-detect" + "importSorter.generalConfiguration.sortOnBeforeSave": false, + "importSorter.sortConfiguration.joinImportPaths": false, + "cSpell.userWords": [], + "cSpell.enabled": true, + "typescript.tsdk": "node_modules/typescript/lib", + "typescript.enablePromptUseWorkspaceTsdk": true, + "npm.packageManager": "yarn", + "prettier.trailingComma": "none", + "prettier.singleQuote": true, + "editor.formatOnSave": true, + "eslint.format.enable": true, + "editor.tabSize": 4, + "files.insertFinalNewline": true, + "files.trimFinalNewlines": true, + "files.trimTrailingWhitespace": true, + "editor.codeActionsOnSave": { + "source.fixAll": "explicit", + "source.organizeImports": "never", + "source.sortMembers": "never", + "organizeImports": "never" + }, + "vsicons.presets.angular": true, + "deepscan.enable": true, + "cSpell.words": [], + "files.exclude": { + "**/.git": true, + "**/.DS_Store": true, + "**/node_modules": false, + "**/public/**/*.png": true, + "**/public/**/*.jpg": true, + "**/public/**/*.pdf": true + }, + "search.exclude": { + "**/node_modules": true, + "**/bower_components": true, + "**/*.code-search": true, + "**/web/components/**": true + }, + "docwriter.style": "Auto-detect" } diff --git a/apps/web/app/[locale]/auth/passcode/page.tsx b/apps/web/app/[locale]/auth/passcode/page.tsx index 8fac3cb62..51b2a314b 100644 --- a/apps/web/app/[locale]/auth/passcode/page.tsx +++ b/apps/web/app/[locale]/auth/passcode/page.tsx @@ -4,7 +4,16 @@ import { getAccessTokenCookie, getActiveUserIdCookie } from '@app/helpers'; import { TAuthenticationPasscode, useAuthenticationPasscode } from '@app/hooks'; import { IClassName } from '@app/interfaces'; import { clsxm } from '@app/utils'; -import { AuthCodeInputField, Avatar, BackButton, Button, Card, InputField, SpinnerLoader, Text } from 'lib/components'; +import { + AuthCodeInputField, + Avatar, + BackButton, + Button, + Card, + InputField, + SpinnerLoader, + Text +} from 'lib/components'; import { CircleIcon, TickCircleIconV2 } from 'lib/components/svgs'; import { AuthLayout } from 'lib/layout'; import { useTranslations } from 'next-intl'; @@ -15,350 +24,390 @@ import { FormEvent, useCallback, useEffect, useState } from 'react'; import stc from 'string-to-color'; function AuthPasscode() { - const form = useAuthenticationPasscode(); - const t = useTranslations(); - const router = useRouter(); + const form = useAuthenticationPasscode(); + const t = useTranslations(); + const router = useRouter(); - useEffect(() => { - const userId = getActiveUserIdCookie(); - if (userId) { - router.replace('/'); - } - }, [router]); + useEffect(() => { + const userId = getActiveUserIdCookie(); + if (userId) { + router.replace('/'); + } + }, [router]); - return ( - - {t('pages.authLogin.HEADING_WORKSPACE_LINE1')} - - {t('pages.authLogin.HEADING_WORKSPACE_LINE2')} - > - ) : ( - t('pages.authLogin.HEADING_DESCRIPTION') - ) - } - > - - - {form.authScreen.screen === 'email' && } - {form.authScreen.screen === 'passcode' && ( - - )} + return ( + + {t('pages.authLogin.HEADING_WORKSPACE_LINE1')} + + {t('pages.authLogin.HEADING_WORKSPACE_LINE2')} + > + ) : ( + t('pages.authLogin.HEADING_DESCRIPTION') + ) + } + > + + + {form.authScreen.screen === 'email' && ( + + )} + {form.authScreen.screen === 'passcode' && ( + + )} - {form.authScreen.screen === 'workspace' && ( - - )} - - - - ); + {form.authScreen.screen === 'workspace' && ( + + )} + + + + ); } export default AuthPasscode; -function EmailScreen({ form, className }: { form: TAuthenticationPasscode } & IClassName) { - const t = useTranslations(); +function EmailScreen({ + form, + className +}: { form: TAuthenticationPasscode } & IClassName) { + const t = useTranslations(); - const handleSendCode = useCallback( - (e: FormEvent) => { - e.preventDefault(); + const handleSendCode = useCallback( + (e: FormEvent) => { + e.preventDefault(); - form.sendAuthCodeHandler().then(() => { - form.authScreen.setScreen('passcode'); - }); - }, - [form] - ); + form.sendAuthCodeHandler().then(() => { + form.authScreen.setScreen('passcode'); + }); + }, + [form] + ); - return ( - - - - - {t('pages.auth.ENTER_EMAIL')} - + return ( + + + + + {t('pages.auth.ENTER_EMAIL')} + - {/* Email input */} - + {/* Email input */} + - - {/* Send code */} - - - {t('common.DONT_HAVE_ACCOUNT')} - - {t('common.REGISTER')} - - - + + {/* Send code */} + + + {t('common.DONT_HAVE_ACCOUNT')} + + {t('common.REGISTER')} + + + - - {t('common.CONTINUE')} - - - - - - ); + + {t('common.CONTINUE')} + + + + + + ); } -function PasscodeScreen({ form, className }: { form: TAuthenticationPasscode } & IClassName) { - const t = useTranslations(); +function PasscodeScreen({ + form, + className +}: { form: TAuthenticationPasscode } & IClassName) { + const t = useTranslations(); - return ( - - - - - {t('pages.auth.LOGIN')} - + return ( + + + + + {t('pages.auth.LOGIN')} + - {/* Auth code input */} - - {t('pages.auth.INPUT_INVITE_CODE')} + {/* Auth code input */} + + + {t('pages.auth.INPUT_INVITE_CODE')} + - { - form.setFormValues((v) => ({ ...v, code })); - }} - hintType={ - form.errors['code'] || form.errors['email'] - ? 'error' - : form.authenticated - ? 'success' - : undefined - } - autoFocus={form.authScreen.screen === 'passcode'} - /> - {(form.errors['code'] || form.errors['email']) && ( - - {form.errors['code'] || form.errors['email']} - - )} - + { + form.setFormValues((v) => ({ ...v, code })); + }} + hintType={ + form.errors['code'] || form.errors['email'] + ? 'error' + : form.authenticated + ? 'success' + : undefined + } + autoFocus={form.authScreen.screen === 'passcode'} + /> + {(form.errors['code'] || form.errors['email']) && ( + + {form.errors['code'] || form.errors['email']} + + )} + - - {/* Send code */} - - - - {t('pages.auth.UNRECEIVED_CODE')} - + + {/* Send code */} + + + + {t('pages.auth.UNRECEIVED_CODE')} + - {!form.sendCodeLoading && ( - - {'Re'} - - {t('pages.auth.SEND_CODE')} - - - )} - {form.sendCodeLoading && } - + {!form.sendCodeLoading && ( + + {'Re'} + + {t('pages.auth.SEND_CODE')} + + + )} + {form.sendCodeLoading && ( + + )} + - - { - form.authScreen.setScreen('email'); - form.setErrors({}); - }} - /> - - + + { + form.authScreen.setScreen('email'); + form.setErrors({}); + }} + /> + + - - {t('pages.auth.LOGIN')} - - - - - - ); + + {t('pages.auth.LOGIN')} + + + + + + ); } -function WorkSpaceScreen({ form, className }: { form: TAuthenticationPasscode } & IClassName) { - const t = useTranslations(); +function WorkSpaceScreen({ + form, + className +}: { form: TAuthenticationPasscode } & IClassName) { + const t = useTranslations(); - const [selectedWorkspace, setSelectedWorkspace] = useState(0); - const [selectedTeam, setSelectedTeam] = useState(''); - const router = useRouter(); + const [selectedWorkspace, setSelectedWorkspace] = useState(0); + const [selectedTeam, setSelectedTeam] = useState(''); + const router = useRouter(); - const signInToWorkspace = useCallback( - (e: any) => { - if (typeof selectedWorkspace !== 'undefined') { - form.handleWorkspaceSubmit(e, form.workspaces[selectedWorkspace].token, selectedTeam); - } - }, - [selectedWorkspace, selectedTeam, form] - ); + const signInToWorkspace = useCallback( + (e: any) => { + if (typeof selectedWorkspace !== 'undefined') { + form.handleWorkspaceSubmit( + e, + form.workspaces[selectedWorkspace].token, + selectedTeam + ); + } + }, + [selectedWorkspace, selectedTeam, form] + ); - useEffect(() => { - if (form.workspaces.length === 1) { - setSelectedWorkspace(0); - } - if (form.workspaces.length === 1 && form.workspaces[0].current_teams.length === 1) { - setSelectedTeam(form.workspaces[0].current_teams[0].team_id); - } - if (form.workspaces.length === 1 && form.workspaces[0].current_teams.length <= 1) { - setTimeout(() => { - document.getElementById('continue-to-workspace')?.click(); - }, 100); - } - }, [form.workspaces]); + useEffect(() => { + if (form.workspaces.length === 1) { + setSelectedWorkspace(0); + } + if ( + form.workspaces.length === 1 && + form.workspaces[0].current_teams.length === 1 + ) { + setSelectedTeam(form.workspaces[0].current_teams[0].team_id); + } + if ( + form.workspaces.length === 1 && + form.workspaces[0].current_teams.length <= 1 + ) { + setTimeout(() => { + document.getElementById('continue-to-workspace')?.click(); + }, 100); + } + }, [form.workspaces]); - useEffect(() => { - if (form.authScreen.screen === 'workspace') { - const accessToken = getAccessTokenCookie(); - if (accessToken && accessToken.length > 100) { - router.refresh(); - } - } - }, [form.authScreen, router]); + useEffect(() => { + if (form.authScreen.screen === 'workspace') { + const accessToken = getAccessTokenCookie(); + if (accessToken && accessToken.length > 100) { + router.refresh(); + } + } + }, [form.authScreen, router]); - return ( - - - - - {t('pages.auth.SELECT_WORKSPACE')} - + return ( + + + + + {t('pages.auth.SELECT_WORKSPACE')} + - - {form.workspaces.map((worksace, index) => ( - - - - {worksace.user.tenant.name} - { - setSelectedWorkspace(index); - if ( - selectedTeam && - !worksace.current_teams - .map((team) => team.team_id) - .includes(selectedTeam) - ) { - setSelectedTeam(worksace.current_teams[0].team_id); - } - }} - > - {selectedWorkspace === index ? ( - - ) : ( - - )} - - - - {/* */} - - {worksace.current_teams.map((team) => ( - - - - - - {team.team_name} - - ({team.team_member_count}) - - - { - setSelectedTeam(team.team_id); - if (selectedWorkspace !== index) { - setSelectedWorkspace(index); - } - }} - > - {selectedTeam === team.team_id ? ( - - ) : ( - - )} - - - ))} - - - - ))} - + + {form.workspaces.map((worksace, index) => ( + + + + {worksace.user.tenant.name} + { + setSelectedWorkspace(index); + if ( + selectedTeam && + !worksace.current_teams + .map((team) => team.team_id) + .includes(selectedTeam) + ) { + setSelectedTeam(worksace.current_teams[0].team_id); + } + }} + > + {selectedWorkspace === index ? ( + + ) : ( + + )} + + + + {/* */} + + {worksace.current_teams.map((team) => ( + + + + + + {team.team_name} + + ({team.team_member_count}) + + + { + setSelectedTeam(team.team_id); + if (selectedWorkspace !== index) { + setSelectedWorkspace(index); + } + }} + > + {selectedTeam === team.team_id ? ( + + ) : ( + + )} + + + ))} + + + + ))} + - - - - { - form.authScreen.setScreen('email'); - form.setErrors({}); - }} - /> - - + + + + { + form.authScreen.setScreen('email'); + form.setErrors({}); + }} + /> + + - - {t('common.CONTINUE')} - - - - - - ); + + {t('common.CONTINUE')} + + + + + + ); } diff --git a/apps/web/app/hooks/auth/useAuthenticationPasscode.ts b/apps/web/app/hooks/auth/useAuthenticationPasscode.ts index 633206587..66a6d0e25 100644 --- a/apps/web/app/hooks/auth/useAuthenticationPasscode.ts +++ b/apps/web/app/hooks/auth/useAuthenticationPasscode.ts @@ -3,11 +3,11 @@ import { authFormValidate } from '@app/helpers/validations'; import { ISigninEmailConfirmWorkspaces } from '@app/interfaces'; import { - sendAuthCodeAPI, - signInEmailAPI, - signInEmailConfirmAPI, - signInWithEmailAndCodeAPI, - signInWorkspaceAPI + sendAuthCodeAPI, + signInEmailAPI, + signInEmailConfirmAPI, + signInWithEmailAndCodeAPI, + signInWorkspaceAPI } from '@app/services/client/api'; import { AxiosError } from 'axios'; import { usePathname, useSearchParams } from 'next/navigation'; @@ -16,247 +16,292 @@ import { useQuery } from '../useQuery'; import { useTranslations } from 'next-intl'; type AuthCodeRef = { - focus: () => void; - clear: () => void; + focus: () => void; + clear: () => void; }; export function useAuthenticationPasscode() { - const pathname = usePathname(); - const query = useSearchParams(); - - const queryTeamId = useMemo(() => { - return query?.get('teamId'); - }, [query]); - const queryEmail = useMemo(() => { - return query?.get('email'); - }, [query]); - const queryCode = useMemo(() => { - return query?.get('code'); - }, [query]); - - const t = useTranslations(); - - const loginFromQuery = useRef(false); - const inputCodeRef = useRef(null); - const [screen, setScreen] = useState<'email' | 'passcode' | 'workspace'>('email'); - const [workspaces, setWorkspaces] = useState([]); - const [authenticated, setAuthenticated] = useState(false); - - const [formValues, setFormValues] = useState({ email: '', code: '' }); - - const [errors, setErrors] = useState({} as { [x: string]: any }); - - // Queries - const { queryCall: sendCodeQueryCall, loading: sendCodeLoading } = useQuery(sendAuthCodeAPI); - - const { queryCall: signInEmailQueryCall, loading: signInEmailLoading } = useQuery(signInEmailAPI); - const { queryCall: signInEmailConfirmQueryCall, loading: signInEmailConfirmLoading } = - useQuery(signInEmailConfirmAPI); - const { queryCall: signInWorkspaceQueryCall, loading: signInWorkspaceLoading } = useQuery(signInWorkspaceAPI); - - const { queryCall, loading, infiniteLoading } = useQuery(signInWithEmailAndCodeAPI); - - const handleChange = (e: any) => { - const { name, value } = e.target; - setFormValues((prevState) => ({ ...prevState, [name]: value })); - }; - - /** - * Verify auth request - */ - const verifySignInEmailConfirmRequest = async ({ email, code }: { email: string; code: string }) => { - signInEmailConfirmQueryCall(email, code) - .then((res) => { - if (res.data?.workspaces && res.data.workspaces.length) { - setWorkspaces(res.data.workspaces); - - setScreen('workspace'); - } - - // If user tries to login from public Team Page as an Already a Member - // Redirect to the current team automatically - if (pathname === '/team/[teamId]/[profileLink]' && res.data.workspaces.length) { - if (queryTeamId) { - const currentWorkspace = res.data.workspaces.find((workspace) => - workspace.current_teams.map((item) => item.team_id).includes(queryTeamId as string) - ); - - signInToWorkspaceRequest({ - email: email, - token: currentWorkspace?.token as string, - selectedTeam: queryTeamId as string - }); - } - } - - if (res.data?.status !== 200 && res.data?.status !== 201) { - setErrors({ code: t('pages.auth.INVALID_INVITE_CODE_MESSAGE') }); - } - }) - .catch((err: AxiosError) => { - if (err.response?.status === 400) { - setErrors((err.response?.data as any)?.errors || {}); - } - }); - }; - - const verifyPasscodeRequest = useCallback( - ({ email, code }: { email: string; code: string }) => { - queryCall(email, code) - .then((res) => { - const errors = (res.data as any).errors as any; - if (errors.email) { - setErrors(errors || {}); - return; - } - - window.location.reload(); - setAuthenticated(true); - }) - .catch((err: AxiosError) => { - if (err.response?.status === 400) { - setErrors((err.response?.data as any)?.errors || {}); - } - - inputCodeRef.current?.clear(); - }); - }, - [queryCall] - ); - const signInToWorkspaceRequest = ({ - email, - token, - selectedTeam - }: { - email: string; - token: string; - selectedTeam: string; - }) => { - signInWorkspaceQueryCall(email, token, selectedTeam) - .then(() => { - window.location.reload(); - setAuthenticated(true); - }) - .catch((err: AxiosError) => { - if (err.response?.status === 400) { - setErrors((err.response?.data as any)?.errors || {}); - } - - inputCodeRef.current?.clear(); - }); - }; - - const handleCodeSubmit = (e: React.FormEvent) => { - e.preventDefault(); - setErrors({}); - const { errors, valid } = authFormValidate(['email', 'code'], formValues as any); - - if (!valid) { - setErrors(errors); - return; - } - - infiniteLoading.current = true; - - verifySignInEmailConfirmRequest({ - email: formValues.email, - code: formValues.code - }); - }; - - const handleSubmit = (e: any) => { - e.preventDefault(); - setErrors({}); - const { errors, valid } = authFormValidate(['email', 'code'], formValues as any); - - if (!valid) { - setErrors(errors); - return; - } - - infiniteLoading.current = true; - - verifyPasscodeRequest({ - email: formValues.email, - code: formValues.code - }); - }; - - const handleWorkspaceSubmit = (e: any, token: string, selectedTeam: string) => { - e.preventDefault(); - setErrors({}); - const { errors, valid } = authFormValidate(['email'], formValues as any); - - if (!valid) { - setErrors(errors); - return; - } - - infiniteLoading.current = true; - - signInToWorkspaceRequest({ - email: formValues.email, - token, - selectedTeam - }); - }; - - /** - * Verifiy immediatly passcode if email and code were passed from url - */ - useEffect(() => { - if (queryEmail && queryCode && !loginFromQuery.current) { - setScreen('passcode'); - verifyPasscodeRequest({ - email: queryEmail as string, - code: queryCode as string - }); - loginFromQuery.current = true; - } - }, [query, verifyPasscodeRequest, queryEmail, queryCode]); - - /** - * send a fresh auth request handler - * STEP1 - */ - const sendAuthCodeHandler = useCallback(() => { - const promise = signInEmailQueryCall(formValues['email']); - - promise.then(() => setErrors({})); - promise.catch((err: AxiosError) => { - if (err.response?.status === 400) { - setErrors((err.response?.data as any)?.errors || {}); - } - }); - - return promise; - }, [formValues, signInEmailQueryCall]); - - return { - sendAuthCodeHandler, - errors, - sendCodeLoading, - handleSubmit, - handleChange, - loading, - formValues, - setFormValues, - inputCodeRef, - setErrors, - authScreen: { screen, setScreen }, - authenticated, - setAuthenticated, - handleCodeSubmit, - signInEmailQueryCall, - signInEmailLoading, - signInEmailConfirmQueryCall, - signInEmailConfirmLoading, - workspaces, - sendCodeQueryCall, - signInWorkspaceLoading, - queryCall, - handleWorkspaceSubmit - }; + const pathname = usePathname(); + const query = useSearchParams(); + + const queryTeamId = useMemo(() => { + return query?.get('teamId'); + }, [query]); + const queryEmail = useMemo(() => { + const emailQuery = query?.get('email') || ''; + localStorage?.setItem('ever-teams-start-email', emailQuery); + return emailQuery; + }, [query]); + const queryCode = useMemo(() => { + return query?.get('code'); + }, [query]); + + const t = useTranslations(); + + const loginFromQuery = useRef(false); + const inputCodeRef = useRef(null); + const [screen, setScreen] = useState<'email' | 'passcode' | 'workspace'>( + 'email' + ); + const [workspaces, setWorkspaces] = useState( + [] + ); + const [authenticated, setAuthenticated] = useState(false); + + const [formValues, setFormValues] = useState({ + email: queryEmail, + code: '' + }); + + const [errors, setErrors] = useState({} as { [x: string]: any }); + + // Queries + const { queryCall: sendCodeQueryCall, loading: sendCodeLoading } = useQuery( + sendAuthCodeAPI + ); + + const { + queryCall: signInEmailQueryCall, + loading: signInEmailLoading + } = useQuery(signInEmailAPI); + const { + queryCall: signInEmailConfirmQueryCall, + loading: signInEmailConfirmLoading + } = useQuery(signInEmailConfirmAPI); + const { + queryCall: signInWorkspaceQueryCall, + loading: signInWorkspaceLoading + } = useQuery(signInWorkspaceAPI); + + const { queryCall, loading, infiniteLoading } = useQuery( + signInWithEmailAndCodeAPI + ); + + const handleChange = (e: any) => { + const { name, value } = e.target; + setFormValues((prevState) => ({ ...prevState, [name]: value })); + }; + + /** + * Verify auth request + */ + const verifySignInEmailConfirmRequest = async ({ + email, + code + }: { + email: string; + code: string; + }) => { + signInEmailConfirmQueryCall(email, code) + .then((res) => { + if (res.data?.workspaces && res.data.workspaces.length) { + setWorkspaces(res.data.workspaces); + + setScreen('workspace'); + } + + // If user tries to login from public Team Page as an Already a Member + // Redirect to the current team automatically + if ( + pathname === '/team/[teamId]/[profileLink]' && + res.data.workspaces.length + ) { + if (queryTeamId) { + const currentWorkspace = res.data.workspaces.find((workspace) => + workspace.current_teams + .map((item) => item.team_id) + .includes(queryTeamId as string) + ); + + signInToWorkspaceRequest({ + email: email, + token: currentWorkspace?.token as string, + selectedTeam: queryTeamId as string + }); + } + } + + if (res.data?.status !== 200 && res.data?.status !== 201) { + setErrors({ code: t('pages.auth.INVALID_INVITE_CODE_MESSAGE') }); + } + }) + .catch((err: AxiosError) => { + if (err.response?.status === 400) { + setErrors((err.response?.data as any)?.errors || {}); + } + }); + }; + + const verifyPasscodeRequest = useCallback( + ({ email, code }: { email: string; code: string }) => { + queryCall(email, code) + .then((res) => { + const errors = (res.data as any).errors ?? {}; + + if (errors.email) { + setErrors(errors); + return; + } + + window.location.reload(); + setAuthenticated(true); + }) + .catch((err: AxiosError) => { + if (err.response?.status === 400) { + setErrors((err.response?.data as any)?.errors || {}); + } + + inputCodeRef.current?.clear(); + }); + }, + [queryCall] + ); + const signInToWorkspaceRequest = ({ + email, + token, + selectedTeam + }: { + email: string; + token: string; + selectedTeam: string; + }) => { + signInWorkspaceQueryCall(email, token, selectedTeam) + .then(() => { + window.location.reload(); + setAuthenticated(true); + }) + .catch((err: AxiosError) => { + if (err.response?.status === 400) { + setErrors((err.response?.data as any)?.errors || {}); + } + + inputCodeRef.current?.clear(); + }); + }; + + const handleCodeSubmit = (e: React.FormEvent) => { + e.preventDefault(); + setErrors({}); + const { errors, valid } = authFormValidate( + ['email', 'code'], + formValues as any + ); + + if (!valid) { + setErrors(errors); + return; + } + + infiniteLoading.current = true; + + verifySignInEmailConfirmRequest({ + email: formValues.email, + code: formValues.code + }); + }; + + const handleSubmit = (e: any) => { + e.preventDefault(); + setErrors({}); + const { errors, valid } = authFormValidate( + ['email', 'code'], + formValues as any + ); + + if (!valid) { + setErrors(errors); + return; + } + + infiniteLoading.current = true; + + verifyPasscodeRequest({ + email: formValues.email, + code: formValues.code + }); + }; + + const handleWorkspaceSubmit = ( + e: any, + token: string, + selectedTeam: string + ) => { + e.preventDefault(); + setErrors({}); + const { errors, valid } = authFormValidate(['email'], formValues as any); + + if (!valid) { + setErrors(errors); + return; + } + + infiniteLoading.current = true; + + signInToWorkspaceRequest({ + email: formValues.email, + token, + selectedTeam + }); + }; + + /** + * Verifiy immediatly passcode if email and code were passed from url + */ + useEffect(() => { + if (queryEmail && queryCode && !loginFromQuery.current) { + setScreen('passcode'); + verifyPasscodeRequest({ + email: queryEmail as string, + code: queryCode as string + }); + loginFromQuery.current = true; + } + }, [query, verifyPasscodeRequest, queryEmail, queryCode]); + + /** + * send a fresh auth request handler + * STEP1 + */ + const sendAuthCodeHandler = useCallback(() => { + const promise = signInEmailQueryCall(formValues['email']); + + promise.then(() => setErrors({})); + promise.catch((err: AxiosError) => { + if (err.response?.status === 400) { + setErrors((err.response?.data as any)?.errors || {}); + } + }); + + return promise; + }, [formValues, signInEmailQueryCall]); + + return { + sendAuthCodeHandler, + errors, + sendCodeLoading, + handleSubmit, + handleChange, + loading, + formValues, + setFormValues, + inputCodeRef, + setErrors, + authScreen: { screen, setScreen }, + authenticated, + setAuthenticated, + handleCodeSubmit, + signInEmailQueryCall, + signInEmailLoading, + signInEmailConfirmQueryCall, + signInEmailConfirmLoading, + workspaces, + sendCodeQueryCall, + signInWorkspaceLoading, + queryCall, + handleWorkspaceSubmit + }; } -export type TAuthenticationPasscode = ReturnType; +export type TAuthenticationPasscode = ReturnType< + typeof useAuthenticationPasscode +>; diff --git a/apps/web/app/hooks/auth/useAuthenticationTeam.ts b/apps/web/app/hooks/auth/useAuthenticationTeam.ts index 6fb7d6764..75b6fa2ca 100644 --- a/apps/web/app/hooks/auth/useAuthenticationTeam.ts +++ b/apps/web/app/hooks/auth/useAuthenticationTeam.ts @@ -6,94 +6,108 @@ import { authFormValidate } from '@app/helpers/validations'; import { IRegisterDataAPI } from '@app/interfaces'; import { registerUserTeamAPI } from '@app/services/client/api'; import { AxiosError } from 'axios'; -import { useCallback, useState } from 'react'; +import { useCallback, useMemo, useState } from 'react'; import { useQuery } from '../useQuery'; import { RECAPTCHA_SITE_KEY } from '@app/constants'; +import { useSearchParams } from 'next/navigation'; const FIRST_STEP = 'STEP1' as const; const SECOND_STEP = 'STEP2' as const; export interface IStepProps { - handleOnChange: any; - form: IRegisterDataAPI; + handleOnChange: any; + form: IRegisterDataAPI; } const initialValues: IRegisterDataAPI = RECAPTCHA_SITE_KEY - ? { - name: '', - email: '', - team: '', - recaptcha: '' - } - : { - name: '', - email: '', - team: '' - }; + ? { + name: '', + email: '', + team: '', + recaptcha: '' + } + : { + name: '', + email: '', + team: '' + }; export function useAuthenticationTeam() { - const [step, setStep] = useState(FIRST_STEP); - const [formValues, setFormValues] = useState(initialValues); - const [errors, setErrors] = useState(initialValues); - const { queryCall, loading, infiniteLoading } = useQuery(registerUserTeamAPI); + const query = useSearchParams(); + const queryEmail = useMemo(() => { + const emailQuery = + query?.get('email') || + localStorage?.getItem('ever-teams-start-email') || + ''; + return emailQuery; + }, [query]); + initialValues.email = queryEmail; + const [step, setStep] = useState( + FIRST_STEP + ); + const [formValues, setFormValues] = useState(initialValues); + const [errors, setErrors] = useState(initialValues); + const { queryCall, loading, infiniteLoading } = useQuery(registerUserTeamAPI); - const handleSubmit = (e: any) => { - e.preventDefault(); - if (step === FIRST_STEP) { - const { errors, valid } = authFormValidate(['team'], formValues); - setErrors(errors as any); - valid && setStep(SECOND_STEP); - return; - } + const handleSubmit = (e: any) => { + e.preventDefault(); + if (step === FIRST_STEP) { + const { errors, valid } = authFormValidate(['team'], formValues); + setErrors(errors as any); + valid && setStep(SECOND_STEP); + return; + } - const noRecaptchaArray = ['email', 'name']; + const noRecaptchaArray = ['email', 'name']; - const withRecaptchaArray = [...noRecaptchaArray, 'recaptcha']; + const withRecaptchaArray = [...noRecaptchaArray, 'recaptcha']; - const validationFields = RECAPTCHA_SITE_KEY ? withRecaptchaArray : noRecaptchaArray; + const validationFields = RECAPTCHA_SITE_KEY + ? withRecaptchaArray + : noRecaptchaArray; - const { errors, valid } = authFormValidate(validationFields, formValues); + const { errors, valid } = authFormValidate(validationFields, formValues); - if (!valid) { - setErrors(errors as any); - return; - } + if (!valid) { + setErrors(errors as any); + return; + } - formValues['timezone'] = userTimezone(); - infiniteLoading.current = true; + formValues['timezone'] = userTimezone(); + infiniteLoading.current = true; - queryCall(formValues) - .then(() => window.location.reload()) - .catch((err: AxiosError) => { - if (err.response?.status === 400) { - setErrors((err.response?.data as any)?.errors || {}); - } - }); - }; + queryCall(formValues) + .then(() => window.location.reload()) + .catch((err: AxiosError) => { + if (err.response?.status === 400) { + setErrors((err.response?.data as any)?.errors || {}); + } + }); + }; - const handleOnChange = useCallback( - (e: any) => { - const { name, value } = e.target; - const key = name as keyof IRegisterDataAPI; - if (errors[key]) { - errors[key] = ''; - } - setFormValues((prevState) => ({ - ...prevState, - [name]: value - })); - }, - [errors] - ); + const handleOnChange = useCallback( + (e: any) => { + const { name, value } = e.target; + const key = name as keyof IRegisterDataAPI; + if (errors[key]) { + errors[key] = ''; + } + setFormValues((prevState) => ({ + ...prevState, + [name]: value + })); + }, + [errors] + ); - return { - handleSubmit, - handleOnChange, - loading, - FIRST_STEP, - step, - SECOND_STEP, - setStep, - errors, - formValues - }; + return { + handleSubmit, + handleOnChange, + loading, + FIRST_STEP, + step, + SECOND_STEP, + setStep, + errors, + formValues + }; } diff --git a/apps/web/next.config.js b/apps/web/next.config.js index d749b5e4b..c47e96931 100644 --- a/apps/web/next.config.js +++ b/apps/web/next.config.js @@ -1,9 +1,33 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable @typescript-eslint/no-var-requires */ const path = require('path'); const withNextIntl = require('next-intl/plugin')(); console.log(`NEXT_PUBLIC_GAUZY_API_SERVER_URL: ${process.env.NEXT_PUBLIC_GAUZY_API_SERVER_URL}`); +const isProduction = process.env.NODE_ENV === 'production'; +const isSentryEnabled = isProduction && process.env.SENTRY_DSN; + +const sentryConfig = isSentryEnabled && { + sentry: { + // For all available options, see: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/ + + // Upload a larger set of source maps for prettier stack traces (increases build time) + widenClientFileUpload: true, + + // Transpiles SDK to be compatible with IE11 (increases bundle size) + transpileClientSDK: true, + + // Routes browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers (increases server load) + tunnelRoute: '/monitoring', + + // Hides source maps from generated client bundles + hideSourceMaps: true, + + // Automatically tree-shake Sentry logger statements to reduce bundle size + disableLogger: true + } +}; // eslint-disable-next-line @typescript-eslint/no-var-requires /** @type {import('next').NextConfig} */ const nextConfig = { @@ -30,25 +54,8 @@ const nextConfig = { 'gauzy.s3.wasabisys.com', 'gauzystage.s3.wasabisys.com' ] - }, // Optional build-time configuration options - sentry: { - // For all available options, see: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/ - - // Upload a larger set of source maps for prettier stack traces (increases build time) - widenClientFileUpload: true, - - // Transpiles SDK to be compatible with IE11 (increases bundle size) - transpileClientSDK: true, - - // Routes browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers (increases server load) - tunnelRoute: '/monitoring', - - // Hides source maps from generated client bundles - hideSourceMaps: true, - - // Automatically tree-shake Sentry logger statements to reduce bundle size - disableLogger: true - } + }, + ...sentryConfig }; // Injected content via Sentry wizard below diff --git a/package.json b/package.json index 0189d2627..4ff60052e 100644 --- a/package.json +++ b/package.json @@ -1,201 +1,202 @@ { - "name": "ever-teams", - "homepage": "https://ever.team", - "license": "UNLICENSED", - "author": { - "name": "Ever Co. LTD", - "email": "ever@ever.co", - "url": "https://ever.co" - }, - "version": "0.1.0", - "repository": { - "type": "git", - "url": "https://github.com/ever-co/ever-teams.git" - }, - "bugs": { - "url": "https://github.com/ever-co/ever-teams/issues" - }, - "private": true, - "scripts": { - "prepare:husky": "npx husky install .husky", - "ng": "cross-env NODE_ENV=development NODE_OPTIONS=--max_old_space_size=8192 yarn nx", - "ng:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max_old_space_size=8192 yarn nx", - "ng:ci": "cross-env NODE_ENV=production NODE_OPTIONS=--max_old_space_size=7000 yarn nx", - "config": "yarn ts-node ./.scripts/configure.ts", - "config:dev": "yarn run config -- --environment=dev", - "config:prod": "yarn run config -- --environment=prod", - "start": "yarn build && yarn concurrently --raw --kill-others \"yarn start:web\"", - "start:prod": "yarn build && yarn concurrently --raw --kill-others \"yarn start:web:prod\"", - "start:web": "cd apps/web && yarn run start", - "start:web:forever": "yarn run config:dev && forever start ng serve web --disable-host-check --host 0.0.0.0", - "start:web:pm2": "cross-env NODE_ENV=development NODE_OPTIONS=--max_old_space_size=4096 yarn build:web && yarn ts-node ./apps/web/src/pm2bootstrap.ts", - "start:web:prod": "yarn run config:prod && yarn ng serve web --configuration production --disable-host-check --host 0.0.0.0 --prod", - "bootstrap": "yarn install && yarn lerna bootstrap", - "prebuild": "rimraf dist coverage", - "build": "yarn build:web && yarn build:mobile && yarn build:extensions", - "build:web": "cd apps/web && yarn run build", - "build:mobile": "cd apps/mobile && yarn install && yarn run build", - "build:extensions": "cd apps/extensions && yarn install && yarn run build", - "commit": "git-cz", - "commit:lint": "commitlint -E HUSKY_GIT_PARAMS", - "semantic-release": "semantic-release", - "test": "yarn run postinstall.web && yarn run config:dev && yarn ng test", - "lint": "lerna run lint", - "lint-fix": "cd apps/web && eslint . --fix", - "lint-fix:scss": "cd apps/web && stylelint **/*.{scss,css} --fix", - "e2e": "yarn run postinstall.web && yarn run config:dev && yarn ng e2e --browser chrome", - "e2e:ci": "yarn run postinstall.web && yarn run config:prod && yarn --frozen-lockfile --cache-folder ~/.cache/yarn ng:ci e2e -c=production --prod --headless", - "prettier": "yarn prettier:web && yarn prettier:mobile && yarn prettier:extensions", - "prettier:extensions": "cd apps/extensions && prettier --write **/*.{js,jsx,ts,tsx,scss,css} --config ./.prettierrc.cjs", - "prettier:web": "cd apps/web && prettier --write **/*.{js,jsx,ts,tsx,scss,css} --config ./.prettierrc", - "prettier:mobile": "cd apps/mobile && prettier --write **/*.{js,jsx,ts,tsx,scss,css} --config ./.prettierrc", - "postinstall": "lerna bootstrap", - "precommit": "yarn lint-fix && yarn lint-fix:scss && yarn prettier", - "affected:apps": "yarn nx affected:apps", - "affected:libs": "yarn nx affected:libs", - "affected:build": "yarn nx affected:build", - "affected:e2e": "yarn nx affected:e2e", - "affected:test": "yarn nx affected:test", - "affected:lint": "yarn nx affected:lint", - "affected:dep-graph": "yarn nx affected:dep-graph", - "affected": "yarn nx affected", - "format": "yarn nx format:write", - "format:write": "yarn nx format:write", - "format:web:write": "cd apps/web && yarn nx format:write", - "format:web:check": "cd apps/web && yarn nx format:check", - "format:check": "nx format:check", - "update": "yarn ng update @nx/workspace", - "update:check": "yarn ng update", - "workspace-schematic": "yarn nx workspace-schematic", - "workspace-generator": "nx workspace-generator", - "dep-graph": "nx dep-graph", - "help": "nx help", - "doc:build": "compodoc -p tsconfig.json -d dist/docs", - "doc:serve": "compodoc -s -d dist/docs", - "doc:build-serve": "compodoc -p tsconfig.json -d docs -s", - "postinstall.electron": "yarn electron-builder install-app-deps && yarn node tools/electron/postinstall", - "postinstall.web": "yarn node tools/web/postinstall", - "spell": "cspell . --config .cspell.json", - "spellcheck": "cspell ." - }, - "config": { - "commitizen": { - "path": "cz-conventional-changelog" - } - }, - "commitlint": { - "extends": [ - "@commitlint/config-conventional" - ] - }, - "husky": { - "hooks": { - "commit-msg": "commitlint -E HUSKY_GIT_PARAMS", - "pre-commit": "pretty-quick --no-verify --staged" - } - }, - "lint-staged": {}, - "release": { - "verifyConditions": [ - "@semantic-release/changelog", - "@semantic-release/npm", - "@semantic-release/git", - "@semantic-release/github" - ], - "prepare": [ - "@semantic-release/changelog", - "@semantic-release/npm", - "@semantic-release/git" - ], - "publish": [ - "@semantic-release/github" - ], - "generateNotes": { - "preset": "react" - }, - "npmPublish": false - }, - "workspaces": { - "packages": [ - "apps/web", - "packages/*", - "libs/*", - "tools" - ], - "nohoist": [] - }, - "resolutions": {}, - "dependencies": { - "@lexical/react": "^0.8.0", - "dotenv": "^16.0.3", - "lexical": "^0.8.0", - "yargs": "^17.5.0" - }, - "devDependencies": { - "@commitlint/cli": "^17.6.6", - "@commitlint/config-conventional": "^17.6.6", - "@commitlint/config-lerna-scopes": "^17.6.6", - "@commitlint/travis-cli": "^17.6.6", - "@compodoc/compodoc": "^1.1.19", - "@cucumber/cucumber": "^8.9.0", - "@cucumber/cucumber-expressions": "^16.0.1", - "@cucumber/gherkin": "^25.0.2", - "@cypress/browserify-preprocessor": "^3.0.2", - "@next/eslint-plugin-next": "^13.0.5", - "@nx/cypress": "^16.7.4", - "@nx/detox": "^16.7.4", - "@nx/eslint-plugin-nx": "^16.0.0-beta.1", - "@nx/jest": "^16.7.4", - "@nx/linter": "^16.7.4", - "@nx/nest": "^16.7.4", - "@nx/next": "^16.7.4", - "@nx/react": "^16.7.4", - "@nx/web": "^16.7.4", - "@nx/node": "^16.7.4", - "@nx/workspace": "^16.7.4", - "@nx/webpack": "^16.7.4", - "@semantic-release/changelog": "^5.0.1", - "@semantic-release/git": "^9.0.0", - "@semantic-release/github": "^7.2.1", - "@semantic-release/npm": "^7.1.1", - "@types/detox": "^18.1.0", - "@types/node": "^18.11.9", - "@types/yargs": "^15.0.9", - "@typescript-eslint/eslint-plugin": "5.60.1", - "@typescript-eslint/parser": "5.60.1", - "cloc": "^2.10.0", - "commitizen": "^4.2.5", - "concurrently": "^7.6.0", - "conventional-changelog": "^3.1.25", - "conventional-changelog-cli": "^2.2.2", - "cross-env": "^7.0.3", - "cypress": "^11.2.0", - "cypress-file-upload": "^5.0.8", - "cz-conventional-changelog": "^3.3.0", - "detox": "20.11.1", - "envalid": "^6.0.2", - "eslint": "8.46.0", - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-cypress": "2.13.4", - "eslint-plugin-prettier": "^4.2.1", - "eslint-plugin-react": "^7.31.8", - "husky": "^8.0.2", - "lerna": "^6.0.3", - "lerna-changelog": "^2.2.0", - "lint-staged": "^10.4.0", - "nx": "16.7.4", - "nx-cloud": "16.3.0", - "prettier": "^3.0.3", - "prettier-eslint-cli": "^8.0.1", - "pretty-quick": "^3.1.3", - "rimraf": "^3.0.2", - "semantic-release": "^19.0.5", - "ts-node": "^10.9.1", - "cspell": "8.0.0" - }, - "engines": { - "node": ">=16.0.0", - "yarn": ">=1.13.0" - }, - "snyk": true + "name": "ever-teams", + "homepage": "https://ever.team", + "license": "UNLICENSED", + "author": { + "name": "Ever Co. LTD", + "email": "ever@ever.co", + "url": "https://ever.co" + }, + "version": "0.1.0", + "repository": { + "type": "git", + "url": "https://github.com/ever-co/ever-teams.git" + }, + "bugs": { + "url": "https://github.com/ever-co/ever-teams/issues" + }, + "private": true, + "scripts": { + "prepare:husky": "npx husky install .husky", + "ng": "cross-env NODE_ENV=development NODE_OPTIONS=--max_old_space_size=8192 yarn nx", + "ng:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max_old_space_size=8192 yarn nx", + "ng:ci": "cross-env NODE_ENV=production NODE_OPTIONS=--max_old_space_size=7000 yarn nx", + "config": "yarn ts-node ./.scripts/configure.ts", + "config:dev": "yarn run config -- --environment=dev", + "config:prod": "yarn run config -- --environment=prod", + "dev:web": "cd apps/web && yarn run dev", + "start": "yarn build && yarn concurrently --raw --kill-others \"yarn start:web\"", + "start:prod": "yarn build && yarn concurrently --raw --kill-others \"yarn start:web:prod\"", + "start:web": "cd apps/web && yarn run start", + "start:web:forever": "yarn run config:dev && forever start ng serve web --disable-host-check --host 0.0.0.0", + "start:web:pm2": "cross-env NODE_ENV=development NODE_OPTIONS=--max_old_space_size=4096 yarn build:web && yarn ts-node ./apps/web/src/pm2bootstrap.ts", + "start:web:prod": "yarn run config:prod && yarn ng serve web --configuration production --disable-host-check --host 0.0.0.0 --prod", + "bootstrap": "yarn install && yarn lerna bootstrap", + "prebuild": "rimraf dist coverage", + "build": "yarn build:web && yarn build:mobile && yarn build:extensions", + "build:web": "cd apps/web && yarn run build", + "build:mobile": "cd apps/mobile && yarn install && yarn run build", + "build:extensions": "cd apps/extensions && yarn install && yarn run build", + "commit": "git-cz", + "commit:lint": "commitlint -E HUSKY_GIT_PARAMS", + "semantic-release": "semantic-release", + "test": "yarn run postinstall.web && yarn run config:dev && yarn ng test", + "lint": "lerna run lint", + "lint-fix": "cd apps/web && eslint . --fix", + "lint-fix:scss": "cd apps/web && stylelint **/*.{scss,css} --fix", + "e2e": "yarn run postinstall.web && yarn run config:dev && yarn ng e2e --browser chrome", + "e2e:ci": "yarn run postinstall.web && yarn run config:prod && yarn --frozen-lockfile --cache-folder ~/.cache/yarn ng:ci e2e -c=production --prod --headless", + "prettier": "yarn prettier:web && yarn prettier:mobile && yarn prettier:extensions", + "prettier:extensions": "cd apps/extensions && prettier --write **/*.{js,jsx,ts,tsx,scss,css} --config ./.prettierrc.cjs", + "prettier:web": "cd apps/web && prettier --write **/*.{js,jsx,ts,tsx,scss,css} --config ./.prettierrc", + "prettier:mobile": "cd apps/mobile && prettier --write **/*.{js,jsx,ts,tsx,scss,css} --config ./.prettierrc", + "postinstall": "lerna bootstrap", + "precommit": "yarn lint-fix && yarn lint-fix:scss && yarn prettier", + "affected:apps": "yarn nx affected:apps", + "affected:libs": "yarn nx affected:libs", + "affected:build": "yarn nx affected:build", + "affected:e2e": "yarn nx affected:e2e", + "affected:test": "yarn nx affected:test", + "affected:lint": "yarn nx affected:lint", + "affected:dep-graph": "yarn nx affected:dep-graph", + "affected": "yarn nx affected", + "format": "yarn nx format:write", + "format:write": "yarn nx format:write", + "format:web:write": "cd apps/web && yarn nx format:write", + "format:web:check": "cd apps/web && yarn nx format:check", + "format:check": "nx format:check", + "update": "yarn ng update @nx/workspace", + "update:check": "yarn ng update", + "workspace-schematic": "yarn nx workspace-schematic", + "workspace-generator": "nx workspace-generator", + "dep-graph": "nx dep-graph", + "help": "nx help", + "doc:build": "compodoc -p tsconfig.json -d dist/docs", + "doc:serve": "compodoc -s -d dist/docs", + "doc:build-serve": "compodoc -p tsconfig.json -d docs -s", + "postinstall.electron": "yarn electron-builder install-app-deps && yarn node tools/electron/postinstall", + "postinstall.web": "yarn node tools/web/postinstall", + "spell": "cspell . --config .cspell.json", + "spellcheck": "cspell ." + }, + "config": { + "commitizen": { + "path": "cz-conventional-changelog" + } + }, + "commitlint": { + "extends": [ + "@commitlint/config-conventional" + ] + }, + "husky": { + "hooks": { + "commit-msg": "commitlint -E HUSKY_GIT_PARAMS", + "pre-commit": "pretty-quick --no-verify --staged" + } + }, + "lint-staged": {}, + "release": { + "verifyConditions": [ + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/git", + "@semantic-release/github" + ], + "prepare": [ + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/git" + ], + "publish": [ + "@semantic-release/github" + ], + "generateNotes": { + "preset": "react" + }, + "npmPublish": false + }, + "workspaces": { + "packages": [ + "apps/web", + "packages/*", + "libs/*", + "tools" + ], + "nohoist": [] + }, + "resolutions": {}, + "dependencies": { + "@lexical/react": "^0.8.0", + "dotenv": "^16.0.3", + "lexical": "^0.8.0", + "yargs": "^17.5.0" + }, + "devDependencies": { + "@commitlint/cli": "^17.6.6", + "@commitlint/config-conventional": "^17.6.6", + "@commitlint/config-lerna-scopes": "^17.6.6", + "@commitlint/travis-cli": "^17.6.6", + "@compodoc/compodoc": "^1.1.19", + "@cucumber/cucumber": "^8.9.0", + "@cucumber/cucumber-expressions": "^16.0.1", + "@cucumber/gherkin": "^25.0.2", + "@cypress/browserify-preprocessor": "^3.0.2", + "@next/eslint-plugin-next": "^13.0.5", + "@nx/cypress": "^16.7.4", + "@nx/detox": "^16.7.4", + "@nx/eslint-plugin-nx": "^16.0.0-beta.1", + "@nx/jest": "^16.7.4", + "@nx/linter": "^16.7.4", + "@nx/nest": "^16.7.4", + "@nx/next": "^16.7.4", + "@nx/react": "^16.7.4", + "@nx/web": "^16.7.4", + "@nx/node": "^16.7.4", + "@nx/workspace": "^16.7.4", + "@nx/webpack": "^16.7.4", + "@semantic-release/changelog": "^5.0.1", + "@semantic-release/git": "^9.0.0", + "@semantic-release/github": "^7.2.1", + "@semantic-release/npm": "^7.1.1", + "@types/detox": "^18.1.0", + "@types/node": "^18.11.9", + "@types/yargs": "^15.0.9", + "@typescript-eslint/eslint-plugin": "5.60.1", + "@typescript-eslint/parser": "5.60.1", + "cloc": "^2.10.0", + "commitizen": "^4.2.5", + "concurrently": "^7.6.0", + "conventional-changelog": "^3.1.25", + "conventional-changelog-cli": "^2.2.2", + "cross-env": "^7.0.3", + "cypress": "^11.2.0", + "cypress-file-upload": "^5.0.8", + "cz-conventional-changelog": "^3.3.0", + "detox": "20.11.1", + "envalid": "^6.0.2", + "eslint": "8.46.0", + "eslint-config-prettier": "^8.5.0", + "eslint-plugin-cypress": "2.13.4", + "eslint-plugin-prettier": "^4.2.1", + "eslint-plugin-react": "^7.31.8", + "husky": "^8.0.2", + "lerna": "^6.0.3", + "lerna-changelog": "^2.2.0", + "lint-staged": "^10.4.0", + "nx": "16.7.4", + "nx-cloud": "16.3.0", + "prettier": "^3.0.3", + "prettier-eslint-cli": "^8.0.1", + "pretty-quick": "^3.1.3", + "rimraf": "^3.0.2", + "semantic-release": "^19.0.5", + "ts-node": "^10.9.1", + "cspell": "8.0.0" + }, + "engines": { + "node": ">=16.0.0", + "yarn": ">=1.13.0" + }, + "snyk": true }