feat: recreate dashboard page from previous version

This commit is contained in:
Sonny
2024-05-03 02:10:15 +02:00
committed by Sonny
parent 2cc490b611
commit 2cf8c5ae02
66 changed files with 2087 additions and 86 deletions

39
inertia/lib/array.ts Normal file
View File

@@ -0,0 +1,39 @@
import i18n from '~/i18n';
export function groupItemBy(array: any[], property: string) {
const hash: any = {};
const props = property.split('.');
for (const item of array) {
const key = props.reduce((acc, prop) => acc && acc[prop], item);
const hashKey =
key !== undefined ? key : i18n.t('common:collection.collections');
if (!hash[hashKey]) {
hash[hashKey] = [];
}
hash[hashKey].push(item);
}
return hash;
}
// Thanks S/O
export function arrayMove<T>(
arr: T[],
previousIndex: number,
nextIndex: number
): T[] {
const arrayCopy = [...arr];
const [removedElement] = arrayCopy.splice(previousIndex, 1);
if (nextIndex >= arr.length) {
// Pad the array with undefined elements if needed
const padding = nextIndex - arr.length + 1;
arrayCopy.push(...new Array(padding).fill(undefined));
}
arrayCopy.splice(nextIndex, 0, removedElement);
return arrayCopy;
}

28
inertia/lib/collection.ts Normal file
View File

@@ -0,0 +1,28 @@
import type Collection from '#models/collection';
export default function sortCcollectionsByNextId(
collections: Collection[]
): Collection[] {
const sortedCollections: Collection[] = [];
const visit = (collection: Collection) => {
// Check if the collection has been visited
if (sortedCollections.includes(collection)) {
return;
}
// Visit the next collection recursively
const nextCollection = collections.find((c) => c.id === collection.nextId);
if (nextCollection) {
visit(nextCollection);
}
// Add the current collection to the sorted array
sortedCollections.push(collection);
};
// Visit each collection to build the sorted array
collections.forEach((collection) => visit(collection));
return sortedCollections.reverse();
}

6
inertia/lib/image.ts Normal file
View File

@@ -0,0 +1,6 @@
export const isImage = (type: string) => type.includes('image');
export const isBase64Image = (data: string) => data.startsWith('data:image/');
export const convertBase64ToBuffer = (base64: string) =>
Buffer.from(base64, 'base64');

View File

@@ -0,0 +1,9 @@
import Collection from '#models/collection';
export const appendCollectionId = (
url: string,
collectionId?: Collection['id']
) => `${url}${collectionId && `?collectionId=${collectionId}`}}`;
export const appendResourceId = (url: string, resourceId?: string) =>
`${url}${resourceId && `/${resourceId}`}}`;

24
inertia/lib/request.ts Normal file
View File

@@ -0,0 +1,24 @@
import i18n from '~/i18n';
export async function makeRequest({
method = 'GET',
url,
body,
}: {
method?: RequestInit['method'];
url: string;
body?: object | any[];
}): Promise<any> {
const request = await fetch(url, {
method,
body: body ? JSON.stringify(body) : undefined,
headers: {
'Content-Type': 'application/json',
},
});
const data = await request.json();
return request.ok
? data
: Promise.reject(data?.error || i18n.t('common:generic-error'));
}

53
inertia/lib/search.tsx Normal file
View File

@@ -0,0 +1,53 @@
import PATHS from '#constants/paths';
import Collection from '#models/collection';
import Link from '#models/link';
import { SearchItem, SearchResult } from '~/types/search';
export function buildSearchItem(
item: Collection | Link,
type: SearchItem['type']
): SearchItem {
return {
id: item.id,
name: item.name,
url:
type === 'link'
? (item as Link).url
: `${PATHS.DASHBOARD}?collectionId=${item.id}`,
type,
collection: type === 'link' ? (item as Link).collection : undefined,
};
}
export function formatSearchItem(
item: SearchItem,
searchTerm: string
): SearchResult | null {
const lowerCaseSearchTerm = searchTerm.toLowerCase().trim();
const lowerCaseName = item.name.toLowerCase().trim();
let currentIndex = 0;
let formattedName = '';
for (const [i, element] of Object(lowerCaseName).entries()) {
if (element === lowerCaseSearchTerm[currentIndex]) {
formattedName += `<b>${item.name[i]}</b>`;
currentIndex++;
} else {
formattedName += item.name[i];
}
}
if (currentIndex !== lowerCaseSearchTerm.length) {
// Search term not fully matched
return null;
}
return {
id: item.id,
name: <div dangerouslySetInnerHTML={{ __html: formattedName }} />,
url: item.url,
type: item.type,
collection: item.collection,
};
}