feat: 🚀 😃 convert repo into a monorepo 🚀 😃 (#51)
* Merge main into turbo-monrepo * feat: rename apps * feat: remove supbase videos and serve all from project * feat: move supabase to root * feat: update README * docs: update link
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
export async function handleAuthChange(event, session) {
|
||||
await fetch('/api/auth', {
|
||||
method: 'POST',
|
||||
headers: new Headers({ 'Content-Type': 'application/json' }),
|
||||
credentials: 'same-origin',
|
||||
body: JSON.stringify({ event, session })
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
export function toggleBodyByMode(isDark) {
|
||||
if (!document) return;
|
||||
|
||||
if (isDark) {
|
||||
document.body.className = document.body.className.concat(' ', 'dark');
|
||||
} else {
|
||||
document.body.className = document.body.className.replace(' dark', '');
|
||||
}
|
||||
}
|
||||
|
||||
export function isCoursesPage(path) {
|
||||
return /courses\/[a-z 0-9 -]/.test(path);
|
||||
}
|
||||
|
||||
export function isCoursePage(path) {
|
||||
return /course\/[a-z 0-9 -]/.test(path);
|
||||
}
|
||||
|
||||
export function isOrgPage(path) {
|
||||
return /org\/[a-z 0-9 -]/.test(path);
|
||||
}
|
||||
|
||||
export function isQuizPage(path) {
|
||||
return /org\/[a-z 0-9 -]+\/quiz\/[a-z 0-9 -]/.test(path);
|
||||
}
|
||||
|
||||
export function isLMSPage(path) {
|
||||
return /lms[\/a-z 0-9 -]*/.test(path);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import { browser } from '$app/environment';
|
||||
import type { Course } from '../types';
|
||||
|
||||
export const isCourseFree = (cost: number) => !(Number(cost) > 0);
|
||||
|
||||
export const getStudentInviteLink = (_course: Course, orgSiteName: string) => {
|
||||
const hash = encodeURIComponent(
|
||||
btoa(
|
||||
JSON.stringify({
|
||||
groupId: _course.group?.id,
|
||||
name: _course.title,
|
||||
description: _course.description,
|
||||
orgSiteName
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
return `https://${orgSiteName}.classroomio.com/invite/s/${hash}`;
|
||||
};
|
||||
|
||||
export const getTextFromHTML = (html: string): string => {
|
||||
if (!browser) return html;
|
||||
|
||||
const dummyDiv = document.createElement('div');
|
||||
dummyDiv.innerHTML = html;
|
||||
|
||||
return dummyDiv.textContent?.trim() || '';
|
||||
};
|
||||
|
||||
const tagsToReplace = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>'
|
||||
};
|
||||
|
||||
export function replaceHTMLTag(text: string) {
|
||||
return text
|
||||
.split('')
|
||||
.map((char) => tagsToReplace[char] || char)
|
||||
.join('');
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import dayjs from 'dayjs';
|
||||
import relativeTime from 'dayjs/plugin/relativeTime';
|
||||
|
||||
dayjs.extend(relativeTime);
|
||||
|
||||
export const calDateDiff = (date: string | number | Date): string => {
|
||||
return dayjs(date).fromNow(true) + ` ago`;
|
||||
};
|
||||
|
||||
export const getGreeting = () => {
|
||||
const date = new Date();
|
||||
const hours = date.getHours();
|
||||
return hours < 12 ? 'Good Morning' : hours < 18 ? 'Good Afternoon' : 'Good Evening';
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
export default (date) => {
|
||||
const d = new Date(date);
|
||||
|
||||
const ye = new Intl.DateTimeFormat('en', { year: 'numeric' }).format(d);
|
||||
const mo = new Intl.DateTimeFormat('en', { month: '2-digit' }).format(d);
|
||||
const da = new Intl.DateTimeFormat('en', { day: '2-digit' }).format(d);
|
||||
|
||||
// return `${ye}-${mo}-${da} ${d.toLocaleTimeString('en-US')}`;
|
||||
return new Intl.DateTimeFormat('en-US', {
|
||||
dateStyle: 'full',
|
||||
timeStyle: 'medium'
|
||||
}).format(d);
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
export function formatYoutubeVideo(url: string, errors: { video: string }) {
|
||||
console.log(`url`, url);
|
||||
const prefix = 'https://www.youtube.com/embed';
|
||||
|
||||
// https://www.youtube.com/embed/qajK1J1neAM
|
||||
if (url.includes('embed')) {
|
||||
return url;
|
||||
}
|
||||
|
||||
// https://youtu.be/qajK1J1neAM
|
||||
if (url.includes('.be/')) {
|
||||
const splittedUrlWithBe = url.split('.be/');
|
||||
|
||||
return `${prefix}/${splittedUrlWithBe[1]}`;
|
||||
}
|
||||
|
||||
// https://www.youtube.com/watch?v=qajK1J1neAM
|
||||
const splitedUrl = url.split('watch');
|
||||
if (splitedUrl.length !== 2) {
|
||||
errors.video = 'Not a valid youtube link';
|
||||
return;
|
||||
}
|
||||
|
||||
const query = new URLSearchParams(splitedUrl[1]);
|
||||
|
||||
return `${prefix}/${query.get('v')}`;
|
||||
}
|
||||
|
||||
export function getEmbedId(url: string) {
|
||||
// https://www.youtube.com/embed/qajK1J1neAM
|
||||
if (url.includes('embed')) {
|
||||
return url.split('embed/')[1];
|
||||
}
|
||||
|
||||
// https://youtu.be/qajK1J1neAM
|
||||
if (url.includes('.be/')) {
|
||||
const splittedUrlWithBe = url.split('.be/');
|
||||
|
||||
return splittedUrlWithBe[1];
|
||||
}
|
||||
|
||||
// https://www.youtube.com/watch?v=qajK1J1neAM
|
||||
const splitedUrl = url.split('watch');
|
||||
if (splitedUrl.length !== 2) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const query = new URLSearchParams(splitedUrl[1]);
|
||||
|
||||
return query.get('v');
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export default () => Date.now().toString(36) + Math.random().toString(36).substr(2);
|
||||
@@ -0,0 +1,10 @@
|
||||
function generateSlug(title) {
|
||||
return title
|
||||
.match(/[^\W\s\d]*/g, '')
|
||||
.filter((v = '') => !!v.trim())
|
||||
.join('-')
|
||||
.toLowerCase()
|
||||
.concat(`-${new Date().getTime()}`);
|
||||
}
|
||||
|
||||
export default generateSlug;
|
||||
@@ -0,0 +1,18 @@
|
||||
export default function generateUUID() {
|
||||
// Public Domain/MIT
|
||||
var d = new Date().getTime(); //Timestamp
|
||||
var d2 = (typeof performance !== 'undefined' && performance.now && performance.now() * 1000) || 0; //Time in microseconds since page-load or 0 if unsupported
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||
var r = Math.random() * 16; //random number between 0 and 16
|
||||
if (d > 0) {
|
||||
//Use timestamp until depleted
|
||||
r = (d + r) % 16 | 0;
|
||||
d = Math.floor(d / 16);
|
||||
} else {
|
||||
//Use microseconds since page-load if supported
|
||||
r = (d2 + r) % 16 | 0;
|
||||
d2 = Math.floor(d2 / 16);
|
||||
}
|
||||
return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
export default (currency: string | undefined) => {
|
||||
const locale = currency == 'NGN' ? 'en-NG' : 'en-US';
|
||||
return new Intl.NumberFormat(locale, {
|
||||
style: 'currency',
|
||||
currency: currency,
|
||||
minimumFractionDigits: 2
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
export function isObject(obj) {
|
||||
return obj === Object(obj);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export default (created_at, due_date) => {
|
||||
return !!due_date ? !!(new Date(created_at).getTime() <= new Date(due_date).getTime()) : true;
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
export function isUUID(uuid: string) {
|
||||
let s = '' + uuid;
|
||||
|
||||
const m: RegExpMatchArray | null = s.match(
|
||||
'^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$'
|
||||
);
|
||||
|
||||
if (m === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
export function genQuizPin(): number {
|
||||
var minm = 100000;
|
||||
var maxm = 999999;
|
||||
return Math.floor(Math.random() * (maxm - minm + 1)) + minm;
|
||||
}
|
||||
|
||||
export function generateSitename(orgName: string): string {
|
||||
return orgName
|
||||
.toLowerCase()
|
||||
.replace(/\s+/g, '-')
|
||||
.replace(/[^a-zA-Z0-9-]/g, '');
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export function removeDuplicate(arr) {
|
||||
let s = new Set(arr);
|
||||
let it = s.values();
|
||||
return Array.from(it);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import dayjs from 'dayjs';
|
||||
import isYesterday from 'dayjs/plugin/isYesterday';
|
||||
import isToday from 'dayjs/plugin/isToday';
|
||||
import isTomorrow from 'dayjs/plugin/isTomorrow';
|
||||
|
||||
import type { UserLessonDataType, LessonsByMonthIndexType } from '$lib/utils/types';
|
||||
|
||||
dayjs.extend(isYesterday);
|
||||
dayjs.extend(isToday);
|
||||
dayjs.extend(isTomorrow);
|
||||
|
||||
export const formatUserUpcomingData = (data: UserLessonDataType[]): LessonsByMonthIndexType => {
|
||||
const result: LessonsByMonthIndexType = {};
|
||||
|
||||
for (const item of data) {
|
||||
const { lesson_at } = item;
|
||||
const lessonAtDate = new Date(lesson_at);
|
||||
const monthIndex = lessonAtDate.getMonth();
|
||||
const dateIndex = lessonAtDate.getDate();
|
||||
|
||||
if (result[monthIndex]) {
|
||||
const prevDateData = result[monthIndex][dateIndex];
|
||||
|
||||
if (Array.isArray(prevDateData)) {
|
||||
result[monthIndex] = {
|
||||
...result[monthIndex],
|
||||
[dateIndex]: [...prevDateData, item]
|
||||
};
|
||||
} else {
|
||||
result[monthIndex] = { ...result[monthIndex], [dateIndex]: [item] };
|
||||
}
|
||||
} else {
|
||||
result[monthIndex] = { [dateIndex]: [item] };
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
export const formatDate = (_selectedDate: string | undefined): string => {
|
||||
if (!_selectedDate) return '';
|
||||
|
||||
const selectedDate = dayjs(_selectedDate);
|
||||
|
||||
if (selectedDate.isToday()) {
|
||||
return 'Today';
|
||||
} else if (selectedDate.isYesterday()) {
|
||||
return 'Yesterday';
|
||||
} else if (selectedDate.isTomorrow()) {
|
||||
return 'Tomorrow';
|
||||
}
|
||||
|
||||
return selectedDate.format('ddd, MMM D');
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
import { ROUTES_TO_HIDE_NAV } from '$lib/utils/constants/routes';
|
||||
|
||||
export default (route: string): boolean => {
|
||||
return ROUTES_TO_HIDE_NAV.some((publicRoute) => {
|
||||
const regex = new RegExp(publicRoute, 'g');
|
||||
return regex.test(route);
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
import { PUBLIC_ROUTES } from '$lib/utils/constants/routes';
|
||||
|
||||
export default (route = '') => {
|
||||
return PUBLIC_ROUTES.some((publicRoute) => {
|
||||
const regex = new RegExp(publicRoute, 'g');
|
||||
return regex.test(route);
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
export default (path: string): boolean => {
|
||||
return ['login', 'signup', 'onboarding'].some((r) => path.includes(r)) || path === '';
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
function showAppsSideBar(path) {
|
||||
return path.includes('/lessons/') && !path.includes('landingpage');
|
||||
}
|
||||
|
||||
export default showAppsSideBar;
|
||||
@@ -0,0 +1,3 @@
|
||||
export function capitalizeFirstLetter(val: string): string {
|
||||
return val.charAt(0).toUpperCase() + val.slice(1);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import {
|
||||
PUBLIC_SUPABASE_ANON_KEY,
|
||||
PUBLIC_SUPABASE_URL,
|
||||
PUBLIC_SUPABASE_BUCKET_URL
|
||||
} from '$env/static/public';
|
||||
import { createClient, SupabaseClient } from '@supabase/supabase-js';
|
||||
import type { ConfigType } from '../types';
|
||||
|
||||
export let supabase: SupabaseClient;
|
||||
|
||||
export const getSupabase = (config?: ConfigType) => {
|
||||
if (supabase) return supabase;
|
||||
config = {
|
||||
supabaseConfig: {
|
||||
bucketPath: PUBLIC_SUPABASE_BUCKET_URL + '/storage/v1/object/sign/',
|
||||
url: PUBLIC_SUPABASE_URL || '',
|
||||
anonKey: PUBLIC_SUPABASE_ANON_KEY || ''
|
||||
}
|
||||
};
|
||||
|
||||
supabase = createClient(config.supabaseConfig.url, config.supabaseConfig.anonKey);
|
||||
|
||||
return supabase;
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
export function setTheme(theme: string) {
|
||||
// In case the default theme is added but another theme exists
|
||||
if (!theme && document.body.className.includes('theme-')) {
|
||||
const regex = /theme-[\w]+/gi;
|
||||
document.body.className = document.body.className.replace(regex, theme);
|
||||
return;
|
||||
}
|
||||
|
||||
// In case theme already exists in dom, don't add
|
||||
if (document.body.className.includes(theme)) return;
|
||||
|
||||
localStorage.setItem('theme', theme);
|
||||
document.body.className = document.body.className.concat(' ', theme);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { supabase } from '$lib/utils/functions/supabase';
|
||||
import type { Profile } from '$lib/components/Course/components/People/types';
|
||||
|
||||
export async function getProfile(email: string): Promise<Profile | null> {
|
||||
const { data } = await supabase.from('profile').select('*').eq('email', email).single();
|
||||
console.log('getProfile data', data);
|
||||
return data;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export function validateEmail(email) {
|
||||
const re =
|
||||
/^(([^<>()[\]\\.,;:\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,}))$/;
|
||||
return re.test(String(email).toLowerCase());
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
import isNumber from 'lodash/isNumber';
|
||||
import z from 'zod';
|
||||
import { validateEmail } from './validateEmail';
|
||||
|
||||
const createQuizValidationSchema = z.object({
|
||||
title: z.string().min(6, {
|
||||
message: 'Must be 6 or more characters long',
|
||||
invalid_type_error: 'Must not be empty'
|
||||
})
|
||||
});
|
||||
|
||||
const askCommunityValidationSchema = z.object({
|
||||
title: z.string().min(6, {
|
||||
message: 'Must be 6 or more characters long',
|
||||
invalid_type_error: 'Must not be empty'
|
||||
}),
|
||||
body: z.string().min(20, {
|
||||
message: 'Must be 10 or more characters long',
|
||||
invalid_type_error: 'Must not be empty'
|
||||
})
|
||||
});
|
||||
const commentInCommunityValidationSchema = z.object({
|
||||
comment: z.string().min(6, {
|
||||
message: 'Must be 6 or more characters long',
|
||||
invalid_type_error: 'Must not be empty'
|
||||
})
|
||||
});
|
||||
|
||||
const orgLandingpageValidationSchema = z.object({
|
||||
name: z.string().min(6, {
|
||||
message: 'Must be 6 or more characters long',
|
||||
invalid_type_error: 'Must not be empty'
|
||||
}),
|
||||
email: z.string().email({
|
||||
message: 'Invalid email address',
|
||||
invalid_type_error: 'Must not be empty'
|
||||
}),
|
||||
phone: z.string().min(6, {
|
||||
message: 'Must be 6 or more characters long',
|
||||
invalid_type_error: 'Must not be empty'
|
||||
}),
|
||||
message: z.string().min(20, {
|
||||
message: 'Must be 10 or more characters long',
|
||||
invalid_type_error: 'Must not be empty'
|
||||
})
|
||||
});
|
||||
|
||||
const forgotValidationSchema = z.object({
|
||||
email: z.string().email({
|
||||
message: 'Invalid email address',
|
||||
invalid_type_error: 'Must not be empty'
|
||||
})
|
||||
});
|
||||
|
||||
const authValidationSchema = z.object({
|
||||
email: z.string().email({
|
||||
message: 'Invalid email address',
|
||||
invalid_type_error: 'Must not be empty'
|
||||
}),
|
||||
password: z.string().min(6, {
|
||||
message: 'Must be 6 or more characters long',
|
||||
invalid_type_error: 'Must not be empty'
|
||||
})
|
||||
});
|
||||
|
||||
const resetValidationSchema = z.object({
|
||||
password: z.string().min(6, {
|
||||
message: 'Must be 6 or more characters long',
|
||||
invalid_type_error: 'Must not be empty'
|
||||
})
|
||||
});
|
||||
|
||||
const onboardingValidationSchema = {
|
||||
stepOne: z.object({
|
||||
fullname: z.string().min(1, { message: 'Enter your fullname' }),
|
||||
orgName: z.string().min(1, { message: 'Enter your organisation name' }),
|
||||
siteName: z.string().min(1, { message: 'Enter your site name' })
|
||||
}),
|
||||
stepTwo: z.object({
|
||||
goal: z
|
||||
.string({
|
||||
required_error: 'Select an option',
|
||||
invalid_type_error: 'Select an option'
|
||||
})
|
||||
.min(1),
|
||||
source: z
|
||||
.string({
|
||||
required_error: 'Select an option',
|
||||
invalid_type_error: 'Select an option'
|
||||
})
|
||||
.min(1)
|
||||
})
|
||||
};
|
||||
|
||||
export const getConfirmPasswordError = ({ password, confirmPassword }) => {
|
||||
return password > 6 && confirmPassword > 6 && password !== confirmPassword
|
||||
? 'Does not match password'
|
||||
: undefined;
|
||||
};
|
||||
|
||||
export const processErrors = (error, mapToId) => {
|
||||
const errors = {};
|
||||
|
||||
if (Array.isArray(error?.issues)) {
|
||||
for (const issue of error.issues) {
|
||||
const { message, path } = issue;
|
||||
|
||||
if (!path.length) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mapToId) {
|
||||
let value = '';
|
||||
path.forEach((p, i) => {
|
||||
const isLast = !path[i + 1];
|
||||
const formatP = isNumber(p) ? `[${p}]` : p;
|
||||
|
||||
value += !value ? formatP : `.${formatP}`;
|
||||
});
|
||||
const key = value.replace('label', 'id');
|
||||
errors[key] = value;
|
||||
} else {
|
||||
errors[path[0]] = message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
};
|
||||
|
||||
export const authValidation = (fields = {}) => {
|
||||
const { error } = authValidationSchema.safeParse(fields);
|
||||
|
||||
return processErrors(error);
|
||||
};
|
||||
|
||||
export const coursePaymentValidation = (fields = {}) => {
|
||||
const schema = z.object({
|
||||
fullname: z.string().min(6, {
|
||||
message: 'Must be 6 or more characters long',
|
||||
invalid_type_error: 'Must not be empty'
|
||||
}),
|
||||
email: z.string().email({
|
||||
message: 'Invalid email address',
|
||||
invalid_type_error: 'Must not be empty'
|
||||
})
|
||||
});
|
||||
const { error } = schema.safeParse(fields);
|
||||
|
||||
return processErrors(error);
|
||||
};
|
||||
|
||||
export const resetValidation = (fields = {}) => {
|
||||
const { error } = resetValidationSchema.safeParse(fields);
|
||||
|
||||
return processErrors(error);
|
||||
};
|
||||
|
||||
export const forgotValidation = (fields = {}) => {
|
||||
const { error } = forgotValidationSchema.safeParse(fields);
|
||||
|
||||
return processErrors(error);
|
||||
};
|
||||
|
||||
export const orgLandingpageValidation = (fields = {}) => {
|
||||
const { error } = orgLandingpageValidationSchema.safeParse(fields);
|
||||
|
||||
return processErrors(error);
|
||||
};
|
||||
|
||||
export const onboardingValidation = (fields = {}, step) => {
|
||||
const schema =
|
||||
step === 1 ? onboardingValidationSchema.stepOne : onboardingValidationSchema.stepTwo;
|
||||
const { error } = schema.safeParse(fields);
|
||||
|
||||
return processErrors(error);
|
||||
};
|
||||
|
||||
// export const createTemplateExerciseValidation = (fields = {}) => {
|
||||
// const schema = z.object({
|
||||
// orgName: z.string().min(5, {
|
||||
// message: 'Must be 5 or more characters long',
|
||||
// }),
|
||||
// siteName: z.string().min(5, {
|
||||
// message: 'Must be 5 or more characters long',
|
||||
// })
|
||||
// });
|
||||
// const { error } = schema.safeParse(fields);
|
||||
|
||||
// return processErrors(error);
|
||||
// };
|
||||
|
||||
export const createOrgValidation = (fields = {}) => {
|
||||
const schema = z.object({
|
||||
orgName: z.string().min(5, {
|
||||
message: 'Must be 5 or more characters long',
|
||||
invalid_type_error: 'Must not be empty'
|
||||
}),
|
||||
siteName: z.string().min(5, {
|
||||
message: 'Must be 5 or more characters long',
|
||||
invalid_type_error: 'Must not be empty'
|
||||
})
|
||||
});
|
||||
const { error } = schema.safeParse(fields);
|
||||
|
||||
return processErrors(error);
|
||||
};
|
||||
|
||||
export const createQuizValidation = (fields = {}) => {
|
||||
const { error } = createQuizValidationSchema.safeParse(fields);
|
||||
|
||||
return processErrors(error);
|
||||
};
|
||||
|
||||
export const askCommunityValidation = (fields = {}) => {
|
||||
const { error } = askCommunityValidationSchema.safeParse(fields);
|
||||
|
||||
return processErrors(error);
|
||||
};
|
||||
|
||||
export const commentInCommunityValidation = (fields = {}) => {
|
||||
const { error } = commentInCommunityValidationSchema.safeParse(fields);
|
||||
|
||||
return processErrors(error);
|
||||
};
|
||||
|
||||
export const getDisableSubmit = ({ password, confirmPassword }) => {
|
||||
return !!(password && confirmPassword && password !== confirmPassword);
|
||||
};
|
||||
|
||||
export const validateEmailInString = (emailsStr) => {
|
||||
let error = '';
|
||||
let hasError = false;
|
||||
|
||||
if (!emailsStr) {
|
||||
return {
|
||||
hasError: true,
|
||||
error: 'Enter an email',
|
||||
emails: []
|
||||
};
|
||||
}
|
||||
|
||||
const emails = emailsStr.split(',').map((_email) => {
|
||||
const email = _email.trim();
|
||||
|
||||
if (!validateEmail(email)) {
|
||||
hasError = true;
|
||||
error += !error.length ? `Not valid email: ${email}` : `, ${email}`;
|
||||
}
|
||||
|
||||
return email;
|
||||
});
|
||||
|
||||
return {
|
||||
hasError,
|
||||
error,
|
||||
emails
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user