mirror of
https://github.com/cssgunc/compass.git
synced 2025-04-09 14:00:15 -04:00
Add prettier and reformat project
This commit is contained in:
parent
3fd0a545e7
commit
f2765ecb47
6
compass/.prettierrc
Normal file
6
compass/.prettierrc
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"trailingComma": "es5",
|
||||
"tabWidth": 4,
|
||||
"semi": true,
|
||||
"singleQuote": false
|
||||
}
|
26
compass/app/auth/actions.ts
Normal file
26
compass/app/auth/actions.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
"use server";
|
||||
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
import { createClient } from "@/utils/supabase/server";
|
||||
|
||||
export async function login(username: string, password: string) {
|
||||
const supabase = createClient();
|
||||
|
||||
// type-casting here for convenience
|
||||
// in practice, you should validate your inputs
|
||||
const data = {
|
||||
email: username,
|
||||
password: password,
|
||||
};
|
||||
|
||||
const { error } = await supabase.auth.signInWithPassword(data);
|
||||
|
||||
if (error) {
|
||||
redirect("/auth/error");
|
||||
}
|
||||
|
||||
revalidatePath("/resource", "layout");
|
||||
redirect("/resource");
|
||||
}
|
3
compass/app/auth/error/page.tsx
Normal file
3
compass/app/auth/error/page.tsx
Normal file
|
@ -0,0 +1,3 @@
|
|||
export default function ErrorPage() {
|
||||
return <p>Sorry, something went wrong</p>;
|
||||
}
|
|
@ -1,25 +1,23 @@
|
|||
// pages/forgot-password.tsx
|
||||
"use client";
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import Input from '@/components/Input';
|
||||
import Button from '@/components/Button';
|
||||
import InlineLink from '@/components/InlineLink';
|
||||
import ErrorBanner from '@/components/auth/ErrorBanner';
|
||||
|
||||
import React, { useState } from "react";
|
||||
import Input from "@/components/Input";
|
||||
import Button from "@/components/Button";
|
||||
import InlineLink from "@/components/InlineLink";
|
||||
import ErrorBanner from "@/components/auth/ErrorBanner";
|
||||
|
||||
export default function ForgotPasswordPage() {
|
||||
const [confirmEmail, setConfirmEmail] = useState("");
|
||||
const [emailError, setEmailError] = useState<string | null>(null);
|
||||
|
||||
|
||||
function isValidEmail(email: string): boolean {
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
if (email.trim() === '') {
|
||||
setEmailError('Email cannot be empty');
|
||||
if (email.trim() === "") {
|
||||
setEmailError("Email cannot be empty");
|
||||
return false;
|
||||
} else if (!emailRegex.test(email)) {
|
||||
setEmailError('Invalid email format');
|
||||
setEmailError("Invalid email format");
|
||||
return false;
|
||||
}
|
||||
return true; // No error
|
||||
|
@ -27,14 +25,16 @@ export default function ForgotPasswordPage() {
|
|||
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||
isValidEmail(confirmEmail);
|
||||
event.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<h1 className="font-bold text-xl text-purple-800">Forgot Password</h1>
|
||||
<h1 className="font-bold text-xl text-purple-800">
|
||||
Forgot Password
|
||||
</h1>
|
||||
<div className="mb-6">
|
||||
<Input
|
||||
type='email'
|
||||
type="email"
|
||||
valid={emailError == null}
|
||||
title="Enter your email address"
|
||||
placeholder="janedoe@gmail.com"
|
||||
|
@ -44,14 +44,11 @@ export default function ForgotPasswordPage() {
|
|||
</div>
|
||||
{emailError && <ErrorBanner heading={emailError} />}
|
||||
<div className="flex flex-col items-left space-y-4">
|
||||
<InlineLink href="/auth/login">
|
||||
Back to Sign In
|
||||
</InlineLink>
|
||||
<InlineLink href="/auth/login">Back to Sign In</InlineLink>
|
||||
<Button type="submit" onClick={handleClick}>
|
||||
Send
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
|
||||
import Paper from '@/components/auth/Paper';
|
||||
|
||||
import Paper from "@/components/auth/Paper";
|
||||
|
||||
export default function RootLayout({
|
||||
// Layouts must accept a children prop.
|
||||
// This will be populated with nested layouts or pages
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<Paper>
|
||||
|
@ -18,5 +16,5 @@ export default function RootLayout({
|
|||
© 2024 Compass Center
|
||||
</p>
|
||||
</Paper>
|
||||
)
|
||||
);
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
// pages/index.tsx
|
||||
"use client";
|
||||
|
||||
import Button from '@/components/Button';
|
||||
import Input from '@/components/Input'
|
||||
import InlineLink from '@/components/InlineLink';
|
||||
import Image from 'next/image';
|
||||
import Button from "@/components/Button";
|
||||
import Input from "@/components/Input";
|
||||
import InlineLink from "@/components/InlineLink";
|
||||
import Image from "next/image";
|
||||
import { useState } from "react";
|
||||
import PasswordInput from '@/components/auth/PasswordInput';
|
||||
import ErrorBanner from '@/components/auth/ErrorBanner';
|
||||
import PasswordInput from "@/components/auth/PasswordInput";
|
||||
import ErrorBanner from "@/components/auth/ErrorBanner";
|
||||
|
||||
export default function Page() {
|
||||
const [email, setEmail] = useState("");
|
||||
|
@ -17,51 +17,62 @@ export default function Page() {
|
|||
|
||||
const handleEmailChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setEmail(event.currentTarget.value);
|
||||
}
|
||||
};
|
||||
|
||||
const handlePasswordChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const handlePasswordChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
setPassword(event.currentTarget.value);
|
||||
}
|
||||
};
|
||||
|
||||
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||
// Priority: Incorrect combo > Missing email > Missing password
|
||||
|
||||
if (password.trim().length === 0) {
|
||||
setEmailError("Please enter your password.")
|
||||
setEmailError("Please enter your password.");
|
||||
event.preventDefault();
|
||||
}
|
||||
// This shouldn't happen, <input type="email"> already provides validation, but just in case.
|
||||
if (email.trim().length === 0) {
|
||||
setPasswordError("Please enter your email.")
|
||||
setPasswordError("Please enter your email.");
|
||||
event.preventDefault();
|
||||
}
|
||||
// Placeholder for incorrect email + password combo.
|
||||
if (email === "incorrect@gmail.com" && password) {
|
||||
setPasswordError("Incorrect password.")
|
||||
setPasswordError("Incorrect password.");
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Image
|
||||
src="/logo.png"
|
||||
alt='Compass Center logo.'
|
||||
alt="Compass Center logo."
|
||||
width={100}
|
||||
height={91}
|
||||
/>
|
||||
|
||||
<h1 className='font-bold text-2xl text-purple-800'>Login</h1>
|
||||
<h1 className="font-bold text-2xl text-purple-800">Login</h1>
|
||||
|
||||
<div className="mb-6">
|
||||
<Input type='email' valid={emailError == ""} title="Email" placeholder="janedoe@gmail.com" onChange={handleEmailChange} required />
|
||||
|
||||
<Input
|
||||
type="email"
|
||||
valid={emailError == ""}
|
||||
title="Email"
|
||||
placeholder="janedoe@gmail.com"
|
||||
onChange={handleEmailChange}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
{emailError && <ErrorBanner heading={emailError} />}
|
||||
|
||||
<div className="mb-6">
|
||||
<PasswordInput title="Password" valid={passwordError == ""} onChange={handlePasswordChange} />
|
||||
|
||||
<PasswordInput
|
||||
title="Password"
|
||||
valid={passwordError == ""}
|
||||
onChange={handlePasswordChange}
|
||||
/>
|
||||
</div>
|
||||
{passwordError && <ErrorBanner heading={passwordError} />}
|
||||
|
||||
|
@ -69,13 +80,8 @@ export default function Page() {
|
|||
<InlineLink href="/auth/forgot_password">
|
||||
Forgot password?
|
||||
</InlineLink>
|
||||
<Button onClick={handleClick}>
|
||||
Login
|
||||
</Button>
|
||||
<Button onClick={handleClick}>Login</Button>
|
||||
</div>
|
||||
|
||||
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,31 +1,36 @@
|
|||
// pages/index.tsx
|
||||
"use client";
|
||||
import { useState, useEffect } from 'react';
|
||||
import Button from '@/components/Button';
|
||||
import PasswordInput from '@/components/auth/PasswordInput';
|
||||
import ErrorBanner from '@/components/auth/ErrorBanner';
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import Button from "@/components/Button";
|
||||
import PasswordInput from "@/components/auth/PasswordInput";
|
||||
import ErrorBanner from "@/components/auth/ErrorBanner";
|
||||
|
||||
function isStrongPassword(password: string): boolean {
|
||||
const strongPasswordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*]).{8,}$/;
|
||||
const strongPasswordRegex =
|
||||
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*]).{8,}$/;
|
||||
return strongPasswordRegex.test(password);
|
||||
}
|
||||
|
||||
|
||||
export default function Page() {
|
||||
const [newPassword, setNewPassword] = useState('');
|
||||
const [confirmPassword, setConfirmPassword] = useState('');
|
||||
const [newPassword, setNewPassword] = useState("");
|
||||
const [confirmPassword, setConfirmPassword] = useState("");
|
||||
const [isButtonDisabled, setIsButtonDisabled] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
setIsButtonDisabled(newPassword === '' || confirmPassword === '' || newPassword !== confirmPassword|| !isStrongPassword(newPassword));
|
||||
setIsButtonDisabled(
|
||||
newPassword === "" ||
|
||||
confirmPassword === "" ||
|
||||
newPassword !== confirmPassword ||
|
||||
!isStrongPassword(newPassword)
|
||||
);
|
||||
}, [newPassword, confirmPassword]);
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="text-center sm:text-left">
|
||||
<h1 className="font-bold text-xl text-purple-800">New Password</h1>
|
||||
<h1 className="font-bold text-xl text-purple-800">
|
||||
New Password
|
||||
</h1>
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
<PasswordInput
|
||||
|
@ -37,26 +42,38 @@ export default function Page() {
|
|||
}}
|
||||
/>
|
||||
</div>
|
||||
{isStrongPassword(newPassword) || newPassword === '' ? null : <ErrorBanner heading="Password is not strong enough." description="Tip: Use a mix of letters, numbers, and symbols for a strong password. Aim for at least 8 characters!" />}
|
||||
{isStrongPassword(newPassword) || newPassword === "" ? null : (
|
||||
<ErrorBanner
|
||||
heading="Password is not strong enough."
|
||||
description="Tip: Use a mix of letters, numbers, and symbols for a strong password. Aim for at least 8 characters!"
|
||||
/>
|
||||
)}
|
||||
<div className="mb-6">
|
||||
<PasswordInput
|
||||
title="Confirm Password"
|
||||
value={confirmPassword}
|
||||
valid={!isButtonDisabled || (newPassword === confirmPassword && confirmPassword !== '')}
|
||||
valid={
|
||||
!isButtonDisabled ||
|
||||
(newPassword === confirmPassword &&
|
||||
confirmPassword !== "")
|
||||
}
|
||||
onChange={(e) => {
|
||||
setConfirmPassword(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{newPassword === confirmPassword || confirmPassword === '' ? null : <ErrorBanner heading="Passwords do not match." description="Please make sure both passwords are the exact same!"/>}
|
||||
{newPassword === confirmPassword ||
|
||||
confirmPassword === "" ? null : (
|
||||
<ErrorBanner
|
||||
heading="Passwords do not match."
|
||||
description="Please make sure both passwords are the exact same!"
|
||||
/>
|
||||
)}
|
||||
<div className="flex flex-col items-left space-y-4">
|
||||
<Button type="submit" disabled={isButtonDisabled} >
|
||||
<Button type="submit" disabled={isButtonDisabled}>
|
||||
Send
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
import '../styles/globals.css';
|
||||
|
||||
import "../styles/globals.css";
|
||||
|
||||
export default function RootLayout({
|
||||
// Layouts must accept a children prop.
|
||||
// This will be populated with nested layouts or pages
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body>{children}</body>
|
||||
</html>
|
||||
)
|
||||
);
|
||||
}
|
|
@ -28,7 +28,9 @@ export default function Page() {
|
|||
console.log("email " + email);
|
||||
};
|
||||
|
||||
const handlePasswordChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const handlePasswordChange = (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
setPassword(event.currentTarget.value);
|
||||
console.log("password " + password);
|
||||
};
|
||||
|
@ -77,9 +79,14 @@ export default function Page() {
|
|||
/>
|
||||
</div>
|
||||
<div className="flex flex-col items-left space-y-4">
|
||||
<InlineLink href="/forgot_password">Forgot password?</InlineLink>
|
||||
<InlineLink href="/forgot_password">
|
||||
Forgot password?
|
||||
</InlineLink>
|
||||
<Button onClick={handleClick}>Login</Button>
|
||||
<div className="text-center text-red-600" hidden={!error}>
|
||||
<div
|
||||
className="text-center text-red-600"
|
||||
hidden={!error}
|
||||
>
|
||||
<p>{error}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
"use client"
|
||||
"use client";
|
||||
|
||||
import Sidebar from '@/components/resource/Sidebar';
|
||||
import React, { useState } from 'react';
|
||||
import { ChevronDoubleRightIcon } from '@heroicons/react/24/outline';
|
||||
import Sidebar from "@/components/resource/Sidebar";
|
||||
import React, { useState } from "react";
|
||||
import { ChevronDoubleRightIcon } from "@heroicons/react/24/outline";
|
||||
|
||||
export default function RootLayout({
|
||||
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
|
||||
|
||||
|
@ -18,20 +17,26 @@ export default function RootLayout({
|
|||
<button
|
||||
onClick={() => setIsSidebarOpen(!isSidebarOpen)}
|
||||
className={`fixed z-20 p-2 text-gray-500 hover:text-gray-800 left-0`}
|
||||
aria-label={'Open sidebar'}
|
||||
aria-label={"Open sidebar"}
|
||||
>
|
||||
{!isSidebarOpen &&
|
||||
<ChevronDoubleRightIcon className="h-5 w-5" /> // Icon for closing the sidebar
|
||||
{
|
||||
!isSidebarOpen && (
|
||||
<ChevronDoubleRightIcon className="h-5 w-5" />
|
||||
) // Icon for closing the sidebar
|
||||
}
|
||||
</button>
|
||||
{/* sidebar */}
|
||||
<div className={`absolute inset-y-0 left-0 transform ${isSidebarOpen ? 'translate-x-0' : '-translate-x-full'} w-64 transition duration-300 ease-in-out`}>
|
||||
<div
|
||||
className={`absolute inset-y-0 left-0 transform ${isSidebarOpen ? "translate-x-0" : "-translate-x-full"} w-64 transition duration-300 ease-in-out`}
|
||||
>
|
||||
<Sidebar setIsSidebarOpen={setIsSidebarOpen} />
|
||||
</div>
|
||||
{/* page ui */}
|
||||
<div className={`flex-1 transition duration-300 ease-in-out ${isSidebarOpen ? 'ml-64' : 'ml-0'}`}>
|
||||
<div
|
||||
className={`flex-1 transition duration-300 ease-in-out ${isSidebarOpen ? "ml-64" : "ml-0"}`}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
|
@ -1,9 +1,13 @@
|
|||
"use client"
|
||||
"use client";
|
||||
import Callout from "@/components/resource/Callout";
|
||||
import Card from "@/components/resource/Card";
|
||||
import { LandingSearchBar } from "@/components/resource/LandingSearchBar";
|
||||
import { BookOpenIcon, BookmarkIcon, ClipboardIcon } from "@heroicons/react/24/solid";
|
||||
import Image from 'next/image';
|
||||
import {
|
||||
BookOpenIcon,
|
||||
BookmarkIcon,
|
||||
ClipboardIcon,
|
||||
} from "@heroicons/react/24/solid";
|
||||
import Image from "next/image";
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
|
@ -13,15 +17,26 @@ export default function Page() {
|
|||
<div className="mb-4 flex items-center space-x-4">
|
||||
<Image
|
||||
src="/logo.png"
|
||||
alt='Compass Center logo.'
|
||||
alt="Compass Center logo."
|
||||
width={25}
|
||||
height={25}
|
||||
/>
|
||||
<h1 className='font-bold text-2xl text-purple-800'>Compass Center Advocate Landing Page</h1>
|
||||
<h1 className="font-bold text-2xl text-purple-800">
|
||||
Compass Center Advocate Landing Page
|
||||
</h1>
|
||||
</div>
|
||||
<Callout>
|
||||
Welcome! Below you will find a list of resources for the Compass Center's trained advocates. These materials serve to virtually provide a collection of advocacy, resource, and hotline manuals and information.
|
||||
<b> If you are an advocate looking for the contact information of a particular Compass Center employee, please directly contact your staff back-up or the person in charge of your training.</b>
|
||||
Welcome! Below you will find a list of resources for the
|
||||
Compass Center's trained advocates. These materials serve to
|
||||
virtually provide a collection of advocacy, resource, and
|
||||
hotline manuals and information.
|
||||
<b>
|
||||
{" "}
|
||||
If you are an advocate looking for the contact
|
||||
information of a particular Compass Center employee,
|
||||
please directly contact your staff back-up or the person
|
||||
in charge of your training.
|
||||
</b>
|
||||
</Callout>
|
||||
</div>
|
||||
<div className="p-8 flex-grow border-t border-gray-200 bg-gray-50">
|
||||
|
@ -35,5 +50,5 @@ export default function Page() {
|
|||
<LandingSearchBar />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { FunctionComponent, ReactNode } from 'react';
|
||||
import { FunctionComponent, ReactNode } from "react";
|
||||
|
||||
type ButtonProps = {
|
||||
children: ReactNode;
|
||||
|
@ -7,9 +7,13 @@ type ButtonProps = {
|
|||
disabled?: boolean;
|
||||
};
|
||||
|
||||
|
||||
const Button: FunctionComponent<ButtonProps> = ({ children, type, disabled, onClick}) => {
|
||||
const buttonClassName = `inline-block rounded border ${disabled ? 'bg-gray-400 text-gray-600 cursor-not-allowed' : 'border-purple-600 bg-purple-600 text-white hover:bg-transparent hover:text-purple-600 focus:outline-none focus:ring active:text-purple-500'} px-4 py-1 text-md font-semibold w-20 h-10 text-center`;
|
||||
const Button: FunctionComponent<ButtonProps> = ({
|
||||
children,
|
||||
type,
|
||||
disabled,
|
||||
onClick,
|
||||
}) => {
|
||||
const buttonClassName = `inline-block rounded border ${disabled ? "bg-gray-400 text-gray-600 cursor-not-allowed" : "border-purple-600 bg-purple-600 text-white hover:bg-transparent hover:text-purple-600 focus:outline-none focus:ring active:text-purple-500"} px-4 py-1 text-md font-semibold w-20 h-10 text-center`;
|
||||
|
||||
return (
|
||||
<button
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
import React, { ReactNode } from 'react';
|
||||
import React, { ReactNode } from "react";
|
||||
|
||||
interface Link {
|
||||
href?: string;
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
const InlineLink: React.FC<Link> = ({href = '#', children}) => {
|
||||
const InlineLink: React.FC<Link> = ({ href = "#", children }) => {
|
||||
return (
|
||||
<a href={href} className='text-sm text-purple-600 hover:underline font-semibold'>
|
||||
<a
|
||||
href={href}
|
||||
className="text-sm text-purple-600 hover:underline font-semibold"
|
||||
>
|
||||
{children}
|
||||
</a>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export default InlineLink;
|
|
@ -1,22 +1,42 @@
|
|||
import React, { FunctionComponent, InputHTMLAttributes, ReactNode, ChangeEvent } from 'react';
|
||||
import React, {
|
||||
FunctionComponent,
|
||||
InputHTMLAttributes,
|
||||
ReactNode,
|
||||
ChangeEvent,
|
||||
} from "react";
|
||||
|
||||
type InputProps = InputHTMLAttributes<HTMLInputElement> & {
|
||||
icon?: ReactNode;
|
||||
title?: ReactNode;
|
||||
type?:ReactNode;
|
||||
placeholder?:ReactNode
|
||||
valid?:boolean;
|
||||
type?: ReactNode;
|
||||
placeholder?: ReactNode;
|
||||
valid?: boolean;
|
||||
onChange: (event: ChangeEvent<HTMLInputElement>) => void;
|
||||
};
|
||||
|
||||
const Input: FunctionComponent<InputProps> = ({ icon, type, title, placeholder, onChange, valid = true, ...rest }) => {
|
||||
const Input: FunctionComponent<InputProps> = ({
|
||||
icon,
|
||||
type,
|
||||
title,
|
||||
placeholder,
|
||||
onChange,
|
||||
valid = true,
|
||||
...rest
|
||||
}) => {
|
||||
return (
|
||||
<div>
|
||||
<label
|
||||
htmlFor={title}
|
||||
className={valid ? "block overflow-hidden rounded-md border border-gray-200 px-3 py-2 shadow-sm focus-within:border-purple-600 focus-within:ring-1 focus-within:ring-purple-600" : "block overflow-hidden rounded-md border border-gray-200 px-3 py-2 shadow-sm focus-within:border-red-600 focus-within:ring-1 focus-within:ring-red-600"}
|
||||
>
|
||||
<span className="text-xs font-semibold text-gray-700"> {title} </span>
|
||||
className={
|
||||
valid
|
||||
? "block overflow-hidden rounded-md border border-gray-200 px-3 py-2 shadow-sm focus-within:border-purple-600 focus-within:ring-1 focus-within:ring-purple-600"
|
||||
: "block overflow-hidden rounded-md border border-gray-200 px-3 py-2 shadow-sm focus-within:border-red-600 focus-within:ring-1 focus-within:ring-red-600"
|
||||
}
|
||||
>
|
||||
<span className="text-xs font-semibold text-gray-700">
|
||||
{" "}
|
||||
{title}{" "}
|
||||
</span>
|
||||
<div className="mt-1 flex items-center">
|
||||
<input
|
||||
type={type}
|
||||
|
@ -29,8 +49,8 @@ const Input: FunctionComponent<InputProps> = ({ icon, type, title, placeholder,
|
|||
{icon}
|
||||
</span>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,17 +1,27 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
|
||||
interface ErrorBannerProps {
|
||||
heading: string;
|
||||
description?: string | null;
|
||||
}
|
||||
|
||||
const ErrorBanner: React.FC<ErrorBannerProps> = ({ heading, description = null }) => {
|
||||
const ErrorBanner: React.FC<ErrorBannerProps> = ({
|
||||
heading,
|
||||
description = null,
|
||||
}) => {
|
||||
return (
|
||||
<div role="alert" className="rounded border-s-4 border-red-500 bg-red-50 p-4">
|
||||
<strong className="block text-sm font-semibold text-red-800">{heading}</strong>
|
||||
{description && <p className="mt-2 text-xs font-thin text-red-700">
|
||||
<div
|
||||
role="alert"
|
||||
className="rounded border-s-4 border-red-500 bg-red-50 p-4"
|
||||
>
|
||||
<strong className="block text-sm font-semibold text-red-800">
|
||||
{heading}
|
||||
</strong>
|
||||
{description && (
|
||||
<p className="mt-2 text-xs font-thin text-red-700">
|
||||
{description}
|
||||
</p>}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { ReactNode } from 'react';
|
||||
import React, { ReactNode } from "react";
|
||||
|
||||
interface PageInterface {
|
||||
children: ReactNode;
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
import React, { useState, FunctionComponent, ChangeEvent, ReactNode } from 'react';
|
||||
import Input from '../Input'; // Adjust the import path as necessary
|
||||
import { Icons } from '@/utils/constants';
|
||||
import React, {
|
||||
useState,
|
||||
FunctionComponent,
|
||||
ChangeEvent,
|
||||
ReactNode,
|
||||
} from "react";
|
||||
import Input from "../Input"; // Adjust the import path as necessary
|
||||
import { Icons } from "@/utils/constants";
|
||||
|
||||
type PasswordInputProps = {
|
||||
title?: ReactNode; // Assuming you might want to reuse title, placeholder etc.
|
||||
|
@ -9,14 +14,20 @@ type PasswordInputProps = {
|
|||
onChange: (event: ChangeEvent<HTMLInputElement>) => void;
|
||||
};
|
||||
|
||||
const PasswordInput: FunctionComponent<PasswordInputProps> = ({ onChange, valid = true, ...rest }) => {
|
||||
const PasswordInput: FunctionComponent<PasswordInputProps> = ({
|
||||
onChange,
|
||||
valid = true,
|
||||
...rest
|
||||
}) => {
|
||||
const [visible, setVisible] = useState(false);
|
||||
|
||||
const toggleVisibility = () => {
|
||||
setVisible(!visible);
|
||||
};
|
||||
|
||||
const PasswordIcon = visible ? Icons['HidePasswordIcon'] : Icons['UnhidePasswordIcon'];
|
||||
const PasswordIcon = visible
|
||||
? Icons["HidePasswordIcon"]
|
||||
: Icons["UnhidePasswordIcon"];
|
||||
|
||||
// Render the Input component and pass the PasswordIcon as an icon prop
|
||||
return (
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import React, { ReactNode } from "react";
|
||||
|
||||
|
||||
interface TagProps {
|
||||
text: string;
|
||||
icon: React.ReactNode;
|
||||
|
@ -9,9 +8,7 @@ interface TagProps {
|
|||
const Card: React.FC<TagProps> = ({ text, icon }) => {
|
||||
return (
|
||||
<div className="flex flex-row space-x-2 items-start justify-start border border-gray-200 bg-white hover:bg-gray-50 shadow rounded-md p-4">
|
||||
<span className="h-5 text-purple-700 w-5">
|
||||
{icon}
|
||||
</span>
|
||||
<span className="h-5 text-purple-700 w-5">{icon}</span>
|
||||
<span className="text-sm text-gray-800 font-semibold">{text}</span>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
import { MagnifyingGlassIcon, XMarkIcon } from "@heroicons/react/24/solid"
|
||||
import React, { useState } from 'react';
|
||||
import Image from 'next/image';
|
||||
import { MagnifyingGlassIcon, XMarkIcon } from "@heroicons/react/24/solid";
|
||||
import React, { useState } from "react";
|
||||
import Image from "next/image";
|
||||
|
||||
export const LandingSearchBar: React.FC = () => {
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
|
||||
const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setSearchTerm(event.target.value);
|
||||
};
|
||||
|
||||
const clearSearch = () => {
|
||||
setSearchTerm('');
|
||||
setSearchTerm("");
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -28,20 +28,32 @@ export const LandingSearchBar: React.FC = () => {
|
|||
</div>
|
||||
{/* input */}
|
||||
{searchTerm && (
|
||||
<button
|
||||
onClick={clearSearch}
|
||||
>
|
||||
<XMarkIcon className="h-5 w-5 text-gray-500" aria-hidden="true" />
|
||||
<button onClick={clearSearch}>
|
||||
<XMarkIcon
|
||||
className="h-5 w-5 text-gray-500"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</button>
|
||||
)}
|
||||
<div className="p-3">
|
||||
<MagnifyingGlassIcon className="h-5 w-5 text-gray-500" aria-hidden="true" />
|
||||
<MagnifyingGlassIcon
|
||||
className="h-5 w-5 text-gray-500"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/* search results, for now since it's empty this is the default screen */}
|
||||
<div className="flex flex-col pt-16 space-y-2 justify-center items-center">
|
||||
<Image alt="Landing illustration" src="/landing_illustration.png" width={250} height={250} />
|
||||
<h2 className="font-medium text-medium text-gray-800">Need to find something? Use the links or the search bar above to get your results.</h2>
|
||||
<Image
|
||||
alt="Landing illustration"
|
||||
src="/landing_illustration.png"
|
||||
width={250}
|
||||
height={250}
|
||||
/>
|
||||
<h2 className="font-medium text-medium text-gray-800">
|
||||
Need to find something? Use the links or the search bar
|
||||
above to get your results.
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
import React from 'react';
|
||||
import { HomeIcon, ChevronDoubleLeftIcon, BookmarkIcon, ClipboardIcon, BookOpenIcon } from '@heroicons/react/24/solid';
|
||||
import { SidebarItem } from './SidebarItem';
|
||||
import { UserProfile } from './UserProfile';
|
||||
import React from "react";
|
||||
import {
|
||||
HomeIcon,
|
||||
ChevronDoubleLeftIcon,
|
||||
BookmarkIcon,
|
||||
ClipboardIcon,
|
||||
BookOpenIcon,
|
||||
} from "@heroicons/react/24/solid";
|
||||
import { SidebarItem } from "./SidebarItem";
|
||||
import { UserProfile } from "./UserProfile";
|
||||
|
||||
interface SidebarProps {
|
||||
setIsSidebarOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
|
@ -21,20 +27,23 @@ const Sidebar: React.FC<SidebarProps> = ({ setIsSidebarOpen }) => {
|
|||
</button>
|
||||
</div>
|
||||
<div className="flex flex-col space-y-8">
|
||||
|
||||
{/* user + logout button */}
|
||||
<div className="flex items-center p-4 space-x-2 border border-gray-200 rounded-md ">
|
||||
|
||||
<UserProfile />
|
||||
</div>
|
||||
{/* navigation menu */}
|
||||
<div className="flex flex-col space-y-2">
|
||||
<h4 className="text-xs font-semibold text-gray-500">Pages</h4>
|
||||
<h4 className="text-xs font-semibold text-gray-500">
|
||||
Pages
|
||||
</h4>
|
||||
<nav className="flex flex-col">
|
||||
<SidebarItem icon={<HomeIcon />} text="Home" />
|
||||
<SidebarItem icon={<BookmarkIcon />} text="Resources" />
|
||||
<SidebarItem icon={<ClipboardIcon />} text="Services" />
|
||||
<SidebarItem icon={<BookOpenIcon />} text="Training Manuals" />
|
||||
<SidebarItem
|
||||
icon={<BookOpenIcon />}
|
||||
text="Training Manuals"
|
||||
/>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -42,5 +51,4 @@ const Sidebar: React.FC<SidebarProps> = ({ setIsSidebarOpen }) => {
|
|||
);
|
||||
};
|
||||
|
||||
|
||||
export default Sidebar;
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
interface SidebarItemProps {
|
||||
icon: React.ReactElement;
|
||||
text: string;
|
||||
|
@ -6,11 +5,14 @@ interface SidebarItemProps {
|
|||
|
||||
export const SidebarItem: React.FC<SidebarItemProps> = ({ icon, text }) => {
|
||||
return (
|
||||
<a href="#" className="flex items-center p-2 space-x-2 hover:bg-gray-200 rounded-md">
|
||||
<span className="h-5 text-gray-500 w-5">
|
||||
{icon}
|
||||
<a
|
||||
href="#"
|
||||
className="flex items-center p-2 space-x-2 hover:bg-gray-200 rounded-md"
|
||||
>
|
||||
<span className="h-5 text-gray-500 w-5">{icon}</span>
|
||||
<span className="flex-grow font-medium text-xs text-gray-500">
|
||||
{text}
|
||||
</span>
|
||||
<span className="flex-grow font-medium text-xs text-gray-500">{text}</span>
|
||||
</a>
|
||||
);
|
||||
};
|
|
@ -2,10 +2,14 @@ export const UserProfile = () => {
|
|||
return (
|
||||
<div className="flex flex-col items-start space-y-2">
|
||||
<div className="flex flex-col">
|
||||
<span className="text-sm font-semibold text-gray-800">Compass Center</span>
|
||||
<span className="text-sm font-semibold text-gray-800">
|
||||
Compass Center
|
||||
</span>
|
||||
<span className="text-xs text-gray-500">cssgunc@gmail.com</span>
|
||||
</div>
|
||||
<button className="text-red-600 font-semibold text-xs hover:underline mt-1">Sign out</button>
|
||||
<button className="text-red-600 font-semibold text-xs hover:underline mt-1">
|
||||
Sign out
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
images: {
|
||||
domains: ['notioly.com']
|
||||
domains: ["notioly.com"],
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = nextConfig
|
||||
module.exports = nextConfig;
|
||||
|
|
766
compass/package-lock.json
generated
766
compass/package-lock.json
generated
|
@ -9,6 +9,8 @@
|
|||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@heroicons/react": "^2.1.1",
|
||||
"@supabase/ssr": "^0.3.0",
|
||||
"@supabase/supabase-js": "^2.42.3",
|
||||
"next": "13.5.6",
|
||||
"react": "^18",
|
||||
"react-dom": "^18"
|
||||
|
@ -20,6 +22,8 @@
|
|||
"autoprefixer": "^10",
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "13.5.6",
|
||||
"husky": "^9.0.11",
|
||||
"lint-staged": "^15.2.2",
|
||||
"postcss": "^8",
|
||||
"tailwindcss": "^3",
|
||||
"typescript": "^5"
|
||||
|
@ -393,6 +397,85 @@
|
|||
"integrity": "sha512-6i/8UoL0P5y4leBIGzvkZdS85RDMG9y1ihZzmTZQ5LdHUYmZ7pKFoj8X0236s3lusPs1Fa5HTQUpwI+UfTcmeA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@supabase/auth-js": {
|
||||
"version": "2.63.0",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.63.0.tgz",
|
||||
"integrity": "sha512-yIgcHnlgv24GxHtVGUhwGqAFDyJkPIC/xjx7HostN08A8yCy8HIfl4JEkTKyBqD1v1L05jNEJOUke4Lf4O1+Qg==",
|
||||
"dependencies": {
|
||||
"@supabase/node-fetch": "^2.6.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@supabase/functions-js": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.2.2.tgz",
|
||||
"integrity": "sha512-sJGq1nludmi7pY/fdtCpyY/pYonx7MfHdN408bqb736guWcVI1AChYVbI4kUM978EuOE4Ci6l7bUudfGg07QRw==",
|
||||
"dependencies": {
|
||||
"@supabase/node-fetch": "^2.6.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@supabase/node-fetch": {
|
||||
"version": "2.6.15",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/node-fetch/-/node-fetch-2.6.15.tgz",
|
||||
"integrity": "sha512-1ibVeYUacxWYi9i0cf5efil6adJ9WRyZBLivgjs+AUpewx1F3xPi7gLgaASI2SmIQxPoCEjAsLAzKPgMJVgOUQ==",
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@supabase/postgrest-js": {
|
||||
"version": "1.15.2",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.15.2.tgz",
|
||||
"integrity": "sha512-9/7pUmXExvGuEK1yZhVYXPZnLEkDTwxgMQHXLrN5BwPZZm4iUCL1YEyep/Z2lIZah8d8M433mVAUEGsihUj5KQ==",
|
||||
"dependencies": {
|
||||
"@supabase/node-fetch": "^2.6.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@supabase/realtime-js": {
|
||||
"version": "2.9.4",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.9.4.tgz",
|
||||
"integrity": "sha512-wdq+2hZpgw0r2ldRs87d3U08Y8BrsO1bZxPNqbImpYshAEkusDz4vufR8KaqujKxqewmXS6YnUhuRVdvSEIKCA==",
|
||||
"dependencies": {
|
||||
"@supabase/node-fetch": "^2.6.14",
|
||||
"@types/phoenix": "^1.5.4",
|
||||
"@types/ws": "^8.5.10",
|
||||
"ws": "^8.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@supabase/ssr": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/ssr/-/ssr-0.3.0.tgz",
|
||||
"integrity": "sha512-lcVyQ7H6eumb2FB1Wa2N+jYWMfq6CFza3KapikT0fgttMQ+QvDgpNogx9jI8bZgKds+XFSMCojxFvFb+gwdbfA==",
|
||||
"dependencies": {
|
||||
"cookie": "^0.5.0",
|
||||
"ramda": "^0.29.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@supabase/supabase-js": "^2.33.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@supabase/storage-js": {
|
||||
"version": "2.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.5.5.tgz",
|
||||
"integrity": "sha512-OpLoDRjFwClwc2cjTJZG8XviTiQH4Ik8sCiMK5v7et0MDu2QlXjCAW3ljxJB5+z/KazdMOTnySi+hysxWUPu3w==",
|
||||
"dependencies": {
|
||||
"@supabase/node-fetch": "^2.6.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@supabase/supabase-js": {
|
||||
"version": "2.42.3",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.42.3.tgz",
|
||||
"integrity": "sha512-/o52L/ngsGapcOUygWigvxzBo/bUVM4bubZMsUSZqZc+9sgjXZsgP/cwyggWUv3QOIqmbBrfSPgDLUh+Ofgi7Q==",
|
||||
"dependencies": {
|
||||
"@supabase/auth-js": "2.63.0",
|
||||
"@supabase/functions-js": "2.2.2",
|
||||
"@supabase/node-fetch": "2.6.15",
|
||||
"@supabase/postgrest-js": "1.15.2",
|
||||
"@supabase/realtime-js": "2.9.4",
|
||||
"@supabase/storage-js": "2.5.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/helpers": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz",
|
||||
|
@ -411,11 +494,15 @@
|
|||
"version": "20.8.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.8.tgz",
|
||||
"integrity": "sha512-YRsdVxq6OaLfmR9Hy816IMp33xOBjfyOgUd77ehqg96CFywxAPbDbXvAsuN2KVg2HOT8Eh6uAfU+l4WffwPVrQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~5.25.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/phoenix": {
|
||||
"version": "1.6.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.4.tgz",
|
||||
"integrity": "sha512-B34A7uot1Cv0XtaHRYDATltAdKx0BvVKNgYNqE4WjtPUa4VQJM7kxeXcVKaH+KS+kCmZ+6w+QaUdcljiheiBJA=="
|
||||
},
|
||||
"node_modules/@types/prop-types": {
|
||||
"version": "15.7.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.9.tgz",
|
||||
|
@ -448,6 +535,14 @@
|
|||
"integrity": "sha512-s/FPdYRmZR8SjLWGMCuax7r3qCWQw9QKHzXVukAuuIJkXkDRwp+Pu5LMIVFi0Fxbav35WURicYr8u1QsoybnQw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/ws": {
|
||||
"version": "8.5.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz",
|
||||
"integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser": {
|
||||
"version": "6.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.9.0.tgz",
|
||||
|
@ -593,6 +688,18 @@
|
|||
"url": "https://github.com/sponsors/epoberezkin"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-escapes": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz",
|
||||
"integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=14.16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
|
@ -1055,6 +1162,37 @@
|
|||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/cli-cursor": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz",
|
||||
"integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"restore-cursor": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/cli-truncate": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz",
|
||||
"integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"slice-ansi": "^5.0.0",
|
||||
"string-width": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/client-only": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
|
||||
|
@ -1078,6 +1216,12 @@
|
|||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/colorette": {
|
||||
"version": "2.0.20",
|
||||
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
|
||||
"integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
|
||||
|
@ -1093,6 +1237,14 @@
|
|||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/cookie": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
|
||||
"integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
|
@ -1810,6 +1962,35 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eventemitter3": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
|
||||
"integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/execa": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
|
||||
"integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cross-spawn": "^7.0.3",
|
||||
"get-stream": "^8.0.1",
|
||||
"human-signals": "^5.0.0",
|
||||
"is-stream": "^3.0.0",
|
||||
"merge-stream": "^2.0.0",
|
||||
"npm-run-path": "^5.1.0",
|
||||
"onetime": "^6.0.0",
|
||||
"signal-exit": "^4.1.0",
|
||||
"strip-final-newline": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.17"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sindresorhus/execa?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
|
@ -2003,6 +2184,18 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-east-asian-width": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz",
|
||||
"integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/get-intrinsic": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz",
|
||||
|
@ -2018,6 +2211,18 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-stream": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
|
||||
"integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/get-symbol-description": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
|
||||
|
@ -2246,6 +2451,30 @@
|
|||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/human-signals": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
|
||||
"integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=16.17.0"
|
||||
}
|
||||
},
|
||||
"node_modules/husky": {
|
||||
"version": "9.0.11",
|
||||
"resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz",
|
||||
"integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"husky": "bin.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/typicode"
|
||||
}
|
||||
},
|
||||
"node_modules/ignore": {
|
||||
"version": "5.2.4",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
|
||||
|
@ -2439,6 +2668,18 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-fullwidth-code-point": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz",
|
||||
"integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-generator-function": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
|
||||
|
@ -2557,6 +2798,18 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-stream": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
|
||||
"integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-string": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
|
||||
|
@ -2784,6 +3037,80 @@
|
|||
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/lint-staged": {
|
||||
"version": "15.2.2",
|
||||
"resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.2.tgz",
|
||||
"integrity": "sha512-TiTt93OPh1OZOsb5B7k96A/ATl2AjIZo+vnzFZ6oHK5FuTk63ByDtxGQpHm+kFETjEWqgkF95M8FRXKR/LEBcw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"chalk": "5.3.0",
|
||||
"commander": "11.1.0",
|
||||
"debug": "4.3.4",
|
||||
"execa": "8.0.1",
|
||||
"lilconfig": "3.0.0",
|
||||
"listr2": "8.0.1",
|
||||
"micromatch": "4.0.5",
|
||||
"pidtree": "0.6.0",
|
||||
"string-argv": "0.3.2",
|
||||
"yaml": "2.3.4"
|
||||
},
|
||||
"bin": {
|
||||
"lint-staged": "bin/lint-staged.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.12.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/lint-staged"
|
||||
}
|
||||
},
|
||||
"node_modules/lint-staged/node_modules/chalk": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
|
||||
"integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^12.17.0 || ^14.13 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/lint-staged/node_modules/commander": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
|
||||
"integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/lint-staged/node_modules/lilconfig": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz",
|
||||
"integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/listr2": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/listr2/-/listr2-8.0.1.tgz",
|
||||
"integrity": "sha512-ovJXBXkKGfq+CwmKTjluEqFi3p4h8xvkxGQQAQan22YCgef4KZ1mKGjzfGh6PL6AW5Csw0QiQPNuQyH+6Xk3hA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cli-truncate": "^4.0.0",
|
||||
"colorette": "^2.0.20",
|
||||
"eventemitter3": "^5.0.1",
|
||||
"log-update": "^6.0.0",
|
||||
"rfdc": "^1.3.0",
|
||||
"wrap-ansi": "^9.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/locate-path": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
|
||||
|
@ -2805,6 +3132,95 @@
|
|||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/log-update": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz",
|
||||
"integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-escapes": "^6.2.0",
|
||||
"cli-cursor": "^4.0.0",
|
||||
"slice-ansi": "^7.0.0",
|
||||
"strip-ansi": "^7.1.0",
|
||||
"wrap-ansi": "^9.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/log-update/node_modules/ansi-regex": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
|
||||
"integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/log-update/node_modules/ansi-styles": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
|
||||
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/log-update/node_modules/is-fullwidth-code-point": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz",
|
||||
"integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"get-east-asian-width": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/log-update/node_modules/slice-ansi": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz",
|
||||
"integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^6.2.1",
|
||||
"is-fullwidth-code-point": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/slice-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/log-update/node_modules/strip-ansi": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
|
||||
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-regex": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/loose-envify": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||
|
@ -2828,6 +3244,12 @@
|
|||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/merge-stream": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
||||
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/merge2": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||
|
@ -2850,6 +3272,18 @@
|
|||
"node": ">=8.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mimic-fn": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
|
||||
"integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
|
@ -2980,6 +3414,33 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/npm-run-path": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz",
|
||||
"integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"path-key": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/npm-run-path/node_modules/path-key": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
|
||||
"integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
|
@ -3116,6 +3577,21 @@
|
|||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/onetime": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
|
||||
"integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"mimic-fn": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/optionator": {
|
||||
"version": "0.9.3",
|
||||
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
|
||||
|
@ -3234,6 +3710,18 @@
|
|||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/pidtree": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz",
|
||||
"integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"pidtree": "bin/pidtree.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/pify": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
||||
|
@ -3431,6 +3919,15 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"node_modules/ramda": {
|
||||
"version": "0.29.1",
|
||||
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.29.1.tgz",
|
||||
"integrity": "sha512-OfxIeWzd4xdUNxlWhgFazxsA/nl3mS4/jGZI5n00uWOoSSFRhC1b6gl6xvmzUamgmqELraWp0J/qqVlXYPDPyA==",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/ramda"
|
||||
}
|
||||
},
|
||||
"node_modules/react": {
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
|
||||
|
@ -3559,6 +4056,52 @@
|
|||
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/restore-cursor": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz",
|
||||
"integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"onetime": "^5.1.0",
|
||||
"signal-exit": "^3.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/restore-cursor/node_modules/mimic-fn": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
|
||||
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/restore-cursor/node_modules/onetime": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
||||
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"mimic-fn": "^2.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/restore-cursor/node_modules/signal-exit": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
|
||||
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/reusify": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||
|
@ -3569,6 +4112,12 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rfdc": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz",
|
||||
"integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/rimraf": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||
|
@ -3726,6 +4275,18 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/signal-exit": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
|
||||
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/slash": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
||||
|
@ -3735,6 +4296,34 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/slice-ansi": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz",
|
||||
"integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^6.0.0",
|
||||
"is-fullwidth-code-point": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/slice-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/slice-ansi/node_modules/ansi-styles": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
|
||||
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||
|
@ -3751,6 +4340,65 @@
|
|||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/string-argv": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz",
|
||||
"integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.6.19"
|
||||
}
|
||||
},
|
||||
"node_modules/string-width": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz",
|
||||
"integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"emoji-regex": "^10.3.0",
|
||||
"get-east-asian-width": "^1.0.0",
|
||||
"strip-ansi": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/string-width/node_modules/ansi-regex": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
|
||||
"integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/string-width/node_modules/emoji-regex": {
|
||||
"version": "10.3.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz",
|
||||
"integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/string-width/node_modules/strip-ansi": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
|
||||
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-regex": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/string.prototype.matchall": {
|
||||
"version": "4.0.10",
|
||||
"resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz",
|
||||
|
@ -3837,6 +4485,18 @@
|
|||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-final-newline": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
|
||||
"integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-json-comments": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
|
||||
|
@ -4022,6 +4682,11 @@
|
|||
"node": ">=8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||
},
|
||||
"node_modules/ts-api-utils": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz",
|
||||
|
@ -4177,8 +4842,7 @@
|
|||
"node_modules/undici-types": {
|
||||
"version": "5.25.3",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz",
|
||||
"integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA=="
|
||||
},
|
||||
"node_modules/update-browserslist-db": {
|
||||
"version": "1.0.13",
|
||||
|
@ -4237,6 +4901,20 @@
|
|||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||
},
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
|
@ -4328,12 +5006,88 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/wrap-ansi": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz",
|
||||
"integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^6.2.1",
|
||||
"string-width": "^7.0.0",
|
||||
"strip-ansi": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/wrap-ansi/node_modules/ansi-regex": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
|
||||
"integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/wrap-ansi/node_modules/ansi-styles": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
|
||||
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/wrap-ansi/node_modules/strip-ansi": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
|
||||
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-regex": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.16.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz",
|
||||
"integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": ">=5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bufferutil": {
|
||||
"optional": true
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
|
@ -4341,9 +5095,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/yaml": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.3.tgz",
|
||||
"integrity": "sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==",
|
||||
"version": "2.3.4",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz",
|
||||
"integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
|
|
|
@ -6,10 +6,13 @@
|
|||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "next lint"
|
||||
"lint": "next lint",
|
||||
"prettier": "prettier --write \"**/*.{js,jsx,ts,tsx,json,css,scss,md}\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@heroicons/react": "^2.1.1",
|
||||
"@supabase/ssr": "^0.3.0",
|
||||
"@supabase/supabase-js": "^2.42.3",
|
||||
"next": "13.5.6",
|
||||
"react": "^18",
|
||||
"react-dom": "^18"
|
||||
|
@ -21,8 +24,20 @@
|
|||
"autoprefixer": "^10",
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "13.5.6",
|
||||
"husky": "^9.0.11",
|
||||
"lint-staged": "^15.2.2",
|
||||
"postcss": "^8",
|
||||
"tailwindcss": "^3",
|
||||
"typescript": "^5"
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "lint-staged"
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{js,jsx,ts,tsx,json,css,scss,md}": [
|
||||
"prettier --write"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,4 +3,4 @@ module.exports = {
|
|||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
/* globals.css */
|
||||
@import 'tailwindcss/base';
|
||||
@import 'tailwindcss/components';
|
||||
@import 'tailwindcss/utilities';
|
||||
|
||||
@import "tailwindcss/base";
|
||||
@import "tailwindcss/components";
|
||||
@import "tailwindcss/utilities";
|
||||
|
||||
:root {
|
||||
/* Colors */
|
||||
|
@ -11,7 +10,8 @@
|
|||
--ring-opacity: 0.5;
|
||||
|
||||
/* Shadows */
|
||||
--shadow-default: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
||||
--shadow-default: 0 1px 3px 0 rgba(0, 0, 0, 0.1),
|
||||
0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
||||
--shadow-focus: 0 0 0 3px rgba(66, 153, 225, 0.5);
|
||||
|
||||
/* Borders */
|
||||
|
@ -31,66 +31,65 @@
|
|||
/* A shade of gray */
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url('/fonts/Inter-Regular.ttf') format('truetype');
|
||||
src: url("/fonts/Inter-Regular.ttf") format("truetype");
|
||||
}
|
||||
|
||||
/* Inter-Bold */
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: url('/fonts/Inter-Bold.ttf') format('truetype');
|
||||
src: url("/fonts/Inter-Bold.ttf") format("truetype");
|
||||
}
|
||||
|
||||
/* Inter-Black */
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 900;
|
||||
src: url('/fonts/Inter-Black.ttf') format('truetype');
|
||||
src: url("/fonts/Inter-Black.ttf") format("truetype");
|
||||
}
|
||||
|
||||
/* Inter-ExtraBold */
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 800;
|
||||
src: url('/fonts/Inter-ExtraBold.ttf') format('truetype');
|
||||
src: url("/fonts/Inter-ExtraBold.ttf") format("truetype");
|
||||
}
|
||||
|
||||
/* Inter-ExtraLight */
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 200;
|
||||
src: url('/fonts/Inter-ExtraLight.ttf') format('truetype');
|
||||
src: url("/fonts/Inter-ExtraLight.ttf") format("truetype");
|
||||
}
|
||||
|
||||
/* Inter-Medium */
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: url('/fonts/Inter-Medium.ttf') format('truetype');
|
||||
src: url("/fonts/Inter-Medium.ttf") format("truetype");
|
||||
}
|
||||
|
||||
/* Inter-SemiBold */
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
src: url('/fonts/Inter-SemiBold.ttf') format('truetype');
|
||||
src: url("/fonts/Inter-SemiBold.ttf") format("truetype");
|
||||
}
|
||||
|
||||
/* Inter-Thin */
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 100;
|
||||
src: url('/fonts/Inter-Thin.ttf') format('truetype');
|
||||
src: url("/fonts/Inter-Thin.ttf") format("truetype");
|
||||
}
|
|
@ -1,23 +1,24 @@
|
|||
import type { Config } from 'tailwindcss';
|
||||
import type { Config } from "tailwindcss";
|
||||
|
||||
const config: Config = {
|
||||
content: [
|
||||
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
'./components/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
'./app/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"./components/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"./app/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
backgroundImage: {
|
||||
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
|
||||
'gradient-conic': 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
|
||||
"gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
|
||||
"gradient-conic":
|
||||
"conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
|
||||
},
|
||||
fontFamily: {
|
||||
'sans': ['Inter', 'sans-serif'], // Add 'Inter' to the fontFamily theme
|
||||
sans: ["Inter", "sans-serif"], // Add 'Inter' to the fontFamily theme
|
||||
},
|
||||
fontWeight: {
|
||||
'medium': 500, // Ensure medium is correctly set to 500
|
||||
}
|
||||
medium: 500, // Ensure medium is correctly set to 500
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
|
|
|
@ -9,8 +9,7 @@ class CollectionImpl {
|
|||
}
|
||||
|
||||
// subject to change
|
||||
setData(data: any){
|
||||
setData(data: any) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
}
|
|
@ -7,7 +7,7 @@ export class Field {
|
|||
constructor(iconKey: keyof typeof Icons, title: string) {
|
||||
this.iconKey = iconKey;
|
||||
this.title = title;
|
||||
}
|
||||
}
|
||||
|
||||
validateInput(value: any): boolean {
|
||||
return value !== null;
|
||||
|
|
|
@ -1,4 +1,23 @@
|
|||
import { ListBulletIcon, HashtagIcon, Bars3BottomLeftIcon, EnvelopeIcon, AtSymbolIcon, ClipboardIcon, ArrowsUpDownIcon, ChevronDoubleRightIcon, ChevronDoubleLeftIcon, ChevronRightIcon, ChevronLeftIcon, EyeIcon, EyeSlashIcon, UserIcon, BookOpenIcon, MagnifyingGlassIcon, LinkIcon, ClipboardDocumentCheckIcon } from '@heroicons/react/24/solid';
|
||||
import {
|
||||
ListBulletIcon,
|
||||
HashtagIcon,
|
||||
Bars3BottomLeftIcon,
|
||||
EnvelopeIcon,
|
||||
AtSymbolIcon,
|
||||
ClipboardIcon,
|
||||
ArrowsUpDownIcon,
|
||||
ChevronDoubleRightIcon,
|
||||
ChevronDoubleLeftIcon,
|
||||
ChevronRightIcon,
|
||||
ChevronLeftIcon,
|
||||
EyeIcon,
|
||||
EyeSlashIcon,
|
||||
UserIcon,
|
||||
BookOpenIcon,
|
||||
MagnifyingGlassIcon,
|
||||
LinkIcon,
|
||||
ClipboardDocumentCheckIcon,
|
||||
} from "@heroicons/react/24/solid";
|
||||
|
||||
export const Icons = {
|
||||
EmailInputIcon: EnvelopeIcon,
|
||||
|
@ -10,40 +29,40 @@ export const Icons = {
|
|||
ServiceIcon: ClipboardIcon,
|
||||
CloseRightArrow: ChevronDoubleRightIcon,
|
||||
CloseLeftArrow: ChevronDoubleLeftIcon,
|
||||
LinkRightArrow:ChevronRightIcon,
|
||||
LinkLeftArrow:ChevronLeftIcon,
|
||||
LinkRightArrow: ChevronRightIcon,
|
||||
LinkLeftArrow: ChevronLeftIcon,
|
||||
SortIcon: ArrowsUpDownIcon,
|
||||
EmailTableIcon:AtSymbolIcon,
|
||||
EmailTableIcon: AtSymbolIcon,
|
||||
LinkTableIcon: LinkIcon,
|
||||
TextTableIcon: Bars3BottomLeftIcon,
|
||||
NumberTableIcon: HashtagIcon,
|
||||
MultiselectTableIcon: ListBulletIcon,
|
||||
RequirementsTableIcon: ClipboardDocumentCheckIcon
|
||||
RequirementsTableIcon: ClipboardDocumentCheckIcon,
|
||||
};
|
||||
|
||||
export enum USER {
|
||||
ADMIN,
|
||||
EMPLOYEE,
|
||||
VOLUNTEER
|
||||
VOLUNTEER,
|
||||
}
|
||||
|
||||
export enum COLLECTION {
|
||||
RESOURCE,
|
||||
SERVICE,
|
||||
USER,
|
||||
TRAINING_MANUAL
|
||||
TRAINING_MANUAL,
|
||||
}
|
||||
|
||||
export enum PROGRAM {
|
||||
DOMESTIC_VIOLENCE,
|
||||
ECONOMIC_STABILITY,
|
||||
COMMUNITY_EDUCATION
|
||||
COMMUNITY_EDUCATION,
|
||||
}
|
||||
|
||||
export enum STATUS {
|
||||
FULL,
|
||||
CLOSED,
|
||||
ACCEPTING_CLIENTS
|
||||
ACCEPTING_CLIENTS,
|
||||
}
|
||||
|
||||
export enum DATATYPE {
|
||||
|
@ -52,7 +71,5 @@ export enum DATATYPE {
|
|||
LINK,
|
||||
EMAIL,
|
||||
MULTISELECT,
|
||||
SELECT
|
||||
SELECT,
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -4,15 +4,18 @@ const serviceEntries = [
|
|||
{
|
||||
name: "Empowerment Workshops",
|
||||
status: [STATUS.ACCEPTING_CLIENTS],
|
||||
summary: "Workshops to empower victims through education and skill-building.",
|
||||
requirements: "Resident of the community and victim of domestic violence.",
|
||||
summary:
|
||||
"Workshops to empower victims through education and skill-building.",
|
||||
requirements:
|
||||
"Resident of the community and victim of domestic violence.",
|
||||
program: [PROGRAM.DOMESTIC_VIOLENCE, PROGRAM.COMMUNITY_EDUCATION],
|
||||
tags: ["empowerment", "education"],
|
||||
},
|
||||
{
|
||||
name: "Financial Literacy Courses",
|
||||
status: [STATUS.ACCEPTING_CLIENTS, STATUS.FULL],
|
||||
summary: "Courses aimed at improving financial independence for victims.",
|
||||
summary:
|
||||
"Courses aimed at improving financial independence for victims.",
|
||||
requirements: "Open to all domestic violence victims.",
|
||||
program: [PROGRAM.ECONOMIC_STABILITY],
|
||||
tags: ["finance", "literacy"],
|
||||
|
@ -20,7 +23,8 @@ const serviceEntries = [
|
|||
{
|
||||
name: "Counseling Services",
|
||||
status: [STATUS.ACCEPTING_CLIENTS],
|
||||
summary: "Professional counseling for individuals and families affected by domestic violence.",
|
||||
summary:
|
||||
"Professional counseling for individuals and families affected by domestic violence.",
|
||||
requirements: "Appointment required.",
|
||||
program: [PROGRAM.DOMESTIC_VIOLENCE],
|
||||
tags: ["counseling", "mental health"],
|
||||
|
@ -36,12 +40,13 @@ const serviceEntries = [
|
|||
{
|
||||
name: "Legal Advocacy",
|
||||
status: [STATUS.FULL],
|
||||
summary: "Legal advice and representation for victims of domestic violence.",
|
||||
summary:
|
||||
"Legal advice and representation for victims of domestic violence.",
|
||||
requirements: "Legal documentation of domestic violence required.",
|
||||
program: [PROGRAM.DOMESTIC_VIOLENCE],
|
||||
tags: ["legal", "advocacy"],
|
||||
}
|
||||
];
|
||||
},
|
||||
];
|
||||
|
||||
const resourceEntries = [
|
||||
{
|
||||
|
@ -60,7 +65,8 @@ const resourceEntries = [
|
|||
},
|
||||
{
|
||||
name: "Support Group Finder",
|
||||
summary: "Find local support groups for survivors of domestic violence.",
|
||||
summary:
|
||||
"Find local support groups for survivors of domestic violence.",
|
||||
link: "https://supportgroups.example.com",
|
||||
program: [PROGRAM.COMMUNITY_EDUCATION],
|
||||
tags: ["support", "community"],
|
||||
|
@ -78,8 +84,8 @@ const resourceEntries = [
|
|||
link: "https://workshops.example.com",
|
||||
program: [PROGRAM.COMMUNITY_EDUCATION],
|
||||
tags: ["education", "workshops"],
|
||||
}
|
||||
];
|
||||
},
|
||||
];
|
||||
|
||||
const userEntries = [
|
||||
{
|
||||
|
@ -121,17 +127,17 @@ const userEntries = [
|
|||
program: [PROGRAM.DOMESTIC_VIOLENCE],
|
||||
experience: 4,
|
||||
group: "Counseling Services Team",
|
||||
}
|
||||
];
|
||||
},
|
||||
];
|
||||
|
||||
export const mockFetchServices = () => {
|
||||
return serviceEntries;
|
||||
}
|
||||
};
|
||||
|
||||
export const mockFetchResources = () => {
|
||||
return resourceEntries;
|
||||
}
|
||||
};
|
||||
|
||||
export const mockFetchUsers = () => {
|
||||
return userEntries;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -15,7 +15,9 @@ export class CollectionDataImpl {
|
|||
for (const header of this.headers) {
|
||||
const value = row[header.title];
|
||||
if (!header.validateInput(value)) {
|
||||
console.error(`Validation failed for ${header.title} with value ${value}`);
|
||||
console.error(
|
||||
`Validation failed for ${header.title} with value ${value}`
|
||||
);
|
||||
isValidRow = false;
|
||||
break;
|
||||
}
|
||||
|
@ -24,7 +26,7 @@ export class CollectionDataImpl {
|
|||
if (isValidRow) {
|
||||
this.rows.push(row);
|
||||
} else {
|
||||
console.log('Row not added due to validation failure.');
|
||||
console.log("Row not added due to validation failure.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,5 +37,4 @@ export class CollectionDataImpl {
|
|||
getHeaders(): Field[] {
|
||||
return this.headers;
|
||||
}
|
||||
|
||||
}
|
|
@ -10,6 +10,4 @@ export class CollectionImpl {
|
|||
this.icon = icon;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,18 +1,15 @@
|
|||
import { Field } from "@/utils/classes/Field";
|
||||
|
||||
|
||||
export class EmailFieldImpl extends Field {
|
||||
|
||||
constructor() {
|
||||
super('EmailTableIcon', "Email");
|
||||
super("EmailTableIcon", "Email");
|
||||
}
|
||||
|
||||
validateInput(value: any) : boolean {
|
||||
if (typeof value !== 'string') {
|
||||
validateInput(value: any): boolean {
|
||||
if (typeof value !== "string") {
|
||||
return false;
|
||||
}
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
return emailRegex.test(value);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,15 +1,12 @@
|
|||
import { Icons } from "@/utils/constants";
|
||||
import { Field } from "@/utils/classes/Field";
|
||||
|
||||
|
||||
export class IntegerFieldImpl extends Field {
|
||||
|
||||
constructor(title: string) {
|
||||
super('NumberTableIcon', title);
|
||||
super("NumberTableIcon", title);
|
||||
}
|
||||
|
||||
validateInput(value: any) : boolean {
|
||||
validateInput(value: any): boolean {
|
||||
return Number.isInteger(value);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,18 +1,16 @@
|
|||
import { Field } from "@/utils/classes/Field";
|
||||
|
||||
|
||||
export class LinkFieldImpl extends Field {
|
||||
|
||||
constructor() {
|
||||
super('LinkTableIcon', "Link");
|
||||
super("LinkTableIcon", "Link");
|
||||
}
|
||||
|
||||
validateInput(value: any) : boolean {
|
||||
if (typeof value !== 'string') {
|
||||
validateInput(value: any): boolean {
|
||||
if (typeof value !== "string") {
|
||||
return false;
|
||||
}
|
||||
const urlRegex = /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/;
|
||||
const urlRegex =
|
||||
/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/;
|
||||
return urlRegex.test(value);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,19 +1,17 @@
|
|||
import { Field } from "@/utils/classes/Field";
|
||||
|
||||
|
||||
export class MultiselectFieldImpl extends Field {
|
||||
|
||||
tags: Set<any>;
|
||||
selectedTags: Set<any>;
|
||||
|
||||
constructor(title: string, tags: Set<any> = new Set()) {
|
||||
super('MultiselectTableIcon', title);
|
||||
this.tags = tags
|
||||
super("MultiselectTableIcon", title);
|
||||
this.tags = tags;
|
||||
this.selectedTags = new Set();
|
||||
}
|
||||
|
||||
getTags() {
|
||||
return this.tags
|
||||
return this.tags;
|
||||
}
|
||||
|
||||
addTag(tag: any) {
|
||||
|
@ -21,7 +19,7 @@ export class MultiselectFieldImpl extends Field {
|
|||
}
|
||||
|
||||
removeTag(tag: any) {
|
||||
if (this.tags.has(tag)){
|
||||
if (this.tags.has(tag)) {
|
||||
this.tags.delete(tag);
|
||||
}
|
||||
}
|
||||
|
@ -31,9 +29,8 @@ export class MultiselectFieldImpl extends Field {
|
|||
}
|
||||
|
||||
removeSelectedTag(tag: any) {
|
||||
if (this.selectedTags.has(tag)){
|
||||
if (this.selectedTags.has(tag)) {
|
||||
this.selectedTags.delete(tag);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,15 +1,12 @@
|
|||
import { Icons } from "@/utils/constants";
|
||||
import { Field } from "@/utils/classes/Field";
|
||||
|
||||
|
||||
export class StringFieldImpl extends Field {
|
||||
|
||||
constructor(title: string, iconKey: keyof typeof Icons = "TextTableIcon") {
|
||||
super(iconKey, title);
|
||||
}
|
||||
|
||||
validateInput(value: any) : boolean {
|
||||
return typeof value === 'string';
|
||||
validateInput(value: any): boolean {
|
||||
return typeof value === "string";
|
||||
}
|
||||
|
||||
}
|
|
@ -1,15 +1,43 @@
|
|||
import { mockFetchResources, mockFetchServices, mockFetchUsers } from "../functions/mockFetch";
|
||||
import {
|
||||
mockFetchResources,
|
||||
mockFetchServices,
|
||||
mockFetchUsers,
|
||||
} from "../functions/mockFetch";
|
||||
import { CollectionDataImpl } from "../implementations/CollectionDataImpl";
|
||||
import { CollectionImpl } from "../implementations/CollectionImpl";
|
||||
import { ResourceCollectionDataType, ServiceCollectionDataType, UserCollectionDataType } from "./CollectionDataType";
|
||||
import {
|
||||
ResourceCollectionDataType,
|
||||
ServiceCollectionDataType,
|
||||
UserCollectionDataType,
|
||||
} from "./CollectionDataType";
|
||||
|
||||
const ServiceCollectionData = new CollectionDataImpl(ServiceCollectionDataType, mockFetchServices());
|
||||
const ResourceCollectionData = new CollectionDataImpl(ResourceCollectionDataType, mockFetchResources());
|
||||
const UserCollectionData = new CollectionDataImpl(UserCollectionDataType, mockFetchUsers());
|
||||
const ServiceCollectionData = new CollectionDataImpl(
|
||||
ServiceCollectionDataType,
|
||||
mockFetchServices()
|
||||
);
|
||||
const ResourceCollectionData = new CollectionDataImpl(
|
||||
ResourceCollectionDataType,
|
||||
mockFetchResources()
|
||||
);
|
||||
const UserCollectionData = new CollectionDataImpl(
|
||||
UserCollectionDataType,
|
||||
mockFetchUsers()
|
||||
);
|
||||
|
||||
export const ServiceCollection = new CollectionImpl('Service','ServiceIcon',new CollectionDataImpl(ServiceCollectionDataType))
|
||||
export const ServiceCollection = new CollectionImpl(
|
||||
"Service",
|
||||
"ServiceIcon",
|
||||
new CollectionDataImpl(ServiceCollectionDataType)
|
||||
);
|
||||
|
||||
export const ResourceCollection = new CollectionImpl('Resource','ResourceIcon',new CollectionDataImpl(ResourceCollectionDataType))
|
||||
|
||||
export const UserCollection = new CollectionImpl('User','UserIcon',new CollectionDataImpl(UserCollectionDataType))
|
||||
export const ResourceCollection = new CollectionImpl(
|
||||
"Resource",
|
||||
"ResourceIcon",
|
||||
new CollectionDataImpl(ResourceCollectionDataType)
|
||||
);
|
||||
|
||||
export const UserCollection = new CollectionImpl(
|
||||
"User",
|
||||
"UserIcon",
|
||||
new CollectionDataImpl(UserCollectionDataType)
|
||||
);
|
||||
|
|
|
@ -6,21 +6,52 @@ import { LinkFieldImpl } from "../implementations/FieldImpl/LinkFieldImpl";
|
|||
import { MultiselectFieldImpl } from "../implementations/FieldImpl/MultiselectFieldImpl";
|
||||
import { StringFieldImpl } from "../implementations/FieldImpl/StringFieldImpl";
|
||||
|
||||
const programSet: Set<PROGRAM> = new Set([PROGRAM.COMMUNITY_EDUCATION, PROGRAM.DOMESTIC_VIOLENCE, PROGRAM.ECONOMIC_STABILITY]);
|
||||
const programSet: Set<PROGRAM> = new Set([
|
||||
PROGRAM.COMMUNITY_EDUCATION,
|
||||
PROGRAM.DOMESTIC_VIOLENCE,
|
||||
PROGRAM.ECONOMIC_STABILITY,
|
||||
]);
|
||||
const program = new MultiselectFieldImpl("program", programSet);
|
||||
const requirements = new StringFieldImpl("requirements","RequirementsTableIcon");
|
||||
const requirements = new StringFieldImpl(
|
||||
"requirements",
|
||||
"RequirementsTableIcon"
|
||||
);
|
||||
const name = new StringFieldImpl("name");
|
||||
const summary = new StringFieldImpl("summary");
|
||||
const statusSet: Set<STATUS> = new Set([STATUS.ACCEPTING_CLIENTS, STATUS.CLOSED, STATUS.FULL])
|
||||
const statusSet: Set<STATUS> = new Set([
|
||||
STATUS.ACCEPTING_CLIENTS,
|
||||
STATUS.CLOSED,
|
||||
STATUS.FULL,
|
||||
]);
|
||||
const status = new MultiselectFieldImpl("status", statusSet);
|
||||
const link = new LinkFieldImpl()
|
||||
const tags = new MultiselectFieldImpl("tags")
|
||||
const link = new LinkFieldImpl();
|
||||
const tags = new MultiselectFieldImpl("tags");
|
||||
const roleSet: Set<USER> = new Set([USER.ADMIN, USER.EMPLOYEE, USER.VOLUNTEER]);
|
||||
const role = new MultiselectFieldImpl("role", roleSet)
|
||||
const experience = new IntegerFieldImpl("yoe")
|
||||
const email = new EmailFieldImpl()
|
||||
const group = new StringFieldImpl("group")
|
||||
const role = new MultiselectFieldImpl("role", roleSet);
|
||||
const experience = new IntegerFieldImpl("yoe");
|
||||
const email = new EmailFieldImpl();
|
||||
const group = new StringFieldImpl("group");
|
||||
|
||||
export const ServiceCollectionDataType: Field[] = [name, status, summary, requirements, program, tags]
|
||||
export const ResourceCollectionDataType: Field[] = [name, summary, link, program, tags]
|
||||
export const UserCollectionDataType: Field[] = [name, role, email, program, experience, group]
|
||||
export const ServiceCollectionDataType: Field[] = [
|
||||
name,
|
||||
status,
|
||||
summary,
|
||||
requirements,
|
||||
program,
|
||||
tags,
|
||||
];
|
||||
export const ResourceCollectionDataType: Field[] = [
|
||||
name,
|
||||
summary,
|
||||
link,
|
||||
program,
|
||||
tags,
|
||||
];
|
||||
export const UserCollectionDataType: Field[] = [
|
||||
name,
|
||||
role,
|
||||
email,
|
||||
program,
|
||||
experience,
|
||||
group,
|
||||
];
|
||||
|
|
Loading…
Reference in New Issue
Block a user