first commit

This commit is contained in:
Inshal
2024-05-29 22:34:28 +05:00
commit e63fc41a20
1470 changed files with 174828 additions and 0 deletions

View File

@@ -0,0 +1,574 @@
import avatar1 from '@images/avatars/avatar-1.png'
import avatar12 from '@images/avatars/avatar-12.png'
import avatar13 from '@images/avatars/avatar-13.png'
import avatar14 from '@images/avatars/avatar-14.png'
import avatar15 from '@images/avatars/avatar-15.png'
import avatar2 from '@images/avatars/avatar-2.png'
import avatar3 from '@images/avatars/avatar-3.png'
import avatar5 from '@images/avatars/avatar-5.png'
import avatar6 from '@images/avatars/avatar-6.png'
import avatar8 from '@images/avatars/avatar-8.png'
import avatar9 from '@images/avatars/avatar-9.png'
import tutorImg1 from '@images/pages/app-academy-tutor-1.png'
import tutorImg2 from '@images/pages/app-academy-tutor-2.png'
import tutorImg3 from '@images/pages/app-academy-tutor-3.png'
import tutorImg4 from '@images/pages/app-academy-tutor-4.png'
import tutorImg5 from '@images/pages/app-academy-tutor-5.png'
import tutorImg6 from '@images/pages/app-academy-tutor-6.png'
export const db = {
courses: [
{
id: 1,
user: 'Lauretta Coie',
image: avatar1,
tutorImg: tutorImg1,
completedTasks: 19,
totalTasks: 25,
userCount: 18,
note: 20,
view: 83,
time: '17h 34m',
logo: 'ri-angularjs-line',
color: 'error',
courseTitle: 'Basics of Angular',
desc: 'Introductory course for Angular and framework basics with TypeScript',
tags: 'Web',
rating: 4.4,
ratingCount: 8,
},
{
id: 2,
user: 'Maybelle Zmitrovich',
tutorImg: tutorImg2,
image: avatar2,
completedTasks: 48,
totalTasks: 52,
userCount: 14,
note: 48,
view: 43,
time: '19h 17m',
logo: 'ri-palette-line',
color: 'warning',
desc: 'Learn how to design a beautiful & engaging mobile app with Figma',
courseTitle: 'UI/UX Design',
tags: 'Design',
rating: 4.9,
ratingCount: 10,
},
{
id: 3,
user: 'Gertie Langwade',
image: avatar2,
tutorImg: tutorImg3,
completedTasks: 87,
totalTasks: 100,
userCount: 19,
note: 81,
view: 88,
time: '16h 16m',
logo: 'ri-reactjs-line',
color: 'info',
desc: 'Master React.js: Build dynamic web apps with front-end technology',
courseTitle: 'React Native',
tags: 'Web',
rating: 4.8,
ratingCount: 9,
},
{
id: 4,
user: 'Estella Chace',
image: avatar3,
completedTasks: 33,
tutorImg: tutorImg4,
totalTasks: 50,
userCount: 28,
note: 21,
view: 87,
time: '15h 49m',
logo: 'ri-pencil-line',
color: 'success',
courseTitle: 'Art & Drawing',
desc: 'Easy-to-follow video & guides show you how to draw animals & people.',
tags: 'Design',
rating: 4.7,
ratingCount: 18,
},
{
id: 5,
user: 'Euell Bownass',
tutorImg: tutorImg5,
image: avatar14,
completedTasks: 100,
totalTasks: 100,
userCount: 13,
note: 19,
view: 13,
time: '12h 42m',
logo: 'ri-star-smile-line',
color: 'primary',
courseTitle: 'Basic Fundamentals',
desc: 'Learn the basics of the most popular programming language.',
tags: 'Web',
rating: 4.6,
ratingCount: 11,
},
{
id: 6,
user: 'Terrye Etches',
tutorImg: tutorImg6,
image: avatar3,
completedTasks: 23,
totalTasks: 25,
userCount: 78,
note: 36,
view: 36,
time: '1h 42m',
logo: 'ri-reactjs-line',
color: 'info',
courseTitle: 'React for Beginners',
desc: 'Learn React in just a couple of afternoons with this immersive course',
tags: 'Web',
rating: 4.5,
ratingCount: 68,
},
{
id: 7,
user: 'Papageno Sloy',
tutorImg: tutorImg1,
image: avatar14,
completedTasks: 11,
totalTasks: 20,
userCount: 74,
note: 21,
view: 60,
time: '4h 59m',
logo: 'ri-star-smile-line',
color: 'primary',
courseTitle: 'The Science of Critical Thinking',
desc: 'Learn how to improve your arguments & make better decisions',
tags: 'Psychology',
rating: 4.4,
ratingCount: 64,
},
{
id: 8,
user: 'Aviva Penvarden',
tutorImg: tutorImg2,
image: avatar1,
completedTasks: 6,
totalTasks: 25,
userCount: 44,
note: 28,
view: 13,
time: '2h 09m',
logo: 'ri-palette-line',
color: 'warning',
courseTitle: 'The Complete Figma UI/UX Course',
desc: 'Learn how to design a beautiful & engaging mobile app with Figma',
tags: 'UI/UX',
rating: 4.3,
ratingCount: 34,
},
{
id: 9,
user: 'Reggi Tuddenham',
tutorImg: tutorImg3,
image: avatar8,
completedTasks: 67,
totalTasks: 100,
userCount: 95,
note: 34,
view: 26,
time: '22h 21m',
logo: 'ri-star-smile-line',
color: 'primary',
courseTitle: 'Advanced Problem Solving Techniques',
desc: 'Learn how to solve problems like a professional with this immersive course',
tags: 'Psychology',
rating: 4.2,
ratingCount: 85,
},
{
id: 10,
user: 'Aluin Leveritt',
image: avatar1,
completedTasks: 49,
totalTasks: 50,
tutorImg: tutorImg4,
userCount: 98,
note: 51,
view: 37,
time: '22h 22m',
logo: 'ri-reactjs-line',
color: 'info',
courseTitle: 'Advanced React Native',
desc: 'Learn how to build the world\'s most popular mobile OS with this immersive course',
tags: 'Web',
rating: 4.1,
ratingCount: 88,
},
{
id: 11,
user: 'Ardys Deakin',
image: avatar9,
completedTasks: 87,
totalTasks: 100,
tutorImg: tutorImg5,
userCount: 19,
note: 40,
view: 32,
time: '15h 25m',
logo: 'ri-reactjs-line',
color: 'info',
courseTitle: 'Building Web Applications with React',
desc: 'Learn how to build modern web apps with React and Redux',
tags: 'Web',
rating: 4.0,
ratingCount: 9,
},
{
id: 12,
user: 'Camel Scown',
image: avatar1,
tutorImg: tutorImg6,
completedTasks: 22,
totalTasks: 25,
userCount: 26,
note: 22,
view: 77,
time: '4h 33m',
logo: 'ri-angularjs-line',
color: 'error',
courseTitle: 'Angular Routing and Navigation',
desc: 'Learn how to build single page applications like a pro with this immersive course',
tags: 'Web',
rating: 3.9,
ratingCount: 16,
},
{
id: 13,
user: 'Bertina Honnan',
image: avatar15,
tutorImg: tutorImg1,
completedTasks: 11,
totalTasks: 50,
userCount: 78,
note: 75,
view: 87,
time: '16h 38m',
logo: 'ri-star-smile-line',
color: 'primary',
courseTitle: 'Creative Problem Solving',
desc: 'Learn how to solve problems creatively and effectively with this immersive course',
tags: 'Psychology',
rating: 3.8,
ratingCount: 68,
},
{
id: 14,
user: 'Hillyer Wooster',
image: avatar2,
tutorImg: tutorImg2,
completedTasks: 11,
totalTasks: 25,
userCount: 92,
note: 39,
view: 60,
time: '22h 43m',
logo: 'ri-angularjs-line',
color: 'error',
courseTitle: 'Building Web Applications with Angular',
desc: 'Learn how to build modern web apps with Angular and TypeScript',
tags: 'Web',
rating: 3.7,
ratingCount: 82,
},
{
id: 15,
user: 'Emerson Hance',
image: avatar12,
tutorImg: tutorImg3,
completedTasks: 4,
totalTasks: 5,
userCount: 14,
note: 22,
view: 51,
time: '2h 29m',
logo: 'ri-angularjs-line',
color: 'error',
courseTitle: 'Advanced Angular',
desc: 'Learn how to build modern web apps with Angular and TypeScript',
tags: 'Web',
rating: 3.6,
ratingCount: 12,
},
{
id: 16,
user: 'Ginger Cruft',
image: avatar1,
tutorImg: tutorImg4,
completedTasks: 22,
totalTasks: 25,
userCount: 20,
note: 12,
view: 95,
time: '20h 10m',
logo: 'ri-reactjs-line',
color: 'info',
courseTitle: 'Testing React with Jest and Enzyme',
desc: 'Learn how to build modern web apps with React and Redux',
tags: 'Web',
rating: 3.5,
ratingCount: 10,
},
{
id: 17,
user: 'Rollie Parsons',
image: avatar13,
tutorImg: tutorImg5,
completedTasks: 11,
totalTasks: 50,
userCount: 29,
note: 20,
view: 98,
time: '16h 15m',
logo: 'ri-palette-line',
color: 'wa',
courseTitle: 'Typography Theory',
desc: 'Learn how to build modern web apps with React and Redux',
tags: 'Design',
rating: 3.4,
ratingCount: 19,
},
{
id: 18,
user: 'Randy Foister',
image: avatar1,
completedTasks: 23,
tutorImg: tutorImg6,
totalTasks: 100,
userCount: 20,
note: 16,
view: 77,
time: '4h 31m',
logo: 'ri-angularjs-line',
color: 'error',
courseTitle: 'Angular Testing',
desc: 'Learn how to build modern web apps with Angular and TypeScript',
tags: 'Web',
rating: 4.3,
ratingCount: 10,
},
{
id: 19,
user: 'Ashleigh Bartkowiak',
image: avatar8,
completedTasks: 17,
tutorImg: tutorImg1,
totalTasks: 50,
userCount: 28,
note: 91,
view: 31,
time: '1h 52m',
logo: 'ri-reactjs-line',
color: 'info',
courseTitle: 'React for Professional',
desc: 'Learn how to build modern web apps with React and Redux',
tags: 'Web',
rating: 4.2,
ratingCount: 18,
},
{
id: 20,
user: 'Bernarr Markie',
image: avatar12,
tutorImg: tutorImg2,
completedTasks: 1,
totalTasks: 10,
userCount: 11,
note: 33,
view: 53,
time: '16h 24m',
logo: 'ri-pencil-line',
color: 'success',
courseTitle: 'The Ultimate Drawing Course',
desc: 'Learn how to draw like a professional with this immersive course',
tags: 'Art',
rating: 4.1,
ratingCount: 9,
},
{
id: 21,
user: 'Merrilee Whitnell',
image: avatar2,
completedTasks: 91,
totalTasks: 100,
tutorImg: tutorImg3,
userCount: 11,
note: 17,
view: 74,
time: '5h 57m',
logo: 'ri-angularjs-line',
color: 'error',
courseTitle: 'Basics of Angular',
desc: 'Introductory course for Angular and framework basics with TypeScript',
tags: 'Web',
rating: 4.0,
ratingCount: 7,
},
{
id: 22,
user: 'Thekla Dineges',
image: avatar1,
tutorImg: tutorImg4,
completedTasks: 49,
totalTasks: 50,
userCount: 28,
note: 30,
view: 54,
time: '4h 40m',
logo: 'ri-pencil-line',
color: 'success',
courseTitle: 'Introduction to Digital Painting',
desc: 'Learn how to draw like a professional with this immersive course',
tags: 'Art',
rating: 3.9,
ratingCount: 18,
},
{
id: 23,
user: 'Freda Garham',
image: avatar5,
tutorImg: tutorImg5,
completedTasks: 81,
totalTasks: 100,
userCount: 79,
note: 46,
view: 27,
time: '8h 44m',
logo: 'ri-star-smile-line',
color: 'primary',
courseTitle: 'The Science of Everyday Thinking',
desc: 'Learn how to think better, argue better, and choose better',
tags: 'Psychology',
rating: 3.8,
ratingCount: 69,
},
{
id: 24,
user: 'Leyla Bourley',
image: avatar13,
completedTasks: 6,
tutorImg: tutorImg6,
totalTasks: 25,
userCount: 28,
note: 11,
view: 77,
time: '22h 36m',
logo: 'ri-pencil-line',
color: 'success',
courseTitle: 'Color Theory',
desc: 'Learn how to use color like a professional with this immersive course',
tags: 'Design',
rating: 3.7,
ratingCount: 18,
},
{
id: 25,
user: 'Nevsa Lawey',
image: avatar6,
completedTasks: 13,
totalTasks: 100,
tutorImg: tutorImg1,
userCount: 93,
note: 73,
view: 67,
time: '19h 21m',
logo: 'ri-palette-line',
color: 'warning',
courseTitle: 'The Complete Figma Course',
desc: 'Learn how to design a beautiful & engaging mobile app with Figma',
tags: 'UI/UX',
rating: 3.6,
ratingCount: 83,
},
],
courseDetails: {
title: 'UI/UX Basic Fundamentals',
about: 'Learn web design in 1 hour with 25+ simple-to-use rules and guidelines — tons of amazing web design resources included!',
instructor: 'Devonne Wallbridge',
instructorAvatar: avatar1,
instructorPosition: 'Web Developer, Designer, and Teacher',
skillLevel: 'All Level',
totalStudents: 38815,
language: 'English',
isCaptions: true,
length: '1.5 total hours',
totalLectures: 19,
description: `
<p class="text-body-1">
The material of this course is also covered in my other course about web design and development with HTML5 & CSS3. Scroll to the bottom of this page to check out that course, too! If you're already taking my other course, you already have all it takes to start designing beautiful websites today!
</p>
<p class="text-body-1">
"Best web design course: If you're interested in web design, but want more than just a "how to use WordPress" course, I highly recommend this one." — Florian Giusti
</p>
<p class="text-body-1">
"Very helpful to us left-brained people: I am familiar with HTML, CSS, jQuery, and Twitter Bootstrap, but I needed instruction in web design. This course gave me practical, impactful techniques for making websites more beautiful and engaging." — Susan Darlene Cain
</p>`,
content: [
{
title: 'Course Content',
status: '2/5',
time: '4.4 min',
id: 'section1',
topics: [
{ title: 'Welcome to this course', time: '2.4 min', isCompleted: true },
{ title: 'Watch before you start', time: '4.8 min', isCompleted: true },
{ title: 'Basic Design theory', time: '5.9 min', isCompleted: false },
{ title: 'Basic Fundamentals', time: '3.6 min', isCompleted: false },
{ title: 'What is ui/ux', time: '10.6 min', isCompleted: false },
],
},
{
title: 'Web design for Developers',
status: '0/4',
time: '4.8 min',
id: 'section2',
topics: [
{ title: 'How to use Pages in Figma', time: '8:31 min', isCompleted: false },
{ title: 'What is Lo Fi Wireframe', time: '2 min', isCompleted: false },
{ title: 'How to use color in Figma', time: '5.9 min', isCompleted: false },
{ title: 'Frames vs Groups in Figma', time: '3.6 min', isCompleted: false },
],
},
{
title: 'Build Beautiful Websites!',
status: '0/4',
time: '4.4 min',
id: 'section3',
topics: [
{ title: 'Section & Div Block', time: '3:53 min', isCompleted: false },
{ title: 'Read-Only Version of Chat App', time: '2:03 min', isCompleted: false },
{ title: 'Webflow Autosave', time: '8 min', isCompleted: false },
{ title: 'Canvas Settings', time: '3 min', isCompleted: false },
{ title: 'HTML Tags', time: '10 min', isCompleted: false },
{ title: 'Footer (Chat App)', time: '9:10 min', isCompleted: false },
],
},
{
title: 'Final Project',
status: '0/3',
time: '4.4 min',
id: 'section4',
topics: [
{ title: 'Responsive Blog Site', time: '10:00 min', isCompleted: false },
{ title: 'Responsive Portfolio', time: '13:00 min', isCompleted: false },
{ title: 'Basic Design theory', time: '15 min', isCompleted: false },
],
},
],
},
}

View File

@@ -0,0 +1,66 @@
import is from '@sindresorhus/is'
import destr from 'destr'
import { rest } from 'msw'
import { db } from '@db/apps/academy/db'
import { paginateArray } from '@api-utils/paginateArray'
export const handlerAppsAcademy = [
// 👉 Course
rest.get(('/api/apps/academy/courses'), (req, res, ctx) => {
const q = req.url.searchParams.get('q')
const label = req.url.searchParams.get('label') || 'All Courses'
const hideCompleted = req.url.searchParams.get('hideCompleted')
const page = req.url.searchParams.get('page')
const itemsPerPage = req.url.searchParams.get('itemsPerPage')
const sortBy = req.url.searchParams.get('sortBy')
const orderBy = req.url.searchParams.get('orderBy')
const searchQuery = is.string(q) ? q : undefined
const queryLowered = (searchQuery ?? '').toString().toLowerCase()
const parsedHideCompleted = destr(hideCompleted)
const hideCompletedLocal = is.boolean(parsedHideCompleted) ? parsedHideCompleted : false
const parsedSortBy = destr(sortBy)
const sortByLocal = is.string(parsedSortBy) ? parsedSortBy : ''
const parsedOrderBy = destr(orderBy)
const orderByLocal = is.string(parsedOrderBy) ? parsedOrderBy : ''
const parsedItemsPerPage = destr(itemsPerPage)
const parsedPage = destr(page)
const itemsPerPageLocal = is.number(parsedItemsPerPage) ? parsedItemsPerPage : 10
const pageLocal = is.number(parsedPage) ? parsedPage : 1
const filteredCourses = db.courses.filter(course => {
return ((course.courseTitle.toLowerCase().includes(queryLowered)
|| course.user.toLowerCase().includes(queryLowered))
&& !((course.completedTasks === course.totalTasks) && hideCompletedLocal)
&& (label !== 'All Courses' ? course.tags.toLocaleLowerCase() === label?.toLowerCase() : true))
})
if (sortByLocal) {
if (sortByLocal === 'courseName') {
filteredCourses.sort((a, b) => {
if (orderByLocal === 'asc')
return a.courseTitle.localeCompare(b.courseTitle)
else
return b.courseTitle.localeCompare(a.courseTitle)
})
}
if (sortByLocal === 'progress') {
filteredCourses.sort((a, b) => {
if (orderByLocal === 'asc')
return (a.completedTasks / a.totalTasks) - (b.completedTasks / b.totalTasks)
else
return (b.completedTasks / b.totalTasks) - (a.completedTasks / a.totalTasks)
})
}
}
return res(ctx.status(200), ctx.json({
courses: paginateArray(filteredCourses, itemsPerPageLocal, pageLocal),
total: filteredCourses.length,
}))
}),
// 👉 Course Details
rest.get(('/api/apps/academy/course-details'), (req, res, ctx) => {
return res(ctx.status(200), ctx.json(db.courseDetails))
}),
]

View File

@@ -0,0 +1 @@
export {}

View File

@@ -0,0 +1,118 @@
const date = new Date()
const nextDay = new Date(new Date().getTime() + 24 * 60 * 60 * 1000)
const nextMonth = date.getMonth() === 11 ? new Date(date.getFullYear() + 1, 0, 1) : new Date(date.getFullYear(), date.getMonth() + 1, 1)
const prevMonth = date.getMonth() === 11 ? new Date(date.getFullYear() - 1, 0, 1) : new Date(date.getFullYear(), date.getMonth() - 1, 1)
export const db = {
events: [
{
id: 1,
url: '',
title: 'Design Review',
start: date,
end: nextDay,
allDay: false,
extendedProps: {
calendar: 'Business',
},
},
{
id: 2,
url: '',
title: 'Meeting With Client',
start: new Date(date.getFullYear(), date.getMonth() + 1, -11),
end: new Date(date.getFullYear(), date.getMonth() + 1, -10),
allDay: true,
extendedProps: {
calendar: 'Business',
},
},
{
id: 3,
url: '',
title: 'Family Trip',
allDay: true,
start: new Date(date.getFullYear(), date.getMonth() + 1, -9),
end: new Date(date.getFullYear(), date.getMonth() + 1, -7),
extendedProps: {
calendar: 'Holiday',
},
},
{
id: 4,
url: '',
title: 'Doctor\'s Appointment',
start: new Date(date.getFullYear(), date.getMonth() + 1, -11),
end: new Date(date.getFullYear(), date.getMonth() + 1, -10),
allDay: true,
extendedProps: {
calendar: 'Personal',
},
},
{
id: 5,
url: '',
title: 'Dart Game?',
start: new Date(date.getFullYear(), date.getMonth() + 1, -13),
end: new Date(date.getFullYear(), date.getMonth() + 1, -12),
allDay: true,
extendedProps: {
calendar: 'ETC',
},
},
{
id: 6,
url: '',
title: 'Meditation',
start: new Date(date.getFullYear(), date.getMonth() + 1, -13),
end: new Date(date.getFullYear(), date.getMonth() + 1, -12),
allDay: true,
extendedProps: {
calendar: 'Personal',
},
},
{
id: 7,
url: '',
title: 'Dinner',
start: new Date(date.getFullYear(), date.getMonth() + 1, -13),
end: new Date(date.getFullYear(), date.getMonth() + 1, -12),
allDay: true,
extendedProps: {
calendar: 'Family',
},
},
{
id: 8,
url: '',
title: 'Product Review',
start: new Date(date.getFullYear(), date.getMonth() + 1, -13),
end: new Date(date.getFullYear(), date.getMonth() + 1, -12),
allDay: true,
extendedProps: {
calendar: 'Business',
},
},
{
id: 9,
url: '',
title: 'Monthly Meeting',
start: nextMonth,
end: nextMonth,
allDay: true,
extendedProps: {
calendar: 'Business',
},
},
{
id: 10,
url: '',
title: 'Monthly Checkup',
start: prevMonth,
end: prevMonth,
allDay: true,
extendedProps: {
calendar: 'Personal',
},
},
],
}

View File

@@ -0,0 +1,63 @@
import is from '@sindresorhus/is'
import destr from 'destr'
import { rest } from 'msw'
import { db } from '@db/apps/calendar/db'
import { genId } from '@api-utils/genId'
export const handlerAppsCalendar = [
// 👉 Get Calendar Events
rest.get(('/api/apps/calendar'), (req, res, ctx) => {
const queries = req.url.searchParams.getAll('calendars')
const parsedCalendars = destr(queries)
const calendars = is.array(parsedCalendars) ? parsedCalendars : undefined
const events = db.events.filter(event => calendars?.includes(event.extendedProps.calendar))
return res(ctx.status(200), ctx.json(events))
}),
// 👉 Add Calendar Event
rest.post(('/api/apps/calendar'), async (req, res, ctx) => {
const event = await req.json()
db.events.push({
...event,
id: genId(db.events),
})
return res(ctx.status(200), ctx.json(event))
}),
// 👉 Update Calendar Event
rest.put(('/api/apps/calendar/:id'), async (req, res, ctx) => {
const updatedEvent = await req.json()
updatedEvent.id = Number(updatedEvent.id)
const eventId = Number(req.params.id)
// Find the index of the event in the database
const currentEvent = db.events.find(e => e.id === eventId)
// update event
if (currentEvent) {
Object.assign(currentEvent, updatedEvent)
return res(ctx.status(200), ctx.json(currentEvent))
}
return res(ctx.status(400), ctx.json({ message: 'Something Went Wrong' }))
}),
// 👉 Delete Calendar Event
rest.delete(('/api/apps/calendar/:id'), (req, res, ctx) => {
const eventId = Number(req.params.id)
const eventIndex = db.events.findIndex(e => e.id === eventId)
if (eventIndex !== -1) {
db.events.splice(eventIndex, 1)
return res(ctx.status(204))
}
return res(ctx.status(400), ctx.json({ message: 'Something Went Wrong' }))
}),
]

View File

@@ -0,0 +1 @@
export {}

View File

@@ -0,0 +1,282 @@
import avatar1 from '@images/avatars/avatar-1.png'
import avatar2 from '@images/avatars/avatar-2.png'
import avatar3 from '@images/avatars/avatar-3.png'
import avatar4 from '@images/avatars/avatar-4.png'
import avatar5 from '@images/avatars/avatar-5.png'
import avatar6 from '@images/avatars/avatar-6.png'
import avatar8 from '@images/avatars/avatar-8.png'
const previousDay = new Date(new Date().getTime() - 24 * 60 * 60 * 1000)
const dayBeforePreviousDay = new Date(new Date().getTime() - 24 * 60 * 60 * 1000 * 2)
export const db = {
profileUser: {
id: 11,
avatar: avatar1,
fullName: 'John Doe',
role: 'admin',
about: 'Dessert chocolate cake lemon drops jujubes. Biscuit cupcake ice cream bear claw brownie marshmallow.',
status: 'online',
settings: {
isTwoStepAuthVerificationEnabled: true,
isNotificationsOn: false,
},
},
contacts: [
{
id: 1,
fullName: 'Gavin Griffith',
role: 'Frontend Developer',
about: 'Cake pie jelly jelly beans. Marzipan lemon drops halvah cake. Pudding cookie lemon drops icing',
avatar: avatar5,
status: 'offline',
},
{
id: 2,
fullName: 'Harriet McBride',
role: 'UI/UX Designer',
about: 'Toffee caramels jelly-o tart gummi bears cake I love ice cream lollipop. Sweet liquorice croissant candy danish dessert icing. Cake macaroon gingerbread toffee sweet.',
avatar: avatar2,
status: 'busy',
},
{
id: 3,
fullName: 'Danny Conner',
role: 'Town planner',
about: 'Soufflé soufflé caramels sweet roll. Jelly lollipop sesame snaps bear claw jelly beans sugar plum sugar plum.',
avatar: '',
status: 'busy',
},
{
id: 4,
fullName: 'Janie West',
role: 'Data scientist',
about: 'Chupa chups candy canes chocolate bar marshmallow liquorice muffin. Lemon drops oat cake tart liquorice tart cookie. Jelly-o cookie tootsie roll halvah.',
avatar: '',
status: 'online',
},
{
id: 5,
fullName: 'Bryan Murray',
role: 'Dietitian',
about: 'Cake pie jelly jelly beans. Marzipan lemon drops halvah cake. Pudding cookie lemon drops icing',
avatar: avatar5,
status: 'busy',
},
{
id: 6,
fullName: 'Albert Underwood',
role: 'Marketing executive',
about: 'Toffee caramels jelly-o tart gummi bears cake I love ice cream lollipop. Sweet liquorice croissant candy danish dessert icing. Cake macaroon gingerbread toffee sweet.',
avatar: avatar6,
status: 'online',
},
{
id: 7,
fullName: 'Adele Ross',
role: 'Special educational needs teacher',
about: 'Biscuit powder oat cake donut brownie ice cream I love soufflé. I love tootsie roll I love powder tootsie roll.',
avatar: '',
status: 'online',
},
{
id: 8,
fullName: 'Mark Berry',
role: 'Advertising copywriter',
about: 'Bear claw ice cream lollipop gingerbread carrot cake. Brownie gummi bears chocolate muffin croissant jelly I love marzipan wafer.',
avatar: avatar3,
status: 'away',
},
{
id: 9,
fullName: 'Joseph Evans',
role: 'Designer, television/film set',
about: 'Gummies gummi bears I love candy icing apple pie I love marzipan bear claw. I love tart biscuit I love candy canes pudding chupa chups liquorice croissant.',
avatar: avatar8,
status: 'offline',
},
{
id: 10,
fullName: 'Blake Carter',
role: 'Building surveyor',
about: 'Cake pie jelly jelly beans. Marzipan lemon drops halvah cake. Pudding cookie lemon drops icing',
avatar: avatar4,
status: 'away',
},
],
chats: [
{
id: 1,
userId: 2,
unseenMsgs: 0,
messages: [
{
message: 'Hi',
time: 'Mon Dec 10 2018 07:45:00 GMT+0000 (GMT)',
senderId: 11,
feedback: {
isSent: true,
isDelivered: true,
isSeen: true,
},
},
{
message: 'Hello. How can I help You?',
time: 'Mon Dec 11 2018 07:45:15 GMT+0000 (GMT)',
senderId: 2,
feedback: {
isSent: true,
isDelivered: true,
isSeen: true,
},
},
{
message: 'Can I get details of my last transaction I made last month? 🤔',
time: 'Mon Dec 11 2018 07:46:10 GMT+0000 (GMT)',
senderId: 11,
feedback: {
isSent: true,
isDelivered: true,
isSeen: true,
},
},
{
message: 'We need to check if we can provide you such information.',
time: 'Mon Dec 11 2018 07:45:15 GMT+0000 (GMT)',
senderId: 2,
feedback: {
isSent: true,
isDelivered: true,
isSeen: true,
},
},
{
message: 'I will inform you as I get update on this.',
time: 'Mon Dec 11 2018 07:46:15 GMT+0000 (GMT)',
senderId: 2,
feedback: {
isSent: true,
isDelivered: true,
isSeen: true,
},
},
{
message: 'If it takes long you can mail me at my mail address.',
time: String(dayBeforePreviousDay),
senderId: 11,
feedback: {
isSent: true,
isDelivered: false,
isSeen: false,
},
},
],
},
{
id: 2,
userId: 1,
unseenMsgs: 1,
messages: [
{
message: 'How can we help? We\'re here for you!',
time: 'Mon Dec 10 2018 07:45:00 GMT+0000 (GMT)',
senderId: 11,
feedback: {
isSent: true,
isDelivered: true,
isSeen: true,
},
},
{
message: 'Hey John, I am looking for the best admin template. Could you please help me to find it out?',
time: 'Mon Dec 10 2018 07:45:23 GMT+0000 (GMT)',
senderId: 1,
feedback: {
isSent: true,
isDelivered: true,
isSeen: true,
},
},
{
message: 'It should use nice Framework.',
time: 'Mon Dec 10 2018 07:45:55 GMT+0000 (GMT)',
senderId: 1,
feedback: {
isSent: true,
isDelivered: true,
isSeen: true,
},
},
{
message: 'Absolutely!',
time: 'Mon Dec 10 2018 07:46:00 GMT+0000 (GMT)',
senderId: 11,
feedback: {
isSent: true,
isDelivered: true,
isSeen: true,
},
},
{
message: 'Our admin is the responsive admin template.!',
time: 'Mon Dec 10 2018 07:46:05 GMT+0000 (GMT)',
senderId: 11,
feedback: {
isSent: true,
isDelivered: true,
isSeen: true,
},
},
{
message: 'Looks clean and fresh UI. 😍',
time: 'Mon Dec 10 2018 07:46:23 GMT+0000 (GMT)',
senderId: 1,
feedback: {
isSent: true,
isDelivered: true,
isSeen: true,
},
},
{
message: 'It\'s perfect for my next project.',
time: 'Mon Dec 10 2018 07:46:33 GMT+0000 (GMT)',
senderId: 1,
feedback: {
isSent: true,
isDelivered: true,
isSeen: true,
},
},
{
message: 'How can I purchase it?',
time: 'Mon Dec 10 2018 07:46:43 GMT+0000 (GMT)',
senderId: 1,
feedback: {
isSent: true,
isDelivered: true,
isSeen: true,
},
},
{
message: 'Thanks, From our official site 😇',
time: 'Mon Dec 10 2018 07:46:53 GMT+0000 (GMT)',
senderId: 11,
feedback: {
isSent: true,
isDelivered: true,
isSeen: true,
},
},
{
message: 'I will purchase it for sure. 👍',
time: String(previousDay),
senderId: 1,
feedback: {
isSent: true,
isDelivered: true,
isSeen: true,
},
},
],
},
],
}

View File

@@ -0,0 +1,81 @@
import { rest } from 'msw'
import { db } from '@db/apps/chat/db'
export const handlerAppsChat = [
rest.get(('/api/apps/chat/chats-and-contacts'), (req, res, ctx) => {
const q = req.url.searchParams.get('q') || ''
const qLowered = q.toLowerCase()
const chatsContacts = db.chats
.map(chat => {
const contact = JSON.parse(JSON.stringify(db.contacts.find(c => c.id === chat.userId)))
contact.chat = { id: chat.id, unseenMsgs: chat.unseenMsgs, lastMessage: chat.messages.at(-1) }
return contact
})
.reverse()
const profileUserData = db.profileUser
const response = {
chatsContacts: chatsContacts.filter(c => c.fullName.toLowerCase().includes(qLowered)),
contacts: db.contacts.filter(c => c.fullName.toLowerCase().includes(qLowered)),
profileUser: profileUserData,
}
return res(ctx.status(200), ctx.json(response))
}),
rest.get(('/api/apps/chat/chats/:userId'), (req, res, ctx) => {
const userId = Number(req.params.userId)
const chat = db.chats.find(e => e.userId === userId)
if (chat)
chat.unseenMsgs = 0
return res(ctx.status(200), ctx.json({
chat,
contact: db.contacts.find(c => c.id === userId),
}))
}),
rest.post(('/api/apps/chat/chats/:userId'), async (req, res, ctx) => {
// Get user id from URL
const chatId = Number(req.params.userId)
// Get message from post data
const { message, senderId } = await req.json()
let activeChat = db.chats.find(chat => chat.userId === chatId)
const newMessageData = {
message,
time: String(new Date()),
senderId,
feedback: {
isSent: true,
isDelivered: false,
isSeen: false,
},
}
// If there's new chat for user create one
let isNewChat = false
if (activeChat === undefined) {
isNewChat = true
db.chats.push({
id: db.chats.length + 1,
userId: chatId,
unseenMsgs: 0,
messages: [newMessageData],
})
activeChat = db.chats.at(-1)
}
else {
activeChat.messages.push(newMessageData)
}
const response = { msg: newMessageData }
if (isNewChat)
response.chat = activeChat
return res(ctx.status(201), ctx.json(response))
}),
]

View File

@@ -0,0 +1 @@
export {}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,460 @@
import is from '@sindresorhus/is'
import { destr } from 'destr'
import { rest } from 'msw'
import { db } from '@db/apps/ecommerce/db'
import { paginateArray } from '@api-utils/paginateArray'
export const handlerAppsEcommerce = [
// 👉 Products
// Get Product List
rest.get('/api/apps/ecommerce/products', (req, res, ctx) => {
const q = req.url.searchParams.get('q')
const stock = req.url.searchParams.get('stock')
const category = req.url.searchParams.get('category')
const status = req.url.searchParams.get('status')
const sortBy = req.url.searchParams.get('sortBy')
const orderBy = req.url.searchParams.get('orderBy')
const itemsPerPage = req.url.searchParams.get('itemsPerPage')
const page = req.url.searchParams.get('page')
const searchQuery = is.string(q) ? q : undefined
const queryLower = (searchQuery ?? '').toString().toLowerCase()
const parsedStock = destr(stock)
const stockLocal = is.boolean(parsedStock) ? parsedStock : undefined
const parsedSortBy = destr(sortBy)
const sortByLocal = is.string(parsedSortBy) ? parsedSortBy : ''
const parsedOrderBy = destr(orderBy)
const orderByLocal = is.string(parsedOrderBy) ? parsedOrderBy : ''
const parsedItemsPerPage = destr(itemsPerPage)
const parsedPage = destr(page)
const itemsPerPageLocal = is.number(parsedItemsPerPage) ? parsedItemsPerPage : 10
const pageLocal = is.number(parsedPage) ? parsedPage : 1
// Filtering Products
let filteredProducts = db.products.filter(product => ((product.productName.toLowerCase().includes(queryLower) || product.productBrand.toLowerCase().includes(queryLower))
&& product.category === (category || product.category)
&& (product.status === (status || product.status))
&& (typeof stockLocal === 'undefined' ? true : (product.stock === stockLocal)))).reverse()
// Sort
if (sortByLocal) {
if (sortByLocal === 'product') {
filteredProducts = filteredProducts.sort((a, b) => {
if (orderByLocal === 'asc')
return a.productName.toLowerCase() > b.productName.toLowerCase() ? 1 : -1
else if (orderByLocal === 'desc')
return a.productName.toLowerCase() < b.productName.toLowerCase() ? 1 : -1
return 0
})
}
if (sortByLocal === 'category') {
filteredProducts = filteredProducts.sort((a, b) => {
if (orderByLocal === 'asc')
return a.category > b.category ? 1 : -1
else if (orderByLocal === 'desc')
return a.category < b.category ? 1 : -1
return 0
})
}
if (sortByLocal === 'status') {
filteredProducts = filteredProducts.sort((a, b) => {
if (orderByLocal === 'asc')
return a.status > b.status ? 1 : -1
else if (orderByLocal === 'desc')
return a.status < b.status ? 1 : -1
return 0
})
}
if (sortByLocal === 'price') {
filteredProducts = filteredProducts.sort((a, b) => {
if (orderByLocal === 'asc')
return Number(a.price.slice(1)) > Number(b.price.slice(1)) ? 1 : -1
else if (orderByLocal === 'desc')
return Number(a.price.slice(1)) < Number(b.price.slice(1)) ? 1 : -1
return 0
})
}
if (sortByLocal === 'qty') {
filteredProducts = filteredProducts.sort((a, b) => {
if (orderByLocal === 'asc')
return a.qty > b.qty ? 1 : -1
else if (orderByLocal === 'desc')
return a.qty < b.qty ? 1 : -1
return 0
})
}
if (sortByLocal === 'sku') {
filteredProducts = filteredProducts.sort((a, b) => {
if (orderByLocal === 'asc')
return a.sku > b.sku ? 1 : -1
else if (orderByLocal === 'desc')
return a.sku < b.sku ? 1 : -1
return 0
})
}
}
return res(ctx.status(200), ctx.json({
products: paginateArray(filteredProducts, itemsPerPageLocal, pageLocal), total: filteredProducts.length,
}))
}),
// 👉 Delete Product
rest.delete('/api/apps/ecommerce/products/:id', (req, res, ctx) => {
const id = Number(req.params.id)
const productIndex = db.products.findIndex(e => e.id === id)
if (productIndex >= 0) {
db.products.splice(productIndex, 1)
return res(ctx.status(204))
}
return res(ctx.status(404))
}),
// 👉 Orders
// Get Order List
rest.get('/api/apps/ecommerce/orders', (req, res, ctx) => {
const q = req.url.searchParams.get('q')
const sortBy = req.url.searchParams.get('sortBy')
const orderBy = req.url.searchParams.get('orderBy')
const itemsPerPage = req.url.searchParams.get('itemsPerPage')
const page = req.url.searchParams.get('page')
const searchQuery = is.string(q) ? q : undefined
const queryLower = (searchQuery ?? '').toString().toLowerCase()
const parsedSortBy = destr(sortBy)
const sortByLocal = is.string(parsedSortBy) ? parsedSortBy : ''
const parsedOrderBy = destr(orderBy)
const orderByLocal = is.string(parsedOrderBy) ? parsedOrderBy : ''
const parsedItemsPerPage = destr(itemsPerPage)
const parsedPage = destr(page)
const itemsPerPageLocal = is.number(parsedItemsPerPage) ? parsedItemsPerPage : 10
const pageLocal = is.number(parsedPage) ? parsedPage : 1
const filterOrders = db.orderData.filter(order => {
return (order.customer.toLowerCase().includes(queryLower)
|| order.email.toLowerCase().includes(queryLower)
|| order.order.toString().includes(queryLower))
}).reverse()
if (sortByLocal) {
if (sortByLocal === 'order') {
filterOrders.sort((a, b) => {
if (orderByLocal === 'desc')
return b.order - a.order
else
return a.order - b.order
})
}
if (sortByLocal === 'customers') {
filterOrders.sort((a, b) => {
if (orderByLocal === 'desc')
return b.customer.localeCompare(a.customer)
else
return a.customer.localeCompare(b.customer)
})
}
if (sortByLocal === 'date') {
filterOrders.sort((a, b) => {
if (orderByLocal === 'desc')
return Number(new Date(b.date)) - Number(new Date(a.date))
else
return Number(new Date(a.date)) - Number(new Date(b.date))
})
}
if (sortByLocal === 'status') {
filterOrders.sort((a, b) => {
if (orderByLocal === 'desc')
return b.status.localeCompare(a.status)
else
return a.status.localeCompare(b.status)
})
}
}
if (sortByLocal === 'spent') {
filterOrders.sort((a, b) => {
if (orderByLocal === 'desc')
return Number(b.spent) - Number(a.spent)
else
return Number(a.spent) - Number(b.spent)
})
}
return res(ctx.status(200), ctx.json({
orders: paginateArray(filterOrders, itemsPerPageLocal, pageLocal), total: filterOrders.length,
}))
}),
// Delete Order
rest.delete('/api/apps/ecommerce/orders/:id', (req, res, ctx) => {
const id = Number(req.params.id)
const orderIndex = db.orderData.findIndex(e => e.id === id)
if (orderIndex >= 0)
db.orderData.splice(orderIndex, 1)
return res(ctx.status(204))
}),
// 👉 Customers
// Get single Customer
rest.get(('/api/apps/ecommerce/customers/:id'), (req, res, ctx) => {
const customerId = Number(req.params.id)
const customerIndex = db.customerData.findIndex(e => e.customerId === customerId)
const customer = db.customerData[customerIndex]
Object.assign(customer, {
status: 'Active',
contact: '+1 (234) 567 890',
})
if (customer) {
return res(ctx.status(200), ctx.json(customer))
}
else {
return res(ctx.status(404))
}
}),
// Get Customer List
rest.get(('/api/apps/ecommerce/customers'), (req, res, ctx) => {
const q = req.url.searchParams.get('q')
const sortBy = req.url.searchParams.get('sortBy')
const orderBy = req.url.searchParams.get('orderBy')
const itemsPerPage = req.url.searchParams.get('itemsPerPage')
const page = req.url.searchParams.get('page')
const parsedSortBy = destr(sortBy)
const sortByLocal = is.string(parsedSortBy) ? parsedSortBy : ''
const parsedOrderBy = destr(orderBy)
const orderByLocal = is.string(parsedOrderBy) ? parsedOrderBy : ''
const parsedItemsPerPage = destr(itemsPerPage)
const parsedPage = destr(page)
const itemsPerPageLocal = is.number(parsedItemsPerPage) ? parsedItemsPerPage : 10
const pageLocal = is.number(parsedPage) ? parsedPage : 1
const searchQuery = is.string(q) ? q : undefined
const queryLowered = (searchQuery ?? '').toString().toLowerCase()
const filteredCustomers = db.customerData.filter(customer => {
return (customer.customer.toLowerCase().includes(queryLowered)
|| customer.country.toLowerCase().includes(queryLowered)
|| customer.email.toLowerCase().includes(queryLowered))
}).reverse()
// Sort Customers
if (sortByLocal) {
if (sortByLocal === 'customer') {
filteredCustomers.sort((a, b) => {
if (orderByLocal === 'asc')
return a.customer.localeCompare(b.customer)
return b.customer.localeCompare(a.customer)
})
}
if (sortByLocal === 'country') {
filteredCustomers.sort((a, b) => {
if (orderByLocal === 'asc')
return a.country.localeCompare(b.country)
return b.country.localeCompare(a.country)
})
}
if (sortByLocal === 'customerId') {
filteredCustomers.sort((a, b) => {
if (orderByLocal === 'asc')
return a.customerId - b.customerId
return b.customerId - a.customerId
})
}
if (sortByLocal === 'orders') {
filteredCustomers.sort((a, b) => {
if (orderByLocal === 'asc')
return a.order - b.order
return b.order - a.order
})
}
}
if (sortByLocal === 'totalSpent') {
filteredCustomers.sort((a, b) => {
if (orderByLocal === 'asc')
return a.totalSpent - b.totalSpent
return b.totalSpent - a.totalSpent
})
}
return res(ctx.status(200), ctx.json({
customers: paginateArray(filteredCustomers, itemsPerPageLocal, pageLocal), total: filteredCustomers.length,
}))
}),
// 👉 Manage Reviews.
// Get Reviews
rest.get(('/api/apps/ecommerce/reviews'), (req, res, ctx) => {
const q = req.url.searchParams.get('q')
const sortBy = req.url.searchParams.get('sortBy')
const orderBy = req.url.searchParams.get('orderBy')
const itemsPerPage = req.url.searchParams.get('itemsPerPage')
const status = req.url.searchParams.get('status')
const page = req.url.searchParams.get('page')
const parsedSortBy = destr(sortBy)
const sortByLocal = is.string(parsedSortBy) ? parsedSortBy : ''
const parsedOrderBy = destr(orderBy)
const orderByLocal = is.string(parsedOrderBy) ? parsedOrderBy : ''
const parsedItemsPerPage = destr(itemsPerPage)
const parsedPage = destr(page)
const itemsPerPageLocal = is.number(parsedItemsPerPage) ? parsedItemsPerPage : 10
const pageLocal = is.number(parsedPage) ? parsedPage : 1
const searchQuery = is.string(q) ? q : undefined
const queryLower = (searchQuery ?? '').toString().toLowerCase()
// Filtering Reviews
const filteredReviews = db.reviews.filter(review => {
const { product, reviewer, email } = review
return ((product.toLowerCase().includes(queryLower) || reviewer.toLowerCase().includes(queryLower) || email.toLowerCase().includes(queryLower) || review.head.toLowerCase().includes(queryLower) || review.para.toLowerCase().includes(queryLower))
&& (review.status === status || status === 'All'))
})
// Sort
if (sortByLocal) {
if (sortByLocal === 'product') {
filteredReviews.sort((a, b) => {
if (orderByLocal === 'asc')
return a.product.toLowerCase() > b.product.toLowerCase() ? 1 : -1
else if (orderByLocal === 'desc')
return a.product.toLowerCase() < b.product.toLowerCase() ? 1 : -1
return 0
})
}
if (sortByLocal === 'reviewer') {
filteredReviews.sort((a, b) => {
if (orderByLocal === 'asc')
return a.reviewer.toLowerCase() > b.reviewer.toLowerCase() ? 1 : -1
else if (orderByLocal === 'desc')
return a.reviewer.toLowerCase() < b.reviewer.toLowerCase() ? 1 : -1
return 0
})
}
if (sortByLocal === 'date') {
filteredReviews.sort((a, b) => {
if (orderByLocal === 'desc')
return Number(new Date(b.date)) - Number(new Date(a.date))
else if (orderByLocal === 'asc')
return Number(new Date(a.date)) - Number(new Date(b.date))
return 0
})
}
}
if (sortByLocal === 'status') {
filteredReviews.sort((a, b) => {
if (orderByLocal === 'asc')
return a.status.toLowerCase() > b.status.toLowerCase() ? 1 : -1
else if (orderByLocal === 'desc')
return a.status.toLowerCase() < b.status.toLowerCase() ? 1 : -1
else
return 0
})
}
return res(ctx.status(200), ctx.json({
reviews: paginateArray(filteredReviews, itemsPerPageLocal, pageLocal), total: filteredReviews.length,
}))
}),
// Delete Review
rest.delete(('/api/apps/ecommerce/reviews/:id'), (req, res, ctx) => {
const id = Number(req.params.id)
const reviewIndex = db.reviews.findIndex(e => e.id === id)
if (reviewIndex !== -1) {
db.reviews.splice(reviewIndex, 1)
return res(ctx.status(200))
}
return res(ctx.status(404))
}),
// 👉 Referrals
// Get Referrals
rest.get(('/api/apps/ecommerce/referrals'), (req, res, ctx) => {
const sortBy = req.url.searchParams.get('sortBy')
const orderBy = req.url.searchParams.get('orderBy')
const itemsPerPage = req.url.searchParams.get('itemsPerPage')
const page = req.url.searchParams.get('page')
const parsedSortBy = destr(sortBy)
const sortByLocal = is.string(parsedSortBy) ? parsedSortBy : ''
const parsedOrderBy = destr(orderBy)
const orderByLocal = is.string(parsedOrderBy) ? parsedOrderBy : ''
const parsedItemsPerPage = destr(itemsPerPage)
const parsedPage = destr(page)
const itemsPerPageLocal = is.number(parsedItemsPerPage) ? parsedItemsPerPage : 10
const pageLocal = is.number(parsedPage) ? parsedPage : 1
const filteredReferrals = [...db.referrals]
if (sortByLocal) {
if (sortByLocal === 'users') {
filteredReferrals.sort((a, b) => {
if (orderByLocal === 'asc')
return a.user.localeCompare(b.user)
else
return b.user.localeCompare(a.user)
})
}
if (sortByLocal === 'referred-id') {
filteredReferrals.sort((a, b) => {
if (orderByLocal === 'asc')
return a.referredId - b.referredId
else if (orderByLocal === 'desc')
return b.referredId - a.referredId
return 0
})
}
if (sortByLocal === 'earning') {
filteredReferrals.sort((a, b) => {
if (orderByLocal === 'asc')
return Number(a.earning.slice(1)) - Number(b.earning.slice(1))
else if (orderByLocal === 'desc')
return Number(b.earning.slice(1)) - Number(a.earning.slice(1))
return 0
})
}
if (sortByLocal === 'value') {
filteredReferrals.sort((a, b) => {
if (orderByLocal === 'asc')
return Number(a.value.slice(1)) - Number(b.value.slice(1))
else if (orderByLocal === 'desc')
return Number(b.value.slice(1)) - Number(a.value.slice(1))
return 0
})
}
if (sortByLocal === 'status') {
filteredReferrals.sort((a, b) => {
if (orderByLocal === 'asc')
return a.status.toLowerCase() > b.status.toLowerCase() ? 1 : -1
else if (orderByLocal === 'desc')
return a.status.toLowerCase() < b.status.toLowerCase() ? 1 : -1
return 0
})
}
}
return res(ctx.status(200), ctx.json({
referrals: paginateArray(filteredReferrals, itemsPerPageLocal, pageLocal),
total: filteredReferrals.length,
}))
}),
]

View File

@@ -0,0 +1 @@
export {}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,70 @@
import { destr } from 'destr'
import { rest } from 'msw'
import { db } from '@db/apps/email/db'
export const handlerAppsEmail = [
// 👉 Get Email List
rest.get(('/api/apps/email'), (req, res, ctx) => {
const q = req.url.searchParams.get('q') || ''
const filter = req.url.searchParams.get('filter') || 'inbox'
const label = req.url.searchParams.get('label') || ''
const queryLowered = q.toLowerCase()
function isInFolder(email) {
if (filter === 'trashed')
return email.isDeleted
if (filter === 'starred')
return email.isStarred && !email.isDeleted
return email.folder === (filter || email.folder) && !email.isDeleted
}
const filteredData = db.emails.filter(email => (email.from.name.toLowerCase().includes(queryLowered) || email.subject.toLowerCase().includes(queryLowered))
&& isInFolder(email)
&& (label ? email.labels.includes(label) : true))
// ------------------------------------------------
// Email Meta
// ------------------------------------------------
const emailsMeta = {
inbox: db.emails.filter(email => !email.isDeleted && !email.isRead && email.folder === 'inbox').length,
draft: db.emails.filter(email => email.folder === 'draft').length,
spam: db.emails.filter(email => !email.isDeleted && !email.isRead && email.folder === 'spam').length,
}
return res(ctx.status(200), ctx.json({ emails: filteredData, emailsMeta }))
}),
// 👉 Update Email Meta
rest.post(('/api/apps/email'), async (req, res, ctx) => {
const { ids, data, label } = await req.json()
const labelLocal = destr(label)
if (!labelLocal) {
const emailIdsLocal = destr(ids)
function updateMailData(email) {
Object.assign(email, data)
}
db.emails.forEach(email => {
if (emailIdsLocal.includes(email.id))
updateMailData(email)
})
return res(ctx.status(200))
}
else {
function updateMailLabels(email) {
const labelIndex = email.labels.indexOf(label)
if (labelIndex === -1)
email.labels.push(label)
else
email.labels.splice(labelIndex, 1)
}
db.emails.forEach(email => {
if (Array.isArray(ids) ? ids.includes(email.id) : ids === email.id)
updateMailLabels(email)
})
return res(ctx.status(200))
}
}),
]

View File

@@ -0,0 +1 @@
export {}

View File

@@ -0,0 +1,913 @@
import avatar1 from '@images/avatars/avatar-1.png'
import avatar2 from '@images/avatars/avatar-2.png'
import avatar3 from '@images/avatars/avatar-3.png'
import avatar4 from '@images/avatars/avatar-4.png'
import avatar5 from '@images/avatars/avatar-5.png'
import avatar6 from '@images/avatars/avatar-6.png'
import avatar7 from '@images/avatars/avatar-7.png'
import avatar8 from '@images/avatars/avatar-8.png'
const now = new Date()
const currentMonth = now.toLocaleString('default', { month: '2-digit' })
export const database = [
{
id: 4987,
issuedDate: `${now.getFullYear()}-${currentMonth}-13`,
client: {
address: '7777 Mendez Plains',
company: 'Hall-Robbins PLC',
companyEmail: 'don85@johnson.com',
country: 'USA',
contact: '(616) 865-4180',
name: 'Jordan Stevenson',
},
service: 'Software Development',
total: 3428,
avatar: '',
invoiceStatus: 'Paid',
balance: 724,
dueDate: `${now.getFullYear()}-${currentMonth}-23`,
},
{
id: 4988,
issuedDate: `${now.getFullYear()}-${currentMonth}-17`,
client: {
address: '04033 Wesley Wall Apt. 961',
company: 'Mccann LLC and Sons',
companyEmail: 'brenda49@taylor.info',
country: 'Haiti',
contact: '(226) 204-8287',
name: 'Stephanie Burns',
},
service: 'UI/UX Design & Development',
total: 5219,
avatar: avatar1,
invoiceStatus: 'Downloaded',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-15`,
},
{
id: 4989,
issuedDate: `${now.getFullYear()}-${currentMonth}-19`,
client: {
address: '5345 Robert Squares',
company: 'Leonard-Garcia and Sons',
companyEmail: 'smithtiffany@powers.com',
country: 'Denmark',
contact: '(955) 676-1076',
name: 'Tony Herrera',
},
service: 'Unlimited Extended License',
total: 3719,
invoiceStatus: 'Paid',
avatar: avatar2,
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-03`,
},
{
id: 4990,
issuedDate: `${now.getFullYear()}-${currentMonth}-06`,
client: {
address: '19022 Clark Parks Suite 149',
company: 'Smith, Miller and Henry LLC',
companyEmail: 'mejiageorge@lee-perez.com',
country: 'Cambodia',
contact: '(832) 323-6914',
name: 'Kevin Patton',
},
service: 'Software Development',
total: 4749,
avatar: avatar3,
invoiceStatus: 'Sent',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-11`,
},
{
id: 4991,
issuedDate: `${now.getFullYear()}-${currentMonth}-08`,
client: {
address: '8534 Saunders Hill Apt. 583',
company: 'Garcia-Cameron and Sons',
companyEmail: 'brandon07@pierce.com',
country: 'Martinique',
contact: '(970) 982-3353',
name: 'Mrs. Julie Donovan MD',
},
service: 'UI/UX Design & Development',
total: 4056,
avatar: avatar4,
invoiceStatus: 'Draft',
balance: 815,
dueDate: `${now.getFullYear()}-${currentMonth}-30`,
},
{
id: 4992,
issuedDate: `${now.getFullYear()}-${currentMonth}-26`,
client: {
address: '661 Perez Run Apt. 778',
company: 'Burnett-Young PLC',
companyEmail: 'guerrerobrandy@beasley-harper.com',
country: 'Botswana',
contact: '(511) 938-9617',
name: 'Amanda Phillips',
},
service: 'UI/UX Design & Development',
total: 2771,
avatar: '',
invoiceStatus: 'Paid',
balance: 2771,
dueDate: `${now.getFullYear()}-${currentMonth}-24`,
},
{
id: 4993,
issuedDate: `${now.getFullYear()}-${currentMonth}-17`,
client: {
address: '074 Long Union',
company: 'Wilson-Lee LLC',
companyEmail: 'williamshenry@moon-smith.com',
country: 'Montserrat',
contact: '(504) 859-2893',
name: 'Christina Collier',
},
service: 'UI/UX Design & Development',
total: 2713,
avatar: '',
invoiceStatus: 'Draft',
balance: 407,
dueDate: `${now.getFullYear()}-${currentMonth}-22`,
},
{
id: 4994,
issuedDate: `${now.getFullYear()}-${currentMonth}-11`,
client: {
address: '5225 Ford Cape Apt. 840',
company: 'Schwartz, Henry and Rhodes Group',
companyEmail: 'margaretharvey@russell-murray.com',
country: 'Oman',
contact: '(758) 403-7718',
name: 'David Flores',
},
service: 'Template Customization',
total: 4309,
avatar: avatar5,
invoiceStatus: 'Paid',
balance: -205,
dueDate: `${now.getFullYear()}-${currentMonth}-13`,
},
{
id: 4995,
issuedDate: `${now.getFullYear()}-${currentMonth}-16`,
client: {
address: '23717 James Club Suite 277',
company: 'Henderson-Holder PLC',
companyEmail: 'dianarodriguez@villegas.com',
country: 'Cambodia',
contact: '(292) 873-8254',
name: 'Valerie Perez',
},
service: 'Software Development',
total: 3367,
avatar: avatar6,
invoiceStatus: 'Downloaded',
balance: 3367,
dueDate: `${now.getFullYear()}-${currentMonth}-24`,
},
{
id: 4996,
issuedDate: `${now.getFullYear()}-${currentMonth}-15`,
client: {
address: '4528 Myers Gateway',
company: 'Page-Wise PLC',
companyEmail: 'bwilson@norris-brock.com',
country: 'Guam',
contact: '(956) 803-2008',
name: 'Susan Dickerson',
},
service: 'Software Development',
total: 4776,
avatar: avatar7,
invoiceStatus: 'Downloaded',
balance: 305,
dueDate: `${now.getFullYear()}-${currentMonth}-02`,
},
{
id: 4997,
issuedDate: `${now.getFullYear()}-${currentMonth}-27`,
client: {
address: '4234 Mills Club Suite 107',
company: 'Turner PLC Inc',
companyEmail: 'markcampbell@bell.info',
country: 'United States Virgin Islands',
contact: '(716) 962-8635',
name: 'Kelly Smith',
},
service: 'Unlimited Extended License',
total: 3789,
avatar: avatar8,
invoiceStatus: 'Partial Payment',
balance: 666,
dueDate: `${now.getFullYear()}-${currentMonth}-18`,
},
{
id: 4998,
issuedDate: `${now.getFullYear()}-${currentMonth}-31`,
client: {
address: '476 Keith Meadow',
company: 'Levine-Dorsey PLC',
companyEmail: 'mary61@rosario.com',
country: 'Syrian Arab Republic',
contact: '(523) 449-0782',
name: 'Jamie Jones',
},
service: 'Unlimited Extended License',
total: 5200,
avatar: avatar2,
invoiceStatus: 'Partial Payment',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-17`,
},
{
id: 4999,
issuedDate: `${now.getFullYear()}-${currentMonth}-14`,
client: {
address: '56381 Ashley Village Apt. 332',
company: 'Hall, Thompson and Ramirez LLC',
companyEmail: 'sean22@cook.com',
country: 'Ukraine',
contact: '(583) 470-8356',
name: 'Ruben Garcia',
},
service: 'Software Development',
total: 4558,
avatar: avatar1,
invoiceStatus: 'Paid',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-01`,
},
{
id: 5000,
issuedDate: `${now.getFullYear()}-${currentMonth}-21`,
client: {
address: '6946 Gregory Plaza Apt. 310',
company: 'Lambert-Thomas Group',
companyEmail: 'mccoymatthew@lopez-jenkins.net',
country: 'Vanuatu',
contact: '(366) 906-6467',
name: 'Ryan Meyer',
},
service: 'Template Customization',
total: 3503,
avatar: avatar7,
invoiceStatus: 'Paid',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-22`,
},
{
id: 5001,
issuedDate: `${now.getFullYear()}-${currentMonth}-30`,
client: {
address: '64351 Andrew Lights',
company: 'Gregory-Haynes PLC',
companyEmail: 'novakshannon@mccarty-murillo.com',
country: 'Romania',
contact: '(320) 616-3915',
name: 'Valerie Valdez',
},
service: 'Unlimited Extended License',
total: 5285,
avatar: avatar6,
invoiceStatus: 'Partial Payment',
balance: -202,
dueDate: `${now.getFullYear()}-${currentMonth}-02`,
},
{
id: 5002,
issuedDate: `${now.getFullYear()}-${currentMonth}-21`,
client: {
address: '5702 Sarah Heights',
company: 'Wright-Schmidt LLC',
companyEmail: 'smithrachel@davis-rose.net',
country: 'Costa Rica',
contact: '(435) 899-1963',
name: 'Melissa Wheeler',
},
service: 'UI/UX Design & Development',
total: 3668,
avatar: avatar5,
invoiceStatus: 'Downloaded',
balance: 731,
dueDate: `${now.getFullYear()}-${currentMonth}-15`,
},
{
id: 5003,
issuedDate: `${now.getFullYear()}-${currentMonth}-30`,
client: {
address: '668 Robert Flats',
company: 'Russell-Abbott Ltd',
companyEmail: 'scott96@mejia.net',
country: 'Congo',
contact: '(254) 399-4728',
name: 'Alan Jimenez',
},
service: 'Unlimited Extended License',
total: 4372,
avatar: '',
invoiceStatus: 'Sent',
balance: -344,
dueDate: `${now.getFullYear()}-${currentMonth}-17`,
},
{
id: 5004,
issuedDate: `${now.getFullYear()}-${currentMonth}-27`,
client: {
address: '55642 Chang Extensions Suite 373',
company: 'Williams LLC Inc',
companyEmail: 'cramirez@ross-bass.biz',
country: 'Saint Pierre and Miquelon',
contact: '(648) 500-4338',
name: 'Jennifer Morris',
},
service: 'Template Customization',
total: 3198,
avatar: avatar4,
invoiceStatus: 'Partial Payment',
balance: -253,
dueDate: `${now.getFullYear()}-${currentMonth}-16`,
},
{
id: 5005,
issuedDate: `${now.getFullYear()}-${currentMonth}-30`,
client: {
address: '56694 Eric Orchard',
company: 'Hudson, Bell and Phillips PLC',
companyEmail: 'arielberg@wolfe-smith.com',
country: 'Uruguay',
contact: '(896) 544-3796',
name: 'Timothy Stevenson',
},
service: 'Unlimited Extended License',
total: 5293,
avatar: '',
invoiceStatus: 'Past Due',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-01`,
},
{
id: 5006,
issuedDate: `${now.getFullYear()}-${currentMonth}-10`,
client: {
address: '3727 Emma Island Suite 879',
company: 'Berry, Gonzalez and Heath Inc',
companyEmail: 'yrobinson@nichols.com',
country: 'Israel',
contact: '(236) 784-5142',
name: 'Erik Hayden',
},
service: 'Template Customization',
total: 5612,
avatar: avatar3,
invoiceStatus: 'Downloaded',
balance: 883,
dueDate: `${now.getFullYear()}-${currentMonth}-12`,
},
{
id: 5007,
issuedDate: `${now.getFullYear()}-${currentMonth}-01`,
client: {
address: '953 Miller Common Suite 580',
company: 'Martinez, Fuller and Chavez and Sons',
companyEmail: 'tatejennifer@allen.net',
country: 'Cook Islands',
contact: '(436) 717-2419',
name: 'Katherine Kennedy',
},
service: 'Software Development',
total: 2230,
avatar: avatar2,
invoiceStatus: 'Sent',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-19`,
},
{
id: 5008,
issuedDate: `${now.getFullYear()}-${currentMonth}-22`,
client: {
address: '808 Sullivan Street Apt. 135',
company: 'Wilson and Sons LLC',
companyEmail: 'gdurham@lee.com',
country: 'Nepal',
contact: '(489) 946-3041',
name: 'Monica Fuller',
},
service: 'Unlimited Extended License',
total: 2032,
avatar: avatar1,
invoiceStatus: 'Partial Payment',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-30`,
},
{
id: 5009,
issuedDate: `${now.getFullYear()}-${currentMonth}-30`,
client: {
address: '25135 Christopher Creek',
company: 'Hawkins, Johnston and Mcguire PLC',
companyEmail: 'jenny96@lawrence-thompson.com',
country: 'Kiribati',
contact: '(274) 246-3725',
name: 'Stacey Carter',
},
service: 'UI/UX Design & Development',
total: 3128,
avatar: avatar8,
invoiceStatus: 'Paid',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-10`,
},
{
id: 5010,
issuedDate: `${now.getFullYear()}-${currentMonth}-06`,
client: {
address: '81285 Rebecca Estates Suite 046',
company: 'Huynh-Mills and Sons',
companyEmail: 'jgutierrez@jackson.com',
country: 'Swaziland',
contact: '(258) 211-5970',
name: 'Chad Davis',
},
service: 'Software Development',
total: 2060,
avatar: avatar7,
invoiceStatus: 'Downloaded',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-08`,
},
{
id: 5011,
issuedDate: `${now.getFullYear()}-${currentMonth}-01`,
client: {
address: '3102 Briggs Dale Suite 118',
company: 'Jones-Cooley and Sons',
companyEmail: 'hunter14@jones.com',
country: 'Congo',
contact: '(593) 965-4100',
name: 'Chris Reyes',
},
service: 'UI/UX Design & Development',
total: 4077,
avatar: '',
invoiceStatus: 'Draft',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-01`,
},
{
id: 5012,
issuedDate: `${now.getFullYear()}-${currentMonth}-30`,
client: {
address: '811 Jill Skyway',
company: 'Jones PLC Ltd',
companyEmail: 'pricetodd@johnson-jenkins.com',
country: 'Brazil',
contact: '(585) 829-2603',
name: 'Laurie Summers',
},
service: 'Template Customization',
total: 2872,
avatar: avatar6,
invoiceStatus: 'Partial Payment',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-18`,
},
{
id: 5013,
issuedDate: `${now.getFullYear()}-${currentMonth}-05`,
client: {
address: '2223 Brandon Inlet Suite 597',
company: 'Jordan, Gomez and Ross Group',
companyEmail: 'perrydavid@chapman-rogers.com',
country: 'Congo',
contact: '(527) 351-5517',
name: 'Lindsay Wilson',
},
service: 'Software Development',
total: 3740,
avatar: avatar4,
invoiceStatus: 'Draft',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-01`,
},
{
id: 5014,
issuedDate: `${now.getFullYear()}-${currentMonth}-01`,
client: {
address: '08724 Barry Causeway',
company: 'Gonzalez, Moody and Glover LLC',
companyEmail: 'leahgriffin@carpenter.com',
country: 'Equatorial Guinea',
contact: '(628) 903-0132',
name: 'Jenna Castro',
},
service: 'Unlimited Extended License',
total: 3623,
avatar: '',
invoiceStatus: 'Downloaded',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-23`,
},
{
id: 5015,
issuedDate: `${now.getFullYear()}-${currentMonth}-16`,
client: {
address: '073 Holt Ramp Apt. 755',
company: 'Ashley-Pacheco Ltd',
companyEmail: 'esparzadaniel@allen.com',
country: 'Seychelles',
contact: '(847) 396-9904',
name: 'Wendy Weber',
},
service: 'Software Development',
total: 2477,
avatar: avatar5,
invoiceStatus: 'Draft',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-01`,
},
{
id: 5016,
issuedDate: `${now.getFullYear()}-${currentMonth}-24`,
client: {
address: '984 Sherry Trail Apt. 953',
company: 'Berry PLC Group',
companyEmail: 'todd34@owens-morgan.com',
country: 'Ireland',
contact: '(852) 249-4539',
name: 'April Yates',
},
service: 'Unlimited Extended License',
total: 3904,
avatar: '',
invoiceStatus: 'Paid',
balance: 951,
dueDate: `${now.getFullYear()}-${currentMonth}-30`,
},
{
id: 5017,
issuedDate: `${now.getFullYear()}-${currentMonth}-24`,
client: {
address: '093 Jonathan Camp Suite 953',
company: 'Allen Group Ltd',
companyEmail: 'roydavid@bailey.com',
country: 'Netherlands',
contact: '(917) 984-2232',
name: 'Daniel Marshall PhD',
},
service: 'UI/UX Design & Development',
total: 3102,
avatar: avatar3,
invoiceStatus: 'Partial Payment',
balance: -153,
dueDate: `${now.getFullYear()}-${currentMonth}-25`,
},
{
id: 5018,
issuedDate: `${now.getFullYear()}-${currentMonth}-29`,
client: {
address: '4735 Kristie Islands Apt. 259',
company: 'Chapman-Schneider LLC',
companyEmail: 'baldwinjoel@washington.com',
country: 'Cocos (Keeling) Islands',
contact: '(670) 409-3703',
name: 'Randy Rich',
},
service: 'UI/UX Design & Development',
total: 2483,
avatar: avatar2,
invoiceStatus: 'Draft',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-10`,
},
{
id: 5019,
issuedDate: `${now.getFullYear()}-${currentMonth}-07`,
client: {
address: '92218 Andrew Radial',
company: 'Mcclure, Hernandez and Simon Ltd',
companyEmail: 'psmith@morris.info',
country: 'Macao',
contact: '(646) 263-0257',
name: 'Mrs. Jodi Chapman',
},
service: 'Unlimited Extended License',
total: 2825,
avatar: avatar1,
invoiceStatus: 'Partial Payment',
balance: -459,
dueDate: `${now.getFullYear()}-${currentMonth}-14`,
},
{
id: 5020,
issuedDate: `${now.getFullYear()}-${currentMonth}-10`,
client: {
address: '2342 Michelle Valley',
company: 'Hamilton PLC and Sons',
companyEmail: 'lori06@morse.com',
country: 'Somalia',
contact: '(751) 213-4288',
name: 'Steven Myers',
},
service: 'Unlimited Extended License',
total: 2029,
avatar: avatar2,
invoiceStatus: 'Past Due',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-28`,
},
{
id: 5021,
issuedDate: `${now.getFullYear()}-${currentMonth}-02`,
client: {
address: '16039 Brittany Terrace Apt. 128',
company: 'Silva-Reeves LLC',
companyEmail: 'zpearson@miller.com',
country: 'Slovakia (Slovak Republic)',
contact: '(655) 649-7872',
name: 'Charles Alexander',
},
service: 'Software Development',
total: 3208,
avatar: '',
invoiceStatus: 'Sent',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-06`,
},
{
id: 5022,
issuedDate: `${now.getFullYear()}-${currentMonth}-02`,
client: {
address: '37856 Olsen Lakes Apt. 852',
company: 'Solis LLC Ltd',
companyEmail: 'strongpenny@young.net',
country: 'Brazil',
contact: '(402) 935-0735',
name: 'Elizabeth Jones',
},
service: 'Software Development',
total: 3077,
avatar: '',
invoiceStatus: 'Sent',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-09`,
},
{
id: 5023,
issuedDate: `${now.getFullYear()}-${currentMonth}-23`,
client: {
address: '11489 Griffin Plaza Apt. 927',
company: 'Munoz-Peters and Sons',
companyEmail: 'carrietorres@acosta.com',
country: 'Argentina',
contact: '(915) 448-6271',
name: 'Heidi Walton',
},
service: 'Software Development',
total: 5578,
avatar: avatar4,
invoiceStatus: 'Draft',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-23`,
},
{
id: 5024,
issuedDate: `${now.getFullYear()}-${currentMonth}-28`,
client: {
address: '276 Michael Gardens Apt. 004',
company: 'Shea, Velez and Garcia LLC',
companyEmail: 'zjohnson@nichols-powers.com',
country: 'Philippines',
contact: '(817) 700-2984',
name: 'Christopher Allen',
},
service: 'Software Development',
total: 2787,
avatar: avatar5,
invoiceStatus: 'Partial Payment',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-25`,
},
{
id: 5025,
issuedDate: `${now.getFullYear()}-${currentMonth}-21`,
client: {
address: '633 Bell Well Apt. 057',
company: 'Adams, Simmons and Brown Group',
companyEmail: 'kayla09@thomas.com',
country: 'Martinique',
contact: '(266) 611-9482',
name: 'Joseph Oliver',
},
service: 'UI/UX Design & Development',
total: 5591,
avatar: '',
invoiceStatus: 'Downloaded',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-07`,
},
{
id: 5026,
issuedDate: `${now.getFullYear()}-${currentMonth}-24`,
client: {
address: '1068 Lopez Fall',
company: 'Williams-Lawrence and Sons',
companyEmail: 'melvindavis@allen.info',
country: 'Mexico',
contact: '(739) 745-9728',
name: 'Megan Roberts',
},
service: 'Template Customization',
total: 2783,
avatar: avatar6,
invoiceStatus: 'Draft',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-22`,
},
{
id: 5027,
issuedDate: `${now.getFullYear()}-${currentMonth}-13`,
client: {
address: '86691 Mackenzie Light Suite 568',
company: 'Deleon Inc LLC',
companyEmail: 'gjordan@fernandez-coleman.com',
country: 'Costa Rica',
contact: '(682) 804-6506',
name: 'Mary Garcia',
},
service: 'Template Customization',
total: 2719,
avatar: '',
invoiceStatus: 'Sent',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-04`,
},
{
id: 5028,
issuedDate: `${now.getFullYear()}-${currentMonth}-18`,
client: {
address: '86580 Sarah Bridge',
company: 'Farmer, Johnson and Anderson Group',
companyEmail: 'robertscott@garcia.com',
country: 'Cameroon',
contact: '(775) 366-0411',
name: 'Crystal Mays',
},
service: 'Template Customization',
total: 3325,
avatar: '',
invoiceStatus: 'Paid',
balance: 361,
dueDate: `${now.getFullYear()}-${currentMonth}-02`,
},
{
id: 5029,
issuedDate: `${now.getFullYear()}-${currentMonth}-29`,
client: {
address: '49709 Edwin Ports Apt. 353',
company: 'Sherman-Johnson PLC',
companyEmail: 'desiree61@kelly.com',
country: 'Macedonia',
contact: '(510) 536-6029',
name: 'Nicholas Tanner',
},
service: 'Template Customization',
total: 3851,
avatar: '',
invoiceStatus: 'Paid',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-25`,
},
{
id: 5030,
issuedDate: `${now.getFullYear()}-${currentMonth}-07`,
client: {
address: '3856 Mathis Squares Apt. 584',
company: 'Byrd LLC PLC',
companyEmail: 'jeffrey25@martinez-hodge.com',
country: 'Congo',
contact: '(253) 230-4657',
name: 'Justin Richardson',
},
service: 'Template Customization',
total: 5565,
avatar: '',
invoiceStatus: 'Draft',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-06`,
},
{
id: 5031,
issuedDate: `${now.getFullYear()}-${currentMonth}-21`,
client: {
address: '141 Adrian Ridge Suite 550',
company: 'Stone-Zimmerman Group',
companyEmail: 'john77@anderson.net',
country: 'Falkland Islands (Malvinas)',
contact: '(612) 546-3485',
name: 'Jennifer Summers',
},
service: 'Template Customization',
total: 3313,
avatar: avatar7,
invoiceStatus: 'Partial Payment',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-09`,
},
{
id: 5032,
issuedDate: `${now.getFullYear()}-${currentMonth}-31`,
client: {
address: '01871 Kristy Square',
company: 'Yang, Hansen and Hart PLC',
companyEmail: 'ywagner@jones.com',
country: 'Germany',
contact: '(203) 601-8603',
name: 'Richard Payne',
},
service: 'Template Customization',
total: 5181,
avatar: '',
invoiceStatus: 'Past Due',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-29`,
},
{
id: 5033,
issuedDate: `${now.getFullYear()}-${currentMonth}-12`,
client: {
address: '075 Smith Views',
company: 'Jenkins-Rosales Inc',
companyEmail: 'calvin07@joseph-edwards.org',
country: 'Colombia',
contact: '(895) 401-4255',
name: 'Lori Wells',
},
service: 'Template Customization',
total: 2869,
avatar: avatar4,
invoiceStatus: 'Partial Payment',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-22`,
},
{
id: 5034,
issuedDate: `${now.getFullYear()}-${currentMonth}-10`,
client: {
address: '2577 Pearson Overpass Apt. 314',
company: 'Mason-Reed PLC',
companyEmail: 'eric47@george-castillo.com',
country: 'Paraguay',
contact: '(602) 336-9806',
name: 'Tammy Sanchez',
},
service: 'Unlimited Extended License',
total: 4836,
avatar: '',
invoiceStatus: 'Paid',
balance: 0,
dueDate: `${now.getFullYear()}-${currentMonth}-22`,
},
{
id: 5035,
issuedDate: `${now.getFullYear()}-${currentMonth}-20`,
client: {
address: '1770 Sandra Mountains Suite 636',
company: 'Foster-Pham PLC',
companyEmail: 'jamesjoel@chapman.net',
country: 'Western Sahara',
contact: '(936) 550-1638',
name: 'Dana Carey',
},
service: 'UI/UX Design & Development',
total: 4263,
avatar: '',
invoiceStatus: 'Draft',
balance: 762,
dueDate: `${now.getFullYear()}-${currentMonth}-12`,
},
{
id: 5036,
issuedDate: `${now.getFullYear()}-${currentMonth}-19`,
client: {
address: '78083 Laura Pines',
company: 'Richardson and Sons LLC',
companyEmail: 'pwillis@cross.org',
country: 'Bhutan',
contact: '(687) 660-2473',
name: 'Andrew Burns',
},
service: 'Unlimited Extended License',
total: 3171,
avatar: avatar3,
invoiceStatus: 'Paid',
balance: -205,
dueDate: `${now.getFullYear()}-${currentMonth}-25`,
},
]

View File

@@ -0,0 +1,141 @@
import is from '@sindresorhus/is'
import destr from 'destr'
import { rest } from 'msw'
import { database } from '@db/apps/invoice/db'
import { paginateArray } from '@api-utils/paginateArray'
export const handlerAppsInvoice = [
// 👉 Client
// Get Clients
rest.get(('/api/apps/invoice/clients'), (req, res, ctx) => {
const clients = database.map(invoice => invoice.client)
return res(ctx.status(200), ctx.json(clients.splice(0, 5)))
}),
// 👉 Invoice
// Get Invoice List
rest.get(('/api/apps/invoice'), (req, res, ctx) => {
const q = req.url.searchParams.get('q')
const status = req.url.searchParams.get('status')
const selectedDateRange = req.url.searchParams.get('selectedDateRange')
const page = req.url.searchParams.get('page')
const itemsPerPage = req.url.searchParams.get('itemsPerPage')
const sortBy = req.url.searchParams.get('sortBy')
const orderBy = req.url.searchParams.get('orderBy')
const searchQuery = is.string(q) ? q : undefined
const queryLowered = (searchQuery ?? '').toString().toLowerCase()
const parsedSortBy = destr(sortBy)
const sortByLocal = is.string(parsedSortBy) ? parsedSortBy : ''
const parsedOrderBy = destr(orderBy)
const orderByLocal = is.string(parsedOrderBy) ? parsedOrderBy : ''
const parsedItemsPerPage = destr(itemsPerPage)
const parsedPage = destr(page)
const itemsPerPageLocal = is.number(parsedItemsPerPage) ? parsedItemsPerPage : 10
const pageLocal = is.number(parsedPage) ? parsedPage : 1
const parsedDateRange = destr(selectedDateRange)
const startDateLocal = parsedDateRange?.start
const endDateLocal = parsedDateRange?.end
// Filtering invoices
let filteredInvoices = database.filter(invoice => ((invoice.client.name.toLowerCase().includes(queryLowered)
|| invoice.client.companyEmail.toLowerCase().includes(queryLowered) || invoice.id.toString().includes(queryLowered))
&& invoice.invoiceStatus === (status || invoice.invoiceStatus))).reverse()
// Sorting invoices
if (sortByLocal) {
if (sortByLocal === 'client') {
filteredInvoices = filteredInvoices.sort((a, b) => {
if (orderByLocal === 'asc')
return a.client.name.localeCompare(b.client.name)
return b.client.name.localeCompare(a.client.name)
})
}
else if (sortByLocal === 'total') {
filteredInvoices = filteredInvoices.sort((a, b) => {
if (orderByLocal === 'asc')
return a.total - b.total
return b.total - a.total
})
}
else if (sortByLocal === 'id') {
filteredInvoices = filteredInvoices.sort((a, b) => {
if (orderByLocal === 'asc')
return a.id - b.id
return b.id - a.id
})
}
else if (sortByLocal === 'date') {
filteredInvoices = filteredInvoices.sort((a, b) => {
if (orderByLocal === 'asc')
return new Date(a.issuedDate).getTime() - new Date(b.issuedDate).getTime()
return new Date(b.issuedDate).getTime() - new Date(a.issuedDate).getTime()
})
}
else if (sortByLocal === 'balance') {
filteredInvoices = filteredInvoices.sort((a, b) => {
if (orderByLocal === 'asc')
return a.balance - b.balance
return b.balance - a.balance
})
}
}
// filtering invoices by date
if (startDateLocal && endDateLocal) {
filteredInvoices = filteredInvoices.filter(invoiceObj => {
const start = new Date(startDateLocal).getTime()
const end = new Date(endDateLocal).getTime()
const issuedDate = new Date(invoiceObj.issuedDate).getTime()
return issuedDate >= start && issuedDate <= end
})
}
const totalInvoices = filteredInvoices.length
return res(ctx.status(200), ctx.json({
invoices: paginateArray(filteredInvoices, itemsPerPageLocal, pageLocal),
totalInvoices,
}))
}),
// Get Single Invoice
rest.get(('/api/apps/invoice/:id'), (req, res, ctx) => {
const invoiceId = req.params.id
const invoice = database.find(e => e.id === Number(invoiceId))
if (!invoice) {
return res(ctx.status(404), ctx.json({ message: 'No invoice found with this id' }))
}
const responseData = {
invoice,
paymentDetails: {
totalDue: '$12,110.55',
bankName: 'American Bank',
country: 'United States',
iban: 'ETD9547621',
swiftCode: 'BR91905',
},
}
return res(ctx.status(200), ctx.json(responseData))
}),
// Delete Invoice
rest.delete(('/api/apps/invoice/:id'), (req, res, ctx) => {
const invoiceId = req.params.id
const invoiceIndex = database.findIndex(e => e.id === Number(invoiceId))
if (invoiceIndex >= 0) {
database.splice(invoiceIndex, 1)
return res(ctx.status(200))
}
return res(ctx.status(404), ctx.json({ error: 'something went wrong' }))
}),
]

View File

@@ -0,0 +1 @@
export {}

View File

@@ -0,0 +1,254 @@
export const db = {
vehicles: [
{
id: 1,
location: 468031,
startCity: 'Cagnes-sur-Mer',
startCountry: 'France',
endCity: 'Catania',
endCountry: 'Italy',
warnings: 'No Warnings',
progress: 49,
},
{
id: 2,
location: 302781,
startCity: 'Köln',
startCountry: 'Germany',
endCity: 'Laspezia',
endCountry: 'Italy',
warnings: 'Ecu Not Responding',
progress: 24,
},
{
id: 3,
location: 715822,
startCity: 'Chambray-lès-Tours',
startCountry: 'France',
endCity: 'Hamm',
endCountry: 'Germany',
warnings: 'Oil Leakage',
progress: 7,
},
{
id: 4,
location: 451430,
startCity: 'Berlin',
startCountry: 'Germany',
endCity: 'Gelsenkirchen',
endCountry: 'Germany',
warnings: 'No Warnings',
progress: 95,
},
{
id: 5,
location: 921577,
startCity: 'Cergy-Pontoise',
startCountry: 'France',
endCity: 'Berlin',
endCountry: 'Germany',
warnings: 'No Warnings',
progress: 65,
},
{
id: 6,
location: 480957,
startCity: 'Villefranche-sur-Saône',
startCountry: 'France',
endCity: 'Halle',
endCountry: 'Germany',
warnings: 'Ecu Not Responding',
progress: 55,
},
{
id: 7,
location: 330178,
startCity: 'Mâcon',
startCountry: 'France',
endCity: 'Bochum',
endCountry: 'Germany',
warnings: 'Fuel Problems',
progress: 74,
},
{
id: 8,
location: 595525,
startCity: 'Fullerton',
startCountry: 'USA',
endCity: 'Lübeck',
endCountry: 'Germany',
warnings: 'No Warnings',
progress: 100,
},
{
id: 9,
location: 182964,
startCity: 'Saintes',
startCountry: 'France',
endCity: 'Roma',
endCountry: 'Italy',
warnings: 'Oil Leakage',
progress: 82,
},
{
id: 10,
location: 706085,
startCity: 'Fort Wayne',
startCountry: 'USA',
endCity: 'Mülheim an der Ruhr',
endCountry: 'Germany',
warnings: 'Oil Leakage',
progress: 49,
},
{
id: 11,
location: 523708,
startCity: 'Albany',
startCountry: 'USA',
endCity: 'Wuppertal',
endCountry: 'Germany',
warnings: 'Temperature not optimal',
progress: 66,
},
{
id: 12,
location: 676485,
startCity: 'Toledo',
startCountry: 'USA',
endCity: 'Magdeburg',
endCountry: 'Germany',
warnings: 'Temperature not optimal',
progress: 7,
},
{
id: 13,
location: 514437,
startCity: 'Houston',
startCountry: 'USA',
endCity: 'Wiesbaden',
endCountry: 'Germany',
warnings: 'Fuel Problems',
progress: 27,
},
{
id: 14,
location: 300198,
startCity: 'West Palm Beach',
startCountry: 'USA',
endCity: 'Dresden',
endCountry: 'Germany',
warnings: 'Temperature not optimal',
progress: 90,
},
{
id: 15,
location: 960090,
startCity: 'Fort Lauderdale',
startCountry: 'USA',
endCity: 'Kiel',
endCountry: 'Germany',
warnings: 'No Warnings',
progress: 81,
},
{
id: 16,
location: 878423,
startCity: 'Schaumburg',
startCountry: 'USA',
endCity: 'Berlin',
endCountry: 'Germany',
warnings: 'Fuel Problems',
progress: 21,
},
{
id: 17,
location: 318119,
startCity: 'Mundolsheim',
startCountry: 'France',
endCity: 'München',
endCountry: 'Germany',
warnings: 'No Warnings',
progress: 26,
},
{
id: 18,
location: 742500,
startCity: 'Fargo',
startCountry: 'USA',
endCity: 'Salerno',
endCountry: 'Italy',
warnings: 'Temperature not optimal',
progress: 80,
},
{
id: 19,
location: 469399,
startCity: 'München',
startCountry: 'Germany',
endCity: 'Ath',
endCountry: 'Belgium',
warnings: 'Ecu Not Responding',
progress: 50,
},
{
id: 20,
location: 411175,
startCity: 'Chicago',
startCountry: 'USA',
endCity: 'Neuss',
endCountry: 'Germany',
warnings: 'Oil Leakage',
progress: 44,
},
{
id: 21,
location: 753525,
startCity: 'Limoges',
startCountry: 'France',
endCity: 'Messina',
endCountry: 'Italy',
warnings: 'Temperature not optimal',
progress: 55,
},
{
id: 22,
location: 882341,
startCity: 'Cesson-Sévigné',
startCountry: 'France',
endCity: 'Napoli',
endCountry: 'Italy',
warnings: 'No Warnings',
progress: 48,
},
{
id: 23,
location: 408270,
startCity: 'Leipzig',
startCountry: 'Germany',
endCity: 'Tournai',
endCountry: 'Belgium',
warnings: 'Ecu Not Responding',
progress: 73,
},
{
id: 24,
location: 276904,
startCity: 'Aulnay-sous-Bois',
startCountry: 'France',
endCity: 'Torino',
endCountry: 'Italy',
warnings: 'Fuel Problems',
progress: 30,
},
{
id: 25,
location: 159145,
startCity: 'Paris 19',
startCountry: 'France',
endCity: 'Dresden',
endCountry: 'Germany',
warnings: 'No Warnings',
progress: 60,
},
],
}

View File

@@ -0,0 +1,72 @@
import is from '@sindresorhus/is'
import { destr } from 'destr'
import { rest } from 'msw'
import { db } from '@db/apps/logistics/db'
import { paginateArray } from '@api-utils/paginateArray'
export const handlerAppLogistics = [
rest.get(('/api/apps/logistics/vehicles'), (req, res, ctx) => {
const sortBy = req.url.searchParams.get('sortBy')
const page = req.url.searchParams.get('page') ?? 1
const itemsPerPage = req.url.searchParams.get('itemsPerPage') ?? 10
const orderBy = req.url.searchParams.get('orderBy')
const parsedSortBy = destr(sortBy)
const sortByLocal = is.string(parsedSortBy) ? parsedSortBy : ''
const parsedOrderBy = destr(orderBy)
const orderByLocal = is.string(parsedOrderBy) ? parsedOrderBy : ''
const parsedItemsPerPage = destr(itemsPerPage)
const parsedPage = destr(page)
const itemsPerPageLocal = is.number(parsedItemsPerPage) ? parsedItemsPerPage : 10
const pageLocal = is.number(parsedPage) ? parsedPage : 1
// Sorting Vehicles
let vehicles = [...db.vehicles]
if (sortBy) {
if (sortByLocal === 'location') {
vehicles = vehicles.sort((a, b) => {
if (orderByLocal === 'asc')
return a.location - b.location
return b.location - a.location
})
}
if (sortByLocal === 'startRoute') {
vehicles = vehicles.sort((a, b) => {
if (orderByLocal === 'asc')
return a.startCity.localeCompare(b.startCity)
return b.startCity.localeCompare(a.startCity)
})
}
if (sortByLocal === 'endRoute') {
vehicles = vehicles.sort((a, b) => {
if (orderByLocal === 'asc')
return a.endCity.localeCompare(b.endCity)
return b.endCity.localeCompare(a.endCity)
})
}
if (sortByLocal === 'warnings') {
vehicles = vehicles.sort((a, b) => {
if (orderByLocal === 'asc')
return a.warnings.localeCompare(b.warnings)
return b.warnings.localeCompare(a.warnings)
})
}
if (sortByLocal === 'progress') {
vehicles = vehicles.sort((a, b) => {
if (orderByLocal === 'asc')
return a.progress - b.progress
return b.progress - a.progress
})
}
}
return res(ctx.status(200), ctx.json({
vehicles: paginateArray(vehicles, itemsPerPageLocal, pageLocal),
totalVehicles: vehicles.length,
}))
}),
]

View File

@@ -0,0 +1 @@
export {}

View File

@@ -0,0 +1,58 @@
export const db = {
permissions: [
{
id: 1,
name: 'Management',
assignedTo: ['administrator'],
createdDate: '14 Apr 2021, 8:43 PM',
},
{
id: 2,
assignedTo: ['administrator'],
name: 'Manage Billing & Roles',
createdDate: '16 Sep 2021, 5:20 PM',
},
{
id: 3,
name: 'Add & Remove Users',
createdDate: '14 Oct 2021, 10:20 AM',
assignedTo: ['administrator', 'manager'],
},
{
id: 4,
name: 'Project Planning',
createdDate: '14 Oct 2021, 10:20 AM',
assignedTo: ['administrator', 'users', 'support'],
},
{
id: 5,
name: 'Manage Email Sequences',
createdDate: '23 Aug 2021, 2:00 PM',
assignedTo: ['administrator', 'users', 'support'],
},
{
id: 6,
name: 'Client Communication',
createdDate: '15 Apr 2021, 11:30 AM',
assignedTo: ['administrator', 'manager'],
},
{
id: 7,
name: 'Only View',
createdDate: '04 Dec 2021, 8:15 PM',
assignedTo: ['administrator', 'restricted-user'],
},
{
id: 8,
name: 'Financial Management',
createdDate: '25 Feb 2021, 10:30 AM',
assignedTo: ['administrator', 'manager'],
},
{
id: 9,
name: 'Manage Others\' Tasks',
createdDate: '04 Nov 2021, 11:45 AM',
assignedTo: ['administrator', 'support'],
},
],
}

View File

@@ -0,0 +1,45 @@
import is from '@sindresorhus/is'
import { destr } from 'destr'
import { rest } from 'msw'
import { db } from '@db/apps/permission/db'
import { paginateArray } from '@api-utils/paginateArray'
export const handlerAppsPermission = [
// 👉 Get Permission List
rest.get(('/api/apps/permissions'), (req, res, ctx) => {
const q = req.url.searchParams.get('q') || ''
const sortBy = req.url.searchParams.get('sortBy')
const page = req.url.searchParams.get('page') || 1
const itemsPerPage = req.url.searchParams.get('itemsPerPage') || 10
const orderBy = req.url.searchParams.get('orderBy')
const parsedSortBy = destr(sortBy)
const sortByLocal = is.string(parsedSortBy) ? parsedSortBy : ''
const parsedOrderBy = destr(orderBy)
const orderByLocal = is.string(parsedOrderBy) ? parsedOrderBy : ''
const parsedItemsPerPage = destr(itemsPerPage)
const parsedPage = destr(page)
const itemsPerPageLocal = is.number(parsedItemsPerPage) ? parsedItemsPerPage : 10
const pageLocal = is.number(parsedPage) ? parsedPage : 1
const searchQuery = is.string(q) ? q : undefined
const queryLower = (searchQuery ?? '').toString().toLowerCase()
let filteredPermissions = db.permissions.filter(permissions => permissions.name.toLowerCase().includes(queryLower)
|| permissions.createdDate.toLowerCase().includes(queryLower)
|| permissions.assignedTo.some(i => i.toLowerCase().startsWith(queryLower)))
// Sorting Permissions
if (sortByLocal && sortByLocal === 'name') {
filteredPermissions = filteredPermissions.sort((a, b) => {
if (orderByLocal === 'asc')
return a.name.localeCompare(b.name)
return b.name.localeCompare(a.name)
})
}
// return response with paginated data
return res(ctx.status(200), ctx.json({
permissions: paginateArray(filteredPermissions, itemsPerPageLocal, pageLocal),
totalPermissions: filteredPermissions.length,
}))
}),
]

View File

@@ -0,0 +1 @@
export {}

View File

@@ -0,0 +1,667 @@
import avatar1 from '@images/avatars/avatar-1.png'
import avatar10 from '@images/avatars/avatar-10.png'
import avatar11 from '@images/avatars/avatar-11.png'
import avatar12 from '@images/avatars/avatar-12.png'
import avatar2 from '@images/avatars/avatar-2.png'
import avatar3 from '@images/avatars/avatar-3.png'
import avatar4 from '@images/avatars/avatar-4.png'
import avatar5 from '@images/avatars/avatar-5.png'
import avatar6 from '@images/avatars/avatar-6.png'
import avatar7 from '@images/avatars/avatar-7.png'
import avatar8 from '@images/avatars/avatar-8.png'
import avatar9 from '@images/avatars/avatar-9.png'
export const db = {
users: [
{
id: 1,
fullName: 'Galasasen Slixby',
company: 'Yotz PVT LTD',
role: 'editor',
username: 'gslixby0',
country: 'El Salvador',
contact: '(479) 232-9151',
email: 'gslixby0@abc.net.au',
currentPlan: 'enterprise',
status: 'inactive',
avatar: avatar1,
},
{
id: 2,
fullName: 'Halsey Redmore',
company: 'Skinder PVT LTD',
role: 'author',
username: 'hredmore1',
country: 'Albania',
contact: '(472) 607-9137',
email: 'hredmore1@imgur.com',
currentPlan: 'team',
status: 'pending',
avatar: avatar2,
},
{
id: 3,
fullName: 'Marjory Sicely',
company: 'Oozz PVT LTD',
role: 'maintainer',
username: 'msicely2',
country: 'Russia',
contact: '(321) 264-4599',
email: 'msicely2@who.int',
currentPlan: 'enterprise',
status: 'active',
avatar: '',
},
{
id: 4,
fullName: 'Cyrill Risby',
company: 'Oozz PVT LTD',
role: 'maintainer',
username: 'crisby3',
country: 'China',
contact: '(923) 690-6806',
email: 'crisby3@wordpress.com',
currentPlan: 'team',
status: 'inactive',
avatar: avatar3,
},
{
id: 5,
fullName: 'Maggy Hurran',
company: 'Aimbo PVT LTD',
role: 'subscriber',
username: 'mhurran4',
country: 'Pakistan',
contact: '(669) 914-1078',
email: 'mhurran4@yahoo.co.jp',
currentPlan: 'enterprise',
status: 'pending',
avatar: avatar4,
},
{
id: 6,
fullName: 'Silvain Halstead',
company: 'Jaxbean PVT LTD',
role: 'author',
username: 'shalstead5',
country: 'China',
contact: '(958) 973-3093',
email: 'shalstead5@shinystat.com',
currentPlan: 'company',
status: 'active',
avatar: '',
},
{
id: 7,
fullName: 'Breena Gallemore',
company: 'Jazzy PVT LTD',
role: 'subscriber',
username: 'bgallemore6',
country: 'Canada',
contact: '(825) 977-8152',
email: 'bgallemore6@boston.com',
currentPlan: 'company',
status: 'pending',
avatar: '',
},
{
id: 8,
fullName: 'Kathryne Liger',
company: 'Pixoboo PVT LTD',
role: 'author',
username: 'kliger7',
country: 'France',
contact: '(187) 440-0934',
email: 'kliger7@vinaora.com',
currentPlan: 'enterprise',
status: 'pending',
avatar: '',
},
{
id: 9,
fullName: 'Franz Scotfurth',
company: 'Tekfly PVT LTD',
role: 'subscriber',
username: 'fscotfurth8',
country: 'China',
contact: '(978) 146-5443',
email: 'fscotfurth8@dailymotion.com',
currentPlan: 'team',
status: 'pending',
avatar: '',
},
{
id: 10,
fullName: 'Jillene Bellany',
company: 'Gigashots PVT LTD',
role: 'maintainer',
username: 'jbellany9',
country: 'Jamaica',
contact: '(589) 284-6732',
email: 'jbellany9@kickstarter.com',
currentPlan: 'company',
status: 'inactive',
avatar: '',
},
{
id: 11,
fullName: 'Jonah Wharlton',
company: 'Eare PVT LTD',
role: 'subscriber',
username: 'jwharltona',
country: 'United States',
contact: '(176) 532-6824',
email: 'jwharltona@oakley.com',
currentPlan: 'team',
status: 'inactive',
avatar: '',
},
{
id: 12,
fullName: 'Seth Hallam',
company: 'Yakitri PVT LTD',
role: 'subscriber',
username: 'shallamb',
country: 'Peru',
contact: '(234) 464-0600',
email: 'shallamb@hugedomains.com',
currentPlan: 'team',
status: 'pending',
avatar: '',
},
{
id: 13,
fullName: 'Yoko Pottie',
company: 'Leenti PVT LTD',
role: 'subscriber',
username: 'ypottiec',
country: 'Philippines',
contact: '(907) 284-5083',
email: 'ypottiec@privacy.gov.au',
currentPlan: 'basic',
status: 'inactive',
avatar: '',
},
{
id: 14,
fullName: 'Maximilianus Krause',
company: 'Digitube PVT LTD',
role: 'author',
username: 'mkraused',
country: 'Democratic Republic of the Congo',
contact: '(167) 135-7392',
email: 'mkraused@stanford.edu',
currentPlan: 'team',
status: 'active',
avatar: '',
},
{
id: 15,
fullName: 'Zsazsa McCleverty',
company: 'Kaymbo PVT LTD',
role: 'maintainer',
username: 'zmcclevertye',
country: 'France',
contact: '(317) 409-6565',
email: 'zmcclevertye@soundcloud.com',
currentPlan: 'enterprise',
status: 'active',
avatar: '',
},
{
id: 16,
fullName: 'Bentlee Emblin',
company: 'Yambee PVT LTD',
role: 'author',
username: 'bemblinf',
country: 'Spain',
contact: '(590) 606-1056',
email: 'bemblinf@wired.com',
currentPlan: 'company',
status: 'active',
avatar: '',
},
{
id: 17,
fullName: 'Brockie Myles',
company: 'Wikivu PVT LTD',
role: 'maintainer',
username: 'bmylesg',
country: 'Poland',
contact: '(553) 225-9905',
email: 'bmylesg@amazon.com',
currentPlan: 'basic',
status: 'active',
avatar: '',
},
{
id: 18,
fullName: 'Bertha Biner',
company: 'Twinte PVT LTD',
role: 'editor',
username: 'bbinerh',
country: 'Yemen',
contact: '(901) 916-9287',
email: 'bbinerh@mozilla.com',
currentPlan: 'team',
status: 'active',
avatar: '',
},
{
id: 19,
fullName: 'Travus Bruntjen',
company: 'Cogidoo PVT LTD',
role: 'admin',
username: 'tbruntjeni',
country: 'France',
contact: '(524) 586-6057',
email: 'tbruntjeni@sitemeter.com',
currentPlan: 'enterprise',
status: 'active',
avatar: '',
},
{
id: 20,
fullName: 'Wesley Burland',
company: 'Bubblemix PVT LTD',
role: 'editor',
username: 'wburlandj',
country: 'Honduras',
contact: '(569) 683-1292',
email: 'wburlandj@uiuc.edu',
currentPlan: 'team',
status: 'inactive',
avatar: '',
},
{
id: 21,
fullName: 'Selina Kyle',
company: 'Wayne Enterprises',
role: 'admin',
username: 'catwomen1940',
country: 'USA',
contact: '(829) 537-0057',
email: 'irena.dubrovna@wayne.com',
currentPlan: 'team',
status: 'active',
avatar: avatar3,
},
{
id: 22,
fullName: 'Jameson Lyster',
company: 'Quaxo PVT LTD',
role: 'editor',
username: 'jlysterl',
country: 'Ukraine',
contact: '(593) 624-0222',
email: 'jlysterl@guardian.co.uk',
currentPlan: 'company',
status: 'inactive',
avatar: '',
},
{
id: 23,
fullName: 'Kare Skitterel',
company: 'Ainyx PVT LTD',
role: 'maintainer',
username: 'kskitterelm',
country: 'Poland',
contact: '(254) 845-4107',
email: 'kskitterelm@ainyx.com',
currentPlan: 'basic',
status: 'pending',
avatar: '',
},
{
id: 24,
fullName: 'Cleavland Hatherleigh',
company: 'Flipopia PVT LTD',
role: 'admin',
username: 'chatherleighn',
country: 'Brazil',
contact: '(700) 783-7498',
email: 'chatherleighn@washington.edu',
currentPlan: 'team',
status: 'pending',
avatar: '',
},
{
id: 25,
fullName: 'Adeline Micco',
company: 'Topicware PVT LTD',
role: 'admin',
username: 'amiccoo',
country: 'France',
contact: '(227) 598-1841',
email: 'amiccoo@whitehouse.gov',
currentPlan: 'enterprise',
status: 'pending',
avatar: '',
},
{
id: 26,
fullName: 'Hugh Hasson',
company: 'Skinix PVT LTD',
role: 'admin',
username: 'hhassonp',
country: 'China',
contact: '(582) 516-1324',
email: 'hhassonp@bizjournals.com',
currentPlan: 'basic',
status: 'inactive',
avatar: '',
},
{
id: 27,
fullName: 'Germain Jacombs',
company: 'Youopia PVT LTD',
role: 'editor',
username: 'gjacombsq',
country: 'Zambia',
contact: '(137) 467-5393',
email: 'gjacombsq@jigsy.com',
currentPlan: 'enterprise',
status: 'active',
avatar: '',
},
{
id: 28,
fullName: 'Bree Kilday',
company: 'Jetpulse PVT LTD',
role: 'maintainer',
username: 'bkildayr',
country: 'Portugal',
contact: '(412) 476-0854',
email: 'bkildayr@mashable.com',
currentPlan: 'team',
status: 'active',
avatar: '',
},
{
id: 29,
fullName: 'Candice Pinyon',
company: 'Kare PVT LTD',
role: 'maintainer',
username: 'cpinyons',
country: 'Sweden',
contact: '(170) 683-1520',
email: 'cpinyons@behance.net',
currentPlan: 'team',
status: 'active',
avatar: '',
},
{
id: 30,
fullName: 'Isabel Mallindine',
company: 'Voomm PVT LTD',
role: 'subscriber',
username: 'imallindinet',
country: 'Slovenia',
contact: '(332) 803-1983',
email: 'imallindinet@shinystat.com',
currentPlan: 'team',
status: 'pending',
avatar: '',
},
{
id: 31,
fullName: 'Gwendolyn Meineken',
company: 'Oyondu PVT LTD',
role: 'admin',
username: 'gmeinekenu',
country: 'Moldova',
contact: '(551) 379-7460',
email: 'gmeinekenu@hc360.com',
currentPlan: 'basic',
status: 'pending',
avatar: '',
},
{
id: 32,
fullName: 'Rafaellle Snowball',
company: 'Fivespan PVT LTD',
role: 'editor',
username: 'rsnowballv',
country: 'Philippines',
contact: '(974) 829-0911',
email: 'rsnowballv@indiegogo.com',
currentPlan: 'basic',
status: 'pending',
avatar: '',
},
{
id: 33,
fullName: 'Rochette Emer',
company: 'Thoughtworks PVT LTD',
role: 'admin',
username: 'remerw',
country: 'North Korea',
contact: '(841) 889-3339',
email: 'remerw@blogtalkradio.com',
currentPlan: 'basic',
status: 'active',
avatar: '',
},
{
id: 34,
fullName: 'Ophelie Fibbens',
company: 'Jaxbean PVT LTD',
role: 'subscriber',
username: 'ofibbensx',
country: 'Indonesia',
contact: '(764) 885-7351',
email: 'ofibbensx@booking.com',
currentPlan: 'company',
status: 'active',
avatar: '',
},
{
id: 35,
fullName: 'Stephen MacGilfoyle',
company: 'Browseblab PVT LTD',
role: 'maintainer',
username: 'smacgilfoyley',
country: 'Japan',
contact: '(350) 589-8520',
email: 'smacgilfoyley@bigcartel.com',
currentPlan: 'company',
status: 'pending',
avatar: avatar12,
},
{
id: 36,
fullName: 'Bradan Rosebotham',
company: 'Agivu PVT LTD',
role: 'subscriber',
username: 'brosebothamz',
country: 'Belarus',
contact: '(882) 933-2180',
email: 'brosebothamz@tripadvisor.com',
currentPlan: 'team',
status: 'inactive',
avatar: avatar6,
},
{
id: 37,
fullName: 'Skip Hebblethwaite',
company: 'Katz PVT LTD',
role: 'admin',
username: 'shebblethwaite10',
country: 'Canada',
contact: '(610) 343-1024',
email: 'shebblethwaite10@arizona.edu',
currentPlan: 'company',
status: 'inactive',
avatar: avatar11,
},
{
id: 38,
fullName: 'Moritz Piccard',
company: 'Twitternation PVT LTD',
role: 'maintainer',
username: 'mpiccard11',
country: 'Croatia',
contact: '(365) 277-2986',
email: 'mpiccard11@vimeo.com',
currentPlan: 'enterprise',
status: 'inactive',
avatar: '',
},
{
id: 39,
fullName: 'Tyne Widmore',
company: 'Yombu PVT LTD',
role: 'subscriber',
username: 'twidmore12',
country: 'Finland',
contact: '(531) 731-0928',
email: 'twidmore12@bravesites.com',
currentPlan: 'team',
status: 'pending',
avatar: avatar8,
},
{
id: 40,
fullName: 'Florenza Desporte',
company: 'Kamba PVT LTD',
role: 'author',
username: 'fdesporte13',
country: 'Ukraine',
contact: '(312) 104-2638',
email: 'fdesporte13@omniture.com',
currentPlan: 'company',
status: 'active',
avatar: '',
},
{
id: 41,
fullName: 'Edwina Baldetti',
company: 'Dazzlesphere PVT LTD',
role: 'maintainer',
username: 'ebaldetti14',
country: 'Haiti',
contact: '(315) 329-3578',
email: 'ebaldetti14@theguardian.com',
currentPlan: 'team',
status: 'pending',
avatar: avatar10,
},
{
id: 42,
fullName: 'Benedetto Rossiter',
company: 'Mybuzz PVT LTD',
role: 'editor',
username: 'brossiter15',
country: 'Indonesia',
contact: '(323) 175-6741',
email: 'brossiter15@craigslist.org',
currentPlan: 'team',
status: 'inactive',
avatar: avatar9,
},
{
id: 43,
fullName: 'Micaela McNirlan',
company: 'Tambee PVT LTD',
role: 'admin',
username: 'mmcnirlan16',
country: 'Indonesia',
contact: '(242) 952-0916',
email: 'mmcnirlan16@hc360.com',
currentPlan: 'basic',
status: 'inactive',
avatar: '',
},
{
id: 44,
fullName: 'Vladamir Koschek',
company: 'Centimia PVT LTD',
role: 'author',
username: 'vkoschek17',
country: 'Guatemala',
contact: '(531) 758-8335',
email: 'vkoschek17@abc.net.au',
currentPlan: 'team',
status: 'active',
avatar: avatar7,
},
{
id: 45,
fullName: 'Corrie Perot',
company: 'Flipopia PVT LTD',
role: 'subscriber',
username: 'cperot18',
country: 'China',
contact: '(659) 385-6808',
email: 'cperot18@goo.ne.jp',
currentPlan: 'team',
status: 'pending',
avatar: avatar6,
},
{
id: 46,
fullName: 'Saunder Offner',
company: 'Skalith PVT LTD',
role: 'maintainer',
username: 'soffner19',
country: 'Poland',
contact: '(200) 586-2264',
email: 'soffner19@mac.com',
currentPlan: 'enterprise',
status: 'pending',
avatar: avatar5,
},
{
id: 47,
fullName: 'Karena Courtliff',
company: 'Feedfire PVT LTD',
role: 'admin',
username: 'kcourtliff1a',
country: 'China',
contact: '(478) 199-0020',
email: 'kcourtliff1a@bbc.co.uk',
currentPlan: 'basic',
status: 'active',
avatar: avatar4,
},
{
id: 48,
fullName: 'Onfre Wind',
company: 'Thoughtmix PVT LTD',
role: 'admin',
username: 'owind1b',
country: 'Ukraine',
contact: '(344) 262-7270',
email: 'owind1b@yandex.ru',
currentPlan: 'basic',
status: 'pending',
avatar: avatar2,
},
{
id: 49,
fullName: 'Paulie Durber',
company: 'Babbleblab PVT LTD',
role: 'subscriber',
username: 'pdurber1c',
country: 'Sweden',
contact: '(694) 676-1275',
email: 'pdurber1c@gov.uk',
currentPlan: 'team',
status: 'inactive',
avatar: avatar3,
},
{
id: 50,
fullName: 'Beverlie Krabbe',
company: 'Kaymbo PVT LTD',
role: 'editor',
username: 'bkrabbe1d',
country: 'China',
contact: '(397) 294-5153',
email: 'bkrabbe1d@home.pl',
currentPlan: 'company',
status: 'active',
avatar: avatar1,
},
],
}

View File

@@ -0,0 +1,137 @@
import is from '@sindresorhus/is'
import destr from 'destr'
import { rest } from 'msw'
import { db } from '@db/apps/users/db'
import { paginateArray } from '@api-utils/paginateArray'
export const handlerAppsUsers = [
// Get Users Details
rest.get(('/api/apps/users'), (req, res, ctx) => {
const q = req.url.searchParams.get('q')
const role = req.url.searchParams.get('role')
const plan = req.url.searchParams.get('plan')
const status = req.url.searchParams.get('status')
const sortBy = req.url.searchParams.get('sortBy')
const itemsPerPage = req.url.searchParams.get('itemsPerPage')
const page = req.url.searchParams.get('page')
const orderBy = req.url.searchParams.get('orderBy')
const searchQuery = is.string(q) ? q : undefined
const queryLower = (searchQuery ?? '').toString().toLowerCase()
const parsedSortBy = destr(sortBy)
const sortByLocal = is.string(parsedSortBy) ? parsedSortBy : ''
const parsedOrderBy = destr(orderBy)
const orderByLocal = is.string(parsedOrderBy) ? parsedOrderBy : ''
const parsedItemsPerPage = destr(itemsPerPage)
const parsedPage = destr(page)
const itemsPerPageLocal = is.number(parsedItemsPerPage) ? parsedItemsPerPage : 10
const pageLocal = is.number(parsedPage) ? parsedPage : 1
// filter users
let filteredUsers = db.users.filter(user => ((user.fullName.toLowerCase().includes(queryLower) || user.email.toLowerCase().includes(queryLower)) && user.role === (role || user.role) && user.currentPlan === (plan || user.currentPlan) && user.status === (status || user.status))).reverse()
// sort users
if (sortByLocal) {
if (sortByLocal === 'user') {
filteredUsers = filteredUsers.sort((a, b) => {
if (orderByLocal === 'asc')
return a.fullName.localeCompare(b.fullName)
else
return b.fullName.localeCompare(a.fullName)
})
}
if (sortByLocal === 'email') {
filteredUsers = filteredUsers.sort((a, b) => {
if (orderByLocal === 'asc')
return a.email.localeCompare(b.email)
else
return b.email.localeCompare(a.email)
})
}
if (sortByLocal === 'role') {
filteredUsers = filteredUsers.sort((a, b) => {
if (orderByLocal === 'asc')
return a.role.localeCompare(b.role)
else
return b.role.localeCompare(a.role)
})
}
if (sortByLocal === 'plan') {
filteredUsers = filteredUsers.sort((a, b) => {
if (orderByLocal === 'asc')
return a.currentPlan.localeCompare(b.currentPlan)
else
return b.currentPlan.localeCompare(a.currentPlan)
})
}
if (sortByLocal === 'status') {
filteredUsers = filteredUsers.sort((a, b) => {
if (orderByLocal === 'asc')
return a.status.localeCompare(b.status)
else
return b.status.localeCompare(a.status)
})
}
}
const totalUsers = filteredUsers.length
// total pages
const totalPages = Math.ceil(totalUsers / itemsPerPageLocal)
return res(ctx.status(200), ctx.json({
users: paginateArray(filteredUsers, itemsPerPageLocal, pageLocal),
totalPages,
totalUsers,
page: pageLocal > Math.ceil(totalUsers / itemsPerPageLocal) ? 1 : page,
}))
}),
// Get Single User Detail
rest.get(('/api/apps/users/:id'), (req, res, ctx) => {
const userId = Number(req.params.id)
const user = db.users.find(e => e.id === userId)
if (!user) {
return res(ctx.status(404), ctx.json({
message: 'User not found',
}))
}
else {
return res(ctx.status(200), ctx.json({
...user,
...{
taskDone: 1230,
projectDone: 568,
taxId: 'Tax-8894',
language: 'English',
},
}))
}
}),
// Delete User
rest.delete(('/api/apps/users/:id'), (req, res, ctx) => {
const userId = Number(req.params.id)
const userIndex = db.users.findIndex(e => e.id === userId)
if (userIndex === -1) {
return res(ctx.status(404), ctx.json({
message: 'User not found',
}))
}
else {
db.users.splice(userIndex, 1)
return res(ctx.status(204))
}
}),
// 👉 Add user
rest.post(('/api/apps/users'), async (req, res, ctx) => {
const user = await req.json()
db.users.push({
...user,
id: db.users.length + 1,
})
return res(ctx.status(201), ctx.json({ body: user }))
}),
]

View File

@@ -0,0 +1 @@
export {}