From c50869398727a7d46e452cc856877754e494c671 Mon Sep 17 00:00:00 2001 From: jahooma Date: Fri, 21 Jan 2022 16:54:02 -0600 Subject: [PATCH] Edit fold page --- firestore.rules | 1 + web/lib/firebase/folds.ts | 6 +- web/pages/fold/[foldSlug]/edit.tsx | 106 ++++++++++++++++++++- web/pages/fold/[foldSlug]/leaderboards.tsx | 24 ++++- 4 files changed, 129 insertions(+), 8 deletions(-) diff --git a/firestore.rules b/firestore.rules index 5e5f3637..2091eb0c 100644 --- a/firestore.rules +++ b/firestore.rules @@ -37,6 +37,7 @@ service cloud.firestore { match /folds/{foldId} { allow read; + allow update: if request.auth.uid == resource.data.curatorId; } } } \ No newline at end of file diff --git a/web/lib/firebase/folds.ts b/web/lib/firebase/folds.ts index e4436707..f1da0444 100644 --- a/web/lib/firebase/folds.ts +++ b/web/lib/firebase/folds.ts @@ -1,4 +1,4 @@ -import { collection, query, where } from 'firebase/firestore' +import { collection, doc, query, updateDoc, where } from 'firebase/firestore' import { Fold } from '../../../common/fold' import { Contract, contractCollection } from './contracts' import { db } from './init' @@ -10,6 +10,10 @@ export function foldPath(fold: Fold, subpath?: 'edit' | 'leaderboards') { return `/fold/${fold.slug}${subpath ? `/${subpath}` : ''}` } +export function updateFold(fold: Fold, updates: Partial) { + return updateDoc(doc(foldCollection, fold.id), updates) +} + export async function listAllFolds() { return getValues(foldCollection) } diff --git a/web/pages/fold/[foldSlug]/edit.tsx b/web/pages/fold/[foldSlug]/edit.tsx index 7f83496e..efc6bb53 100644 --- a/web/pages/fold/[foldSlug]/edit.tsx +++ b/web/pages/fold/[foldSlug]/edit.tsx @@ -1,9 +1,28 @@ +import clsx from 'clsx' import _ from 'lodash' +import { ArrowCircleLeftIcon } from '@heroicons/react/solid' +import { useState } from 'react' +import { Fold } from '../../../../common/fold' +import { parseWordsAsTags } from '../../../../common/util/parse' +import { Col } from '../../../components/layout/col' +import { Spacer } from '../../../components/layout/spacer' import { Page } from '../../../components/page' +import { TagsList } from '../../../components/tags-list' +import { + foldPath, + getFoldBySlug, + updateFold, +} from '../../../lib/firebase/folds' +import Custom404 from '../../404' +import { SiteLink } from '../../../components/site-link' + +export async function getStaticProps(props: { params: { foldSlug: string } }) { + const { foldSlug } = props.params + + const fold = await getFoldBySlug(foldSlug) -export async function getStaticProps() { return { - props: {}, + props: { fold }, revalidate: 60, // regenerate after a minute } @@ -13,6 +32,85 @@ export async function getStaticPaths() { return { paths: [], fallback: 'blocking' } } -export default function Leaderboards(props: {}) { - return Edit fold +export default function EditFoldPage(props: { fold: Fold | null }) { + const { fold } = props + + const [name, setName] = useState(fold?.name ?? '') + const [tags, setTags] = useState(fold?.tags.join(', ') ?? '') + const [isSubmitting, setIsSubmitting] = useState(false) + + if (!fold) return + + const saveDisabled = + !name || + !tags || + (name === fold.name && _.isEqual(parseWordsAsTags(tags), fold.tags)) + + const onSubmit = async () => { + setIsSubmitting(true) + + await updateFold(fold, { name, tags: parseWordsAsTags(tags) }) + + setIsSubmitting(false) + } + + return ( + + + + + {' '} + {fold.name} + + + + +
+ + + setName(e.target.value || '')} + /> +
+ + + +
+ + + setTags(e.target.value || '')} + /> +
+ + + + + + + + +
+ ) } diff --git a/web/pages/fold/[foldSlug]/leaderboards.tsx b/web/pages/fold/[foldSlug]/leaderboards.tsx index 1226683f..66070790 100644 --- a/web/pages/fold/[foldSlug]/leaderboards.tsx +++ b/web/pages/fold/[foldSlug]/leaderboards.tsx @@ -1,12 +1,22 @@ import _ from 'lodash' +import { ArrowCircleLeftIcon } from '@heroicons/react/solid' + import { Col } from '../../../components/layout/col' import { Leaderboard } from '../../../components/leaderboard' import { Page } from '../../../components/page' +import { SiteLink } from '../../../components/site-link' import { formatMoney } from '../../../lib/util/format' +import { foldPath, getFoldBySlug } from '../../../lib/firebase/folds' +import { Fold } from '../../../../common/fold' +import { Spacer } from '../../../components/layout/spacer' + +export async function getStaticProps(props: { params: { foldSlug: string } }) { + const { foldSlug } = props.params + + const fold = await getFoldBySlug(foldSlug) -export async function getStaticProps() { return { - props: {}, + props: { fold }, revalidate: 60, // regenerate after a minute } @@ -16,9 +26,17 @@ export async function getStaticPaths() { return { paths: [], fallback: 'blocking' } } -export default function Leaderboards(props: {}) { +export default function Leaderboards(props: { fold: Fold }) { + const { fold } = props return ( + + {' '} + {fold.name} + + + +