From b01e211acb71033fec1fc75946e6051931c47804 Mon Sep 17 00:00:00 2001 From: SrJuggernaut Date: Fri, 6 Oct 2023 12:27:28 -0600 Subject: [PATCH] feat: static unirse --- .env.example | 17 +- package.json | 2 + src/app/Team.tsx | 56 +++--- src/app/equipo/page.tsx | 4 +- src/app/equipo/unirse/ApplyForm.tsx | 286 +++++++++++++++++++++++++++ src/app/equipo/unirse/page.tsx | 18 +- src/app/page.tsx | 10 +- src/components/layout/Menu.tsx | 8 +- src/components/ui/Button.tsx | 22 +++ src/components/ui/IconButton.tsx | 22 +++ src/components/ui/form/FormGroup.tsx | 23 +++ src/components/ui/form/Input.tsx | 17 ++ src/lib/appwrite.ts | 9 + src/lib/nodeAppwrite.ts | 12 ++ src/services/backend/database.ts | 18 ++ src/services/backend/roles.ts | 35 ++++ src/services/backend/teamApply.ts | 32 +++ src/services/frontend/database.ts | 2 + src/services/frontend/teamApply.ts | 25 +++ src/types/User.ts | 2 + src/types/teamApply.ts | 13 ++ yarn.lock | 143 ++++++++++++++ 22 files changed, 722 insertions(+), 54 deletions(-) create mode 100644 src/app/equipo/unirse/ApplyForm.tsx create mode 100644 src/components/ui/Button.tsx create mode 100644 src/components/ui/IconButton.tsx create mode 100644 src/components/ui/form/FormGroup.tsx create mode 100644 src/components/ui/form/Input.tsx create mode 100644 src/lib/appwrite.ts create mode 100644 src/lib/nodeAppwrite.ts create mode 100644 src/services/backend/database.ts create mode 100644 src/services/backend/roles.ts create mode 100644 src/services/backend/teamApply.ts create mode 100644 src/services/frontend/database.ts create mode 100644 src/services/frontend/teamApply.ts create mode 100644 src/types/teamApply.ts diff --git a/.env.example b/.env.example index 32612d6..f306c51 100644 --- a/.env.example +++ b/.env.example @@ -1,7 +1,6 @@ # App variables SITE_NAME="EntGamers" -DISCORD_JOIN_WEBHOOK_URL="https://discord.com/api/webhooks/XXXXXXXXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" # Deployment variables @@ -14,4 +13,18 @@ DEPLOY_PATH="" # Github actions variables SSH_PRIVATE_KEY="" -SSH_KNOWN_HOSTS="" \ No newline at end of file +SSH_KNOWN_HOSTS="" + +# Appwrite required variables + +NEXT_PUBLIC_APPWRITE_ENDPOINT="" +NEXT_PUBLIC_APPWRITE_PROJECT_ID="" +APPWRITE_API_KEY="" + +# Appwrite optional variables + +NEXT_PUBLIC_APPWRITE_DATABASE_ID="" +NEXT_PUBLIC_APPWRITE_COLLECTION_ID="" +NEXT_PUBLIC_APPWRITE_ADMIN_TEAM_ID="" +NEXT_PUBLIC_APPWRITE_ADMIN_MODERATOR_TEAM_ID="" +NEXT_PUBLIC_APPWRITE_ADMIN_COLLABORATOR_TEAM_ID="" \ No newline at end of file diff --git a/package.json b/package.json index d93d3fc..2cdd481 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@fortawesome/free-brands-svg-icons": "^6.4.2", "@fortawesome/free-solid-svg-icons": "^6.4.2", "@fortawesome/react-fontawesome": "^0.2.0", + "appwrite": "^13.0.0", "entgamers-panda-preset": "0.0.7", "formik": "^2.4.4", "framer-motion": "^10.16.4", @@ -24,6 +25,7 @@ "isomorphic-fetch": "^3.0.0", "next": "13.4.19", "next-connect": "^1.0.0", + "node-appwrite": "^11.0.0", "react": "18.2.0", "react-dom": "18.2.0", "sharp": "^0.32.5", diff --git a/src/app/Team.tsx b/src/app/Team.tsx index 3017974..6c92e26 100644 --- a/src/app/Team.tsx +++ b/src/app/Team.tsx @@ -30,16 +30,14 @@ const team: TeamMember[] = [ const Team: FC = () => { return (
-
- +
{
))} - - -
- +
- Ver el equipo completo - - - Únete al equipo - -
+ + Ver el equipo completo + + + Únete al equipo + +
+
) } diff --git a/src/app/equipo/page.tsx b/src/app/equipo/page.tsx index 5434fc2..c099efb 100644 --- a/src/app/equipo/page.tsx +++ b/src/app/equipo/page.tsx @@ -103,7 +103,7 @@ const EquipoPage: FC = () => {
¡Quiero ser moderador! @@ -119,7 +119,7 @@ const EquipoPage: FC = () => {
¡Quiero ser colaborador! diff --git a/src/app/equipo/unirse/ApplyForm.tsx b/src/app/equipo/unirse/ApplyForm.tsx new file mode 100644 index 0000000..13c03b2 --- /dev/null +++ b/src/app/equipo/unirse/ApplyForm.tsx @@ -0,0 +1,286 @@ +'use client' +import Button from '@/components/ui/Button' +import Typography from '@/components/ui/Typography' +import FormGroup from '@/components/ui/form/FormGroup' +import Input from '@/components/ui/form/Input' +import { css } from '@/styled-system/css' +import { type TeamApplyData } from '@/types/teamApply' +import { faChevronRight } from '@fortawesome/free-solid-svg-icons' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { useFormik } from 'formik' +import { AnimatePresence, motion } from 'framer-motion' +import { useSearchParams } from 'next/navigation' +import { useEffect, type FC } from 'react' + +const ApplyForm: FC = () => { + const searchParams = useSearchParams() + + const formik = useFormik({ + initialValues: { + name: '', + email: '', + discordName: '', + message: '', + role: 'administrator' + }, + onSubmit: (values) => { + console.log(values) + } + }) + useEffect(() => { + if (searchParams.has('role')) { + formik.setFieldValue('role', searchParams.get('role')) + .catch((error) => { + console.error(error) + }) + } + }, []) + + return ( +
+
+ + + +
+
+
+ + + + {formik.touched.name !== undefined && formik.errors.name !== undefined && ( + + {formik.errors.name} + + )} + + + + + {formik.touched.email !== undefined && formik.errors.email !== undefined && ( + + {formik.errors.email} + + )} + + + + + {formik.touched.discordName !== undefined && formik.errors.discordName !== undefined && ( + + {formik.errors.discordName} + + )} + + + + + {formik.touched.message !== undefined && formik.errors.message !== undefined && ( + + {formik.errors.message} + + )} + + +
+
+ + {formik.values.role === 'moderator' && ( + + Moderadores + + El equipo de moderación de EntGamers se encarga de moderar los distintos espacios en los que se desenvuelve la comunidad, como los grupos de Facebook, Discord, Etc. + + Requisitos +
    +
  • + Imparcialidad +
    + La comunidad esta conformada por amigos y conocidos, por lo tanto es importante poder actuar de forma imparcial y responsable. +
  • +
+ Beneficios +
    +
  • + Experiencia +
    + Uno de los objetivos de la comunidad es brindar experiencia en gestión y desarrollo de proyectos equiparable a un entorno laboral, que sea comprobable y útil. +
  • +
+
+ )} + {formik.values.role === 'collaborator' && ( + + Colaborador + + Los colaboradores son personas ajenas al staff central de EntGamers que nos ayudan a traer contenido, eventos y actividades a la comunidad. + + Requisitos +
    +
  • + Profesionalismo +
    + La comunidad siempre intenta conseguir el mayor nivel de calidad en todos sus proyectos, por lo que buscamos gente dispuesta a otorgar este nivel de profesionalismo para el disfrute de la comunidad. +
  • +
+ Beneficios +
    +
  • + Apoyo +
    + Puedes contar con el apoyo de la comunidad para tus proyectos, ya sea en forma de difusión, asesoramiento o recursos. +
  • +
+
+ )} + {formik.values.role === 'administrator' && ( + + Administradores + + Los administradores son quienes se encargan de que todo funcione como es debido en la comunidad, desde la moderación de los grupos hasta la organización de eventos y actividades. Son los responsables de que la comunidad siga creciendo y mejorando. + + Requisitos +
    +
  • + Profesionalismo +
    + La comunidad siempre intenta conseguir el mayor nivel de calidad en todos sus proyectos, por lo que buscamos gente dispuesta a otorgar este nivel de profesionalismo para el disfrute de la comunidad. +
  • +
  • + Constancia +
    + La comunidad busca gente que en sus posibilidades sea activa, que pueda estar al tanto de lo que pasa en ella. +
  • +
  • + Proactividad +
    + La comunidad esta en constante crecimiento, por eso, buscamos gente que ayude a buscar nuevas oportunidades para diferentes proyectos y actividades de interés a la comunidad. +
  • +
+ Beneficios +
    +
  • + Experiencia +
    + Uno de los objetivos de la comunidad es brindar experiencia en gestión y desarrollo de proyectos equiparable a un entorno laboral, que sea comprobable y útil. +
  • +
  • + Capacitación +
    + La comunidad buscara dar capacitación a sus miembros en lo referido a herramientas y procedimientos utilizados. +
  • +
  • +
+
+ )} +
+
+
+
+ ) +} +export default ApplyForm diff --git a/src/app/equipo/unirse/page.tsx b/src/app/equipo/unirse/page.tsx index 7d78e31..72a139a 100644 --- a/src/app/equipo/unirse/page.tsx +++ b/src/app/equipo/unirse/page.tsx @@ -1,7 +1,7 @@ import Typography from '@/components/ui/Typography' -import { css } from '@/styled-system/css' import { Container } from '@/styled-system/jsx' import { type FC } from 'react' +import ApplyForm from './ApplyForm' const EquipoUnirsePage: FC = () => { return ( @@ -10,21 +10,7 @@ const EquipoUnirsePage: FC = () => { El equipo de EntGamers está formado por personas que se dedican a la administración de la comunidad, a la organización de eventos y a la creación de contenido. Aquí podrás enterarte cuales son las funciones de cada uno de los miembros del equipo y como puedes unirte a nosotros. -
- Esta sección está en construcción. Puedes unirte contactándonos mediante nuestro Servidor de Discord. -
+ ) } diff --git a/src/app/page.tsx b/src/app/page.tsx index 68e5567..bdfc79d 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -2,9 +2,17 @@ import Clanes from '@/app/Clanes' import Hero from '@/app/Hero' import Social from '@/app/Social' import Team from '@/app/Team' +import { ensureRoles } from '@/services/backend/roles' +import { ensureTeamApplyCollection } from '@/services/backend/teamApply' import { type FC } from 'react' -const HomePage: FC = () => { +const ensureAll = async (): Promise => { + await ensureRoles() + await ensureTeamApplyCollection() +} + +const HomePage: FC = async () => { + await ensureAll() return ( <> diff --git a/src/components/layout/Menu.tsx b/src/components/layout/Menu.tsx index b5de733..a9f2130 100644 --- a/src/components/layout/Menu.tsx +++ b/src/components/layout/Menu.tsx @@ -1,5 +1,6 @@ import trees from '@/assets/icons/trees' import BackDrop from '@/components/ui/BackDrop' +import IconButton from '@/components/ui/IconButton' import { css } from '@/styled-system/css' import { iconButton } from '@/styled-system/recipes' import { type IconDefinition } from '@fortawesome/fontawesome-common-types' @@ -29,14 +30,11 @@ const Menu: FC = () => { }, []) return ( <> - + , HTMLButtonElement>, ButtonVariantProps> + +export interface ButtonProps extends ComposedButtonProps {} + +const Button: FC = ({ children, className, ...rest }) => { + const [buttonRecipeArgs, allOtherButtonProps] = button.splitVariantProps(rest) + return ( + + ) +} + +export default Button diff --git a/src/components/ui/IconButton.tsx b/src/components/ui/IconButton.tsx new file mode 100644 index 0000000..25423ec --- /dev/null +++ b/src/components/ui/IconButton.tsx @@ -0,0 +1,22 @@ +import { cx } from '@/styled-system/css' +import { iconButton, type IconButtonVariantProps } from '@/styled-system/recipes/icon-button' +import { type MergeOmitting } from '@/types/utilities' +import React, { type FC } from 'react' + +type ComposedIconButtonProps = MergeOmitting, IconButtonVariantProps> + +export interface IconButtonProps extends ComposedIconButtonProps {} + +const IconButton: FC = ({ children, className, ...rest }) => { + const [iconButtonRecipeArgs, allOtherIconButtonProps] = iconButton.splitVariantProps(rest) + return ( + + ) +} + +export default IconButton diff --git a/src/components/ui/form/FormGroup.tsx b/src/components/ui/form/FormGroup.tsx new file mode 100644 index 0000000..72fc16e --- /dev/null +++ b/src/components/ui/form/FormGroup.tsx @@ -0,0 +1,23 @@ +import { css, cx } from '@/styled-system/css' +import { type DetailedHTMLProps, type FC, type HTMLAttributes, type ReactNode } from 'react' + +export interface FormGroupProps extends DetailedHTMLProps, HTMLDivElement> { + children: ReactNode +} + +const FormGroup: FC = ({ children, className, ...props }) => { + return ( +
+ {children} +
+ ) +} +export default FormGroup diff --git a/src/components/ui/form/Input.tsx b/src/components/ui/form/Input.tsx new file mode 100644 index 0000000..e94561b --- /dev/null +++ b/src/components/ui/form/Input.tsx @@ -0,0 +1,17 @@ +import { cx } from '@/styled-system/css' +import { input, type InputVariantProps } from '@/styled-system/recipes/input' +import { type MergeOmitting } from '@/types/utilities' +import { type DetailedHTMLProps, type FC, type InputHTMLAttributes } from 'react' + +export type InputProps = MergeOmitting, HTMLInputElement>, InputVariantProps> + +const Input: FC = ({ className, ...props }) => { + const [inputCss, rest] = input.splitVariantProps(props) + return ( + + ) +} +export default Input diff --git a/src/lib/appwrite.ts b/src/lib/appwrite.ts new file mode 100644 index 0000000..8e7be23 --- /dev/null +++ b/src/lib/appwrite.ts @@ -0,0 +1,9 @@ +import { Client, Databases } from 'appwrite' + +export const appwriteClient = new Client() + .setEndpoint(process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT ?? '') + .setProject(process.env.NEXT_PUBLIC_APPWRITE_PROJECT ?? '') + +export const databases = new Databases(appwriteClient) + +export { ID } from 'appwrite' diff --git a/src/lib/nodeAppwrite.ts b/src/lib/nodeAppwrite.ts new file mode 100644 index 0000000..2d09cf0 --- /dev/null +++ b/src/lib/nodeAppwrite.ts @@ -0,0 +1,12 @@ +import { Client, Databases, Teams } from 'node-appwrite' + +export const clientNodeAppwrite = new Client() + .setEndpoint(process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT ?? '') + .setProject(process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID ?? '') + .setKey(process.env.APPWRITE_API_KEY ?? '') + +export const databases = new Databases(clientNodeAppwrite) + +export const teams = new Teams(clientNodeAppwrite) + +export { Permission, Role } from 'node-appwrite' diff --git a/src/services/backend/database.ts b/src/services/backend/database.ts new file mode 100644 index 0000000..63c627c --- /dev/null +++ b/src/services/backend/database.ts @@ -0,0 +1,18 @@ +import { databases } from '@/lib/nodeAppwrite' + +export const DATABASE_NAME = 'entgamers-website' +export const DATABASE_ID = process.env.NEXT_PUBLIC_APPWRITE_DATABASE_ID ?? DATABASE_NAME + +export const ensureDatabase = (() => { + let databaseEnsured = false + return async () => { + if (databaseEnsured) return + try { + await databases.get(DATABASE_ID) + } catch (error) { + await databases.create(DATABASE_ID, DATABASE_NAME) + } finally { + databaseEnsured = true + } + } +})() diff --git a/src/services/backend/roles.ts b/src/services/backend/roles.ts new file mode 100644 index 0000000..00f31ad --- /dev/null +++ b/src/services/backend/roles.ts @@ -0,0 +1,35 @@ +import { teams } from '@/lib/nodeAppwrite' +import { type UserPreferences } from '@/types/User' + +export const ADMIN_TEAM_NAME = 'admin' +export const ADMIN_TEAM_ID = process.env.NEXT_PUBLIC_APPWRITE_ADMIN_TEAM_ID ?? ADMIN_TEAM_NAME +export const MODERATOR_TEAM_NAME = 'moderator' +export const MODERATOR_TEAM_ID = process.env.NEXT_PUBLIC_APPWRITE_MODERATOR_TEAM_ID ?? MODERATOR_TEAM_NAME +export const COLLABORATOR_TEAM_NAME = 'collaborator' +export const COLLABORATOR_TEAM_ID = process.env.NEXT_PUBLIC_APPWRITE_COLLABORATOR_TEAM_ID ?? COLLABORATOR_TEAM_NAME + +const ensureRoleExists = (roleId: string, roleName: string): (() => Promise) => { + let roleExists = false + return async (): Promise => { + if (roleExists) return + try { + await teams.get(roleId) + roleExists = true + } catch (error) { + await teams.create(roleId, roleName) + roleExists = true + } + } +} + +export const ensureRoles = async (): Promise => { + const adminRole = ensureRoleExists(ADMIN_TEAM_ID, ADMIN_TEAM_NAME) + const moderatorRole = ensureRoleExists(MODERATOR_TEAM_ID, MODERATOR_TEAM_NAME) + const collaboratorRole = ensureRoleExists(COLLABORATOR_TEAM_ID, COLLABORATOR_TEAM_NAME) + + await Promise.all([ + adminRole(), + moderatorRole(), + collaboratorRole() + ]) +} diff --git a/src/services/backend/teamApply.ts b/src/services/backend/teamApply.ts new file mode 100644 index 0000000..bedfd68 --- /dev/null +++ b/src/services/backend/teamApply.ts @@ -0,0 +1,32 @@ +import { Permission, Role, databases } from '@/lib/nodeAppwrite' +import { DATABASE_ID, ensureDatabase } from '@/services/backend/database' +import { ADMIN_TEAM_ID } from './roles' + +export const TEAM_APPLY_COLLECTION_NAME = 'team-apply' +export const TEAM_APPLY_COLLECTION_ID = process.env.NEXT_PUBLIC_APPWRITE_TEAM_APPLY_COLLECTION_ID ?? TEAM_APPLY_COLLECTION_NAME + +export const ensureTeamApplyCollection = (() => { + let collectionEnsured = false + return async () => { + if (collectionEnsured) return + await ensureDatabase() + try { + await databases.getCollection(DATABASE_ID, TEAM_APPLY_COLLECTION_ID) + } catch (error) { + const permissions = [ + Permission.create(Role.any()), + Permission.read(Role.team(ADMIN_TEAM_ID)), + Permission.update(Role.team(ADMIN_TEAM_ID)), + Permission.delete(Role.team(ADMIN_TEAM_ID)) + ] + await databases.createCollection(DATABASE_ID, TEAM_APPLY_COLLECTION_ID, TEAM_APPLY_COLLECTION_NAME, permissions, false, true) + await databases.createStringAttribute(DATABASE_ID, TEAM_APPLY_COLLECTION_ID, 'name', 128, true) + await databases.createEmailAttribute(DATABASE_ID, TEAM_APPLY_COLLECTION_ID, 'email', true) + await databases.createStringAttribute(DATABASE_ID, TEAM_APPLY_COLLECTION_ID, 'discordName', 128, true) + await databases.createStringAttribute(DATABASE_ID, TEAM_APPLY_COLLECTION_ID, 'role', 24, true) + await databases.createStringAttribute(DATABASE_ID, TEAM_APPLY_COLLECTION_ID, 'message', 4096, true) + } finally { + collectionEnsured = true + } + } +})() diff --git a/src/services/frontend/database.ts b/src/services/frontend/database.ts new file mode 100644 index 0000000..2257640 --- /dev/null +++ b/src/services/frontend/database.ts @@ -0,0 +1,2 @@ +export const DATABASE_NAME = 'entgamers-website' +export const DATABASE_ID = process.env.NEXT_PUBLIC_APPWRITE_DATABASE_ID ?? DATABASE_NAME diff --git a/src/services/frontend/teamApply.ts b/src/services/frontend/teamApply.ts new file mode 100644 index 0000000..ded76a4 --- /dev/null +++ b/src/services/frontend/teamApply.ts @@ -0,0 +1,25 @@ +import { ID, databases } from '@/lib/appwrite' +import { DATABASE_ID } from '@/services/frontend/database' +import { type TeamApplyData, type TeamApplyDocument, type TeamApplyList } from '@/types/teamApply' + +export const TEAM_APPLY_COLLECTION_NAME = 'team-apply' +export const TEAM_APPLY_COLLECTION_ID = process.env.NEXT_PUBLIC_APPWRITE_TEAM_APPLY_COLLECTION_ID ?? TEAM_APPLY_COLLECTION_NAME + +export const createTeamApply = async (data: TeamApplyData): Promise => { + const createdTeamApply = await databases.createDocument(DATABASE_ID, TEAM_APPLY_COLLECTION_ID, ID.unique(), data) + return createdTeamApply +} + +export const getTeamApply = async (teamApplyId: string): Promise => { + const teamApply = await databases.getDocument(DATABASE_ID, TEAM_APPLY_COLLECTION_ID, teamApplyId) + return teamApply +} + +export const listTeamApply = async (): Promise => { + const teamApplyList = await databases.listDocuments(DATABASE_ID, TEAM_APPLY_COLLECTION_ID) + return teamApplyList +} + +export const deleteTeamApply = async (teamApplyId: string): Promise => { + await databases.deleteDocument(DATABASE_ID, TEAM_APPLY_COLLECTION_ID, teamApplyId) +} diff --git a/src/types/User.ts b/src/types/User.ts index 40ec753..6584154 100644 --- a/src/types/User.ts +++ b/src/types/User.ts @@ -1,5 +1,7 @@ import { type IconDefinition } from '@fortawesome/fontawesome-svg-core' +export type UserPreferences = Record + export interface TeamMember { image: string name: string diff --git a/src/types/teamApply.ts b/src/types/teamApply.ts new file mode 100644 index 0000000..bb50058 --- /dev/null +++ b/src/types/teamApply.ts @@ -0,0 +1,13 @@ +import { type Models } from 'appwrite' + +export interface TeamApplyData { + name: string + email: string + discordName: string + message: string + role: 'moderator' | 'administrator' | 'collaborator' +} + +export type TeamApplyDocument = Models.Document & TeamApplyData + +export type TeamApplyList = Models.DocumentList diff --git a/yarn.lock b/yarn.lock index bd6416b..9ab4c6f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3325,6 +3325,16 @@ __metadata: languageName: node linkType: hard +"appwrite@npm:^13.0.0": + version: 13.0.0 + resolution: "appwrite@npm:13.0.0" + dependencies: + cross-fetch: 3.1.5 + isomorphic-form-data: 2.0.0 + checksum: 0495fef9e4b62c8c1317bedf28d7d6f5ac713536bf0a155386356f23161d59b82f3529116c5374d0a914215974f5bf48a0c5728b7b98397eb9c0693cf29e7a23 + languageName: node + linkType: hard + "aproba@npm:^1.0.3 || ^2.0.0": version: 2.0.0 resolution: "aproba@npm:2.0.0" @@ -3579,6 +3589,13 @@ __metadata: languageName: node linkType: hard +"asynckit@npm:^0.4.0": + version: 0.4.0 + resolution: "asynckit@npm:0.4.0" + checksum: 7b78c451df768adba04e2d02e63e2d0bf3b07adcd6e42b4cf665cb7ce899bedd344c69a1dcbce355b5f972d597b25aaa1c1742b52cffd9caccb22f348114f6be + languageName: node + linkType: hard + "autoprefixer@npm:10.4.15": version: 10.4.15 resolution: "autoprefixer@npm:10.4.15" @@ -3611,6 +3628,17 @@ __metadata: languageName: node linkType: hard +"axios@npm:^1.4.0": + version: 1.5.0 + resolution: "axios@npm:1.5.0" + dependencies: + follow-redirects: ^1.15.0 + form-data: ^4.0.0 + proxy-from-env: ^1.1.0 + checksum: e7405a5dbbea97760d0e6cd58fecba311b0401ddb4a8efbc4108f5537da9b3f278bde566deb777935a960beec4fa18e7b8353881f2f465e4f2c0e949fead35be + languageName: node + linkType: hard + "axobject-query@npm:^3.1.1": version: 3.2.1 resolution: "axobject-query@npm:3.2.1" @@ -4115,6 +4143,15 @@ __metadata: languageName: node linkType: hard +"combined-stream@npm:^1.0.6, combined-stream@npm:^1.0.8": + version: 1.0.8 + resolution: "combined-stream@npm:1.0.8" + dependencies: + delayed-stream: ~1.0.0 + checksum: 49fa4aeb4916567e33ea81d088f6584749fc90c7abec76fd516bf1c5aa5c79f3584b5ba3de6b86d26ddd64bae5329c4c7479343250cfe71c75bb366eae53bb7c + languageName: node + linkType: hard + "comma-separated-tokens@npm:^2.0.0": version: 2.0.3 resolution: "comma-separated-tokens@npm:2.0.3" @@ -4235,6 +4272,15 @@ __metadata: languageName: node linkType: hard +"cross-fetch@npm:3.1.5": + version: 3.1.5 + resolution: "cross-fetch@npm:3.1.5" + dependencies: + node-fetch: 2.6.7 + checksum: f6b8c6ee3ef993ace6277fd789c71b6acf1b504fd5f5c7128df4ef2f125a429e29cd62dc8c127523f04a5f2fa4771ed80e3f3d9695617f441425045f505cf3bb + languageName: node + linkType: hard + "cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": version: 7.0.3 resolution: "cross-spawn@npm:7.0.3" @@ -4438,6 +4484,13 @@ __metadata: languageName: node linkType: hard +"delayed-stream@npm:~1.0.0": + version: 1.0.0 + resolution: "delayed-stream@npm:1.0.0" + checksum: 46fe6e83e2cb1d85ba50bd52803c68be9bd953282fa7096f51fc29edd5d67ff84ff753c51966061e5ba7cb5e47ef6d36a91924eddb7f3f3483b1c560f77a0020 + languageName: node + linkType: hard + "delegates@npm:^1.0.0": version: 1.0.0 resolution: "delegates@npm:1.0.0" @@ -5542,6 +5595,16 @@ __metadata: languageName: node linkType: hard +"follow-redirects@npm:^1.15.0": + version: 1.15.3 + resolution: "follow-redirects@npm:1.15.3" + peerDependenciesMeta: + debug: + optional: true + checksum: 584da22ec5420c837bd096559ebfb8fe69d82512d5585004e36a3b4a6ef6d5905780e0c74508c7b72f907d1fa2b7bd339e613859e9c304d0dc96af2027fd0231 + languageName: node + linkType: hard + "for-each@npm:^0.3.3": version: 0.3.3 resolution: "for-each@npm:0.3.3" @@ -5561,6 +5624,28 @@ __metadata: languageName: node linkType: hard +"form-data@npm:^2.3.2": + version: 2.5.1 + resolution: "form-data@npm:2.5.1" + dependencies: + asynckit: ^0.4.0 + combined-stream: ^1.0.6 + mime-types: ^2.1.12 + checksum: 5134ada56cc246b293a1ac7678dba6830000603a3979cf83ff7b2f21f2e3725202237cfb89e32bcb38a1d35727efbd3c3a22e65b42321e8ade8eec01ce755d08 + languageName: node + linkType: hard + +"form-data@npm:^4.0.0": + version: 4.0.0 + resolution: "form-data@npm:4.0.0" + dependencies: + asynckit: ^0.4.0 + combined-stream: ^1.0.8 + mime-types: ^2.1.12 + checksum: 01135bf8675f9d5c61ff18e2e2932f719ca4de964e3be90ef4c36aacfc7b9cb2fceb5eca0b7e0190e3383fe51c5b37f4cb80b62ca06a99aaabfcfd6ac7c9328c + languageName: node + linkType: hard + "formik@npm:^2.4.4": version: 2.4.4 resolution: "formik@npm:2.4.4" @@ -6729,6 +6814,15 @@ __metadata: languageName: node linkType: hard +"isomorphic-form-data@npm:2.0.0": + version: 2.0.0 + resolution: "isomorphic-form-data@npm:2.0.0" + dependencies: + form-data: ^2.3.2 + checksum: 234bfaa1ed037b1d6cf659eb7a5806889f1f60bc4c7effe5f54e52506004604a9d7229a03a8f9656a1a7ea5fcedca4342277083e38f88ff910b64eefa97dd95e + languageName: node + linkType: hard + "iterator.prototype@npm:^1.1.2": version: 1.1.2 resolution: "iterator.prototype@npm:1.1.2" @@ -7790,6 +7884,22 @@ __metadata: languageName: node linkType: hard +"mime-db@npm:1.52.0": + version: 1.52.0 + resolution: "mime-db@npm:1.52.0" + checksum: 0d99a03585f8b39d68182803b12ac601d9c01abfa28ec56204fa330bc9f3d1c5e14beb049bafadb3dbdf646dfb94b87e24d4ec7b31b7279ef906a8ea9b6a513f + languageName: node + linkType: hard + +"mime-types@npm:^2.1.12": + version: 2.1.35 + resolution: "mime-types@npm:2.1.35" + dependencies: + mime-db: 1.52.0 + checksum: 89a5b7f1def9f3af5dad6496c5ed50191ae4331cc5389d7c521c8ad28d5fdad2d06fd81baf38fed813dc4e46bb55c8145bb0ff406330818c9cf712fb2e9b3836 + languageName: node + linkType: hard + "mime@npm:^3.0.0": version: 3.0.0 resolution: "mime@npm:3.0.0" @@ -8082,6 +8192,7 @@ __metadata: "@types/react-dom": ^18.2.7 "@typescript-eslint/eslint-plugin": ^6.4.0 "@typescript-eslint/parser": ^5.38.0 + appwrite: ^13.0.0 entgamers-panda-preset: 0.0.7 eslint: ^8.0.1 eslint-config-next: latest @@ -8099,6 +8210,7 @@ __metadata: isomorphic-fetch: ^3.0.0 next: 13.4.19 next-connect: ^1.0.0 + node-appwrite: ^11.0.0 react: 18.2.0 react-dom: 18.2.0 sharp: ^0.32.5 @@ -8190,6 +8302,16 @@ __metadata: languageName: node linkType: hard +"node-appwrite@npm:^11.0.0": + version: 11.0.0 + resolution: "node-appwrite@npm:11.0.0" + dependencies: + axios: ^1.4.0 + form-data: ^4.0.0 + checksum: ccbfe4ba7bab28a964d22018a7c38c8ad2c8447dc8f4bb310ed3d127aecf373fffc4e53ef8a5162f91dfa84b1e7eae5c160d2e4fee2c598a848131636e39e5fd + languageName: node + linkType: hard + "node-eval@npm:^2.0.0": version: 2.0.0 resolution: "node-eval@npm:2.0.0" @@ -8199,6 +8321,20 @@ __metadata: languageName: node linkType: hard +"node-fetch@npm:2.6.7": + version: 2.6.7 + resolution: "node-fetch@npm:2.6.7" + dependencies: + whatwg-url: ^5.0.0 + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + checksum: 8d816ffd1ee22cab8301c7756ef04f3437f18dace86a1dae22cf81db8ef29c0bf6655f3215cb0cdb22b420b6fe141e64b26905e7f33f9377a7fa59135ea3e10b + languageName: node + linkType: hard + "node-fetch@npm:^2.6.1": version: 2.7.0 resolution: "node-fetch@npm:2.7.0" @@ -8956,6 +9092,13 @@ __metadata: languageName: node linkType: hard +"proxy-from-env@npm:^1.1.0": + version: 1.1.0 + resolution: "proxy-from-env@npm:1.1.0" + checksum: ed7fcc2ba0a33404958e34d95d18638249a68c430e30fcb6c478497d72739ba64ce9810a24f53a7d921d0c065e5b78e3822759800698167256b04659366ca4d4 + languageName: node + linkType: hard + "pump@npm:^3.0.0": version: 3.0.0 resolution: "pump@npm:3.0.0"