diff --git a/.env.local.example b/.env.local.example deleted file mode 100644 index def7fde6..00000000 --- a/.env.local.example +++ /dev/null @@ -1 +0,0 @@ -TIME_ZONE="America/Edmonton" diff --git a/.husky/pre-commit b/.husky/pre-commit deleted file mode 100755 index b51a66b8..00000000 --- a/.husky/pre-commit +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" - -npx lint-staged -# eslint --fix . -# npm run lint diff --git a/.lintstagedrc.json b/.lintstagedrc.json deleted file mode 100644 index a156f838..00000000 --- a/.lintstagedrc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "src/**/*.{js,jsx,ts,tsx}": ["yarn prettier --write ."] -} diff --git a/next.config.js b/next.config.js deleted file mode 100644 index e85fc5d2..00000000 --- a/next.config.js +++ /dev/null @@ -1,13 +0,0 @@ -/** @type {import('next').NextConfig} */ -const nextConfig = { - images: { - remotePatterns: [ - { - protocol: "https", - hostname: "images.ctfassets.net", - }, - ], - }, -}; - -export default nextConfig; diff --git a/package.json b/package.json index 5ceba816..96d48908 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "contentful": "^10.15.0", "date-fns": "^4.1.0", "js-sha3": "^0.9.3", + "lodash.debounce": "^4.0.8", "luxon": "^3.4.4", "next": "^14.2.12", "react": "^18", @@ -55,6 +56,7 @@ "@next/eslint-plugin-next": "^15.4.5", "@tanstack/react-query-devtools": "^5.84.1", "@types/aws-lambda": "^8.10.138", + "@types/lodash.debounce": "^4.0.9", "@types/luxon": "^3.4.2", "@types/node": "^20.12.7", "@types/react": "^18", diff --git a/postcss.config.cjs b/postcss.config.cjs deleted file mode 100644 index 12a703d9..00000000 --- a/postcss.config.cjs +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -}; diff --git a/src/app/admin/components/UsersTableSetup.tsx b/src/app/admin/components/UsersTableSetup.tsx index 8a5991d3..2ccb1a26 100644 --- a/src/app/admin/components/UsersTableSetup.tsx +++ b/src/app/admin/components/UsersTableSetup.tsx @@ -1,6 +1,7 @@ "use client"; -import { useState } from "react"; +import debounce from "lodash.debounce"; +import { useMemo, useState } from "react"; import { TbInfoSquareRoundedFilled } from "react-icons/tb"; import { createColumnHelper } from "@tanstack/react-table"; import DeleteButton from "../teams/components/DeleteButton"; @@ -45,6 +46,13 @@ export const usersColumns = [ }, }) => { const [value, setValue] = useState(getValue()!); + const debouncedUpdate = useMemo( + () => + debounce((newValue: string) => { + meta?.updateData(index, "teamId", newValue); + }, 300), + [meta, index], + ); if (!getIsSelected()) return getValue(); const onBlur = () => { meta?.updateData(index, "teamId", value); @@ -53,7 +61,10 @@ export const usersColumns = [ setValue(e.target.value)} + onChange={(e) => { + setValue(e.target.value); + debouncedUpdate(e.target.value); + }} onBlur={onBlur} /> ); @@ -70,6 +81,13 @@ export const usersColumns = [ }) => { const initialValue = getValue()!; const [value, setValue] = useState(initialValue); + const debouncedUpdate = useMemo( + () => + debounce((newValue: string) => { + meta?.updateData(index, "firstName", newValue); + }, 300), + [meta, index], + ); if (!getIsSelected()) { return getValue(); } @@ -80,7 +98,10 @@ export const usersColumns = [ setValue(e.target.value)} + onChange={(e) => { + setValue(e.target.value); + debouncedUpdate(e.target.value); + }} onBlur={onBlur} /> ); @@ -99,6 +120,13 @@ export const usersColumns = [ }) => { const initialValue = getValue()!; const [value, setValue] = useState(initialValue); + const debouncedUpdate = useMemo( + () => + debounce((newValue: string) => { + meta?.updateData(index, "lastName", newValue); + }, 300), + [meta, index], + ); if (!getIsSelected()) { return getValue(); } @@ -109,7 +137,10 @@ export const usersColumns = [ setValue(e.target.value)} + onChange={(e) => { + setValue(e.target.value); + debouncedUpdate(e.target.value); + }} onBlur={onBlur} /> ); @@ -128,6 +159,13 @@ export const usersColumns = [ }) => { const initialValue = getValue(); const [value, setValue] = useState(initialValue ?? ""); + const debouncedUpdate = useMemo( + () => + debounce((newValue: string) => { + meta?.updateData(index, "role", newValue); + }, 300), + [meta, index], + ); if (!getIsSelected()) { return getValue(); } @@ -140,7 +178,7 @@ export const usersColumns = [ className="w-full rounded-md border border-awesomer-purple bg-white p-2 focus:outline-none focus:ring-1 focus:ring-awesomer-purple" onChange={(e) => { setValue(Role[e.target.value as keyof typeof Role]); - onBlur(); + debouncedUpdate(Role[e.target.value as keyof typeof Role]); }} onBlur={onBlur} > diff --git a/src/app/admin/create-food-event/createFoodEventForm.tsx b/src/app/admin/create-food-event/createFoodEventForm.tsx index 84bd48a9..64a29bf1 100644 --- a/src/app/admin/create-food-event/createFoodEventForm.tsx +++ b/src/app/admin/create-food-event/createFoodEventForm.tsx @@ -1,6 +1,8 @@ "use client"; +import debounce from "lodash.debounce"; import { DateTime } from "luxon"; +import { useMemo } from "react"; import type { SubmitHandler } from "react-hook-form"; import { useForm } from "react-hook-form"; import { type Schema } from "@/amplify/data/resource"; @@ -24,6 +26,14 @@ const CreateFoodTicketForm = () => { formState: { errors, isSubmitting }, } = useForm(); + const debouncedFormUpdate = useMemo( + () => + debounce((field: string, value: string) => { + console.log(`Field ${field} updated to ${value} - Auto-saving...`); + }, 500), + [], + ); + const foodEventMutation = useMutation({ mutationFn: createFoodEvent, onSuccess: () => { @@ -80,6 +90,9 @@ const CreateFoodTicketForm = () => { type="text" className={INPUT_STYLES} placeholder="Breakfast, Lunch, or Dinner" + onChange={(e) => { + debouncedFormUpdate(e.target.name || "name", e.target.value); + }} /> {errors.name && (
{errors.name.message}
@@ -91,6 +104,12 @@ const CreateFoodTicketForm = () => { })} className={INPUT_STYLES} placeholder="Description" + onChange={(e) => { + debouncedFormUpdate( + e.target.name || "description", + e.target.value, + ); + }} /> {errors.description && (
@@ -104,6 +123,9 @@ const CreateFoodTicketForm = () => { })} type="datetime-local" className={INPUT_STYLES} + onChange={(e) => { + debouncedFormUpdate(e.target.name || "start", e.target.value); + }} /> {errors.start && (
{errors.start.message}
@@ -115,6 +137,9 @@ const CreateFoodTicketForm = () => { })} type="datetime-local" className={INPUT_STYLES} + onChange={(e) => { + debouncedFormUpdate(e.target.name || "end", e.target.value); + }} /> {errors.end && (
{errors.end.message}
@@ -127,6 +152,12 @@ const CreateFoodTicketForm = () => { type="text" className={INPUT_STYLES} placeholder="Number of Groups" + onChange={(e) => { + debouncedFormUpdate( + e.target.name || "totalGroupCount", + e.target.value, + ); + }} /> {errors.totalGroupCount && (
diff --git a/src/app/admin/teams/TeamTableSetup.tsx b/src/app/admin/teams/TeamTableSetup.tsx index 0e4ff409..d85357df 100644 --- a/src/app/admin/teams/TeamTableSetup.tsx +++ b/src/app/admin/teams/TeamTableSetup.tsx @@ -1,4 +1,5 @@ -import { useState } from "react"; +import debounce from "lodash.debounce"; +import { useMemo, useState } from "react"; import { TbInfoSquareRoundedFilled } from "react-icons/tb"; import { createColumnHelper } from "@tanstack/react-table"; import DeleteButton from "./components/DeleteButton"; @@ -22,13 +23,27 @@ export const teamColumns = [ }, }) => { const [value, setValue] = useState(getValue()); + + const debouncedUpdate = useMemo( + () => + debounce((newValue: string) => { + meta?.updateData(index, "name", newValue); + }, 300), + [meta, index], + ); + if (!getIsSelected()) return getValue(); const onBlur = () => meta?.updateData(index, "name", value); + const onChange = (e: React.ChangeEvent) => { + const newValue = e.target.value; + setValue(newValue); + debouncedUpdate(newValue); + }; return ( setValue(e.target.value)} + onChange={onChange} onBlur={onBlur} /> ); @@ -66,22 +81,32 @@ export const teamColumns = [ }) => { const initialValue = getValue(); const [value, setValue] = useState(initialValue); + + const debouncedUpdate = useMemo( + () => + debounce((newValue: boolean) => { + meta?.updateData(index, "approved", newValue); + }, 300), + [meta, index], + ); + if (!getIsSelected()) return getValue() ? "Approved" : "Not Approved"; const ApproveStatus = { Approved: true, "Not Approved": false, } as const; const onBlur = () => meta?.updateData(index, "approved", value); + const onChange = (e: React.ChangeEvent) => { + const newValue = + ApproveStatus[e.target.value as keyof typeof ApproveStatus]; + setValue(newValue); + debouncedUpdate(newValue); + }; return (