From aef3ccedeabdfd5d9f4d371302886b1b606eb9b5 Mon Sep 17 00:00:00 2001 From: mariacasancho Date: Fri, 9 Oct 2020 11:45:09 +0200 Subject: [PATCH] feedback table --- components/DashboardShell.js | 41 +++++------- components/DeleteFeedbackButton.js | 74 ++++++++++++++++++++++ components/FeedbackTable.js | 43 +++++++++++++ components/FeedbackTableHeader.js | 23 +++++++ components/FeedbackTableSkeleton.js | 45 ++++++++++++++ components/SiteTable.js | 2 +- components/SiteTableHeader.js | 26 ++++++++ lib/auth.js | 8 +++ lib/db-admin.js | 16 +++++ lib/db.js | 4 ++ pages/api/feedback.js | 13 ++++ pages/dashboard.js | 11 +++- pages/feedback.js | 37 +++++++++++ pages/index.js | 96 +++++++++++++++++++---------- styles/theme.js | 36 +++++++++++ 15 files changed, 414 insertions(+), 61 deletions(-) create mode 100644 components/DeleteFeedbackButton.js create mode 100644 components/FeedbackTable.js create mode 100644 components/FeedbackTableHeader.js create mode 100644 components/FeedbackTableSkeleton.js create mode 100644 components/SiteTableHeader.js create mode 100644 pages/api/feedback.js create mode 100644 pages/feedback.js diff --git a/components/DashboardShell.js b/components/DashboardShell.js index 8a3d6dc..a4b9b16 100644 --- a/components/DashboardShell.js +++ b/components/DashboardShell.js @@ -1,16 +1,6 @@ import React from 'react'; -import { - Box, - Breadcrumb, - BreadcrumbItem, - BreadcrumbLink, - Heading, - Button, - Flex, - Link, - Avatar, - Icon -} from '@chakra-ui/core'; +import NextLink from 'next/link'; +import { Box, Button, Flex, Link, Avatar, Icon } from '@chakra-ui/core'; import { useAuth } from '@/lib/auth'; import AddSiteModal from './AddSiteModal'; @@ -31,29 +21,28 @@ const DashboardShell = ({ children }) => { w="full" px={8} > - - - Sites - Feedback + + + + + + + + Sites + + + Feedback + - + - - - Sites - - - - My Sites - + Add Site - {children} diff --git a/components/DeleteFeedbackButton.js b/components/DeleteFeedbackButton.js new file mode 100644 index 0000000..698ce42 --- /dev/null +++ b/components/DeleteFeedbackButton.js @@ -0,0 +1,74 @@ +import React, { useState, useRef } from 'react'; +import { mutate } from 'swr'; +import { + AlertDialog, + AlertDialogBody, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogContent, + AlertDialogOverlay, + IconButton, + Button +} from '@chakra-ui/core'; + +import { deleteFeedback } from '@/lib/db'; +import { useAuth } from '@/lib/auth'; + +const DeleteFeedbackButton = ({ feedbackId }) => { + const [isOpen, setIsOpen] = useState(); + const cancelRef = useRef(); + const auth = useAuth(); + + const onClose = () => setIsOpen(false); + const onDelete = () => { + deleteFeedback(feedbackId); + mutate( + ['/api/feedback', auth.user.token], + async (data) => { + return { + feedback: data.feedback.filter( + (feedback) => feedback.id !== feedbackId + ) + }; + }, + false + ); + onClose(); + }; + + return ( + <> + setIsOpen(true)} + /> + + + + + Delete Feedback + + + Are you sure? You can't undo this action afterwards. + + + + + + + + + ); +}; + +export default DeleteFeedbackButton; \ No newline at end of file diff --git a/components/FeedbackTable.js b/components/FeedbackTable.js new file mode 100644 index 0000000..9a3e594 --- /dev/null +++ b/components/FeedbackTable.js @@ -0,0 +1,43 @@ +import React from 'react'; +import { Box, Code, Switch, IconButton } from '@chakra-ui/core'; + +import { Table, Tr, Th, Td } from './Table'; +import DeleteFeedbackButton from './DeleteFeedbackButton'; + +const FeedbackTable = (props) => { + return ( + + + + + + + + + + + + {props.feedback.map((feedback) => ( + + + + + + + + ))} + +
NameFeedbackRouteVisible{''}
{feedback.author}{feedback.text} + {feedback.route || '/'} + + + + +
+ ); +}; + +export default FeedbackTable; \ No newline at end of file diff --git a/components/FeedbackTableHeader.js b/components/FeedbackTableHeader.js new file mode 100644 index 0000000..49e21b2 --- /dev/null +++ b/components/FeedbackTableHeader.js @@ -0,0 +1,23 @@ +import React from 'react'; +import { + Breadcrumb, + BreadcrumbItem, + BreadcrumbLink, + Heading, + Flex +} from '@chakra-ui/core'; + +const FeedbackTableHeader = () => ( + <> + + + Feedback + + + + My Feedback + + +); + +export default FeedbackTableHeader; \ No newline at end of file diff --git a/components/FeedbackTableSkeleton.js b/components/FeedbackTableSkeleton.js new file mode 100644 index 0000000..bb9a392 --- /dev/null +++ b/components/FeedbackTableSkeleton.js @@ -0,0 +1,45 @@ +import React from 'react'; +import { Box, Skeleton } from '@chakra-ui/core'; +import { Table, Tr, Th, Td } from './Table'; + +const SkeletonRow = ({ width }) => ( + + + + + + + + + + + + + + +); + +const FeedbackTableSkeleton = () => { + return ( + + + + + + + + + + + + + + + + + +
NameFeedbackRouteVisible{''}
+ ); +}; + +export default FeedbackTableSkeleton; \ No newline at end of file diff --git a/components/SiteTable.js b/components/SiteTable.js index 358539f..86f33c8 100644 --- a/components/SiteTable.js +++ b/components/SiteTable.js @@ -27,7 +27,7 @@ const SiteTable = ({ sites }) => { - View Feedback + View Feedback {format(parseISO(site.createdAt), 'PPpp')} diff --git a/components/SiteTableHeader.js b/components/SiteTableHeader.js new file mode 100644 index 0000000..d77c553 --- /dev/null +++ b/components/SiteTableHeader.js @@ -0,0 +1,26 @@ +import React from 'react'; +import { + Breadcrumb, + BreadcrumbItem, + BreadcrumbLink, + Heading, + Flex +} from '@chakra-ui/core'; + +import AddSiteModal from './AddSiteModal'; + +const SiteTableHeader = () => ( + <> + + + Sites + + + + My Sites + + Add Site + + +); + +export default SiteTableHeader; \ No newline at end of file diff --git a/lib/auth.js b/lib/auth.js index d727615..6ce3c6e 100644 --- a/lib/auth.js +++ b/lib/auth.js @@ -44,6 +44,13 @@ function useProvideAuth() { .then((response) => handlerUser(response.user)); }; + const signinWithGoogle = () => { + return firebase + .auth() + .signInWithPopup(new firebase.auth.GoogleAuthProvider()) + .then((response) => handleUser(response.user)); + }; + const signout = () => { return firebase .auth() @@ -60,6 +67,7 @@ function useProvideAuth() { return { user, signinWithGithub, + signinWithGoogle, signout }; } diff --git a/lib/db-admin.js b/lib/db-admin.js index 2a63459..b1142f1 100644 --- a/lib/db-admin.js +++ b/lib/db-admin.js @@ -54,3 +54,19 @@ export async function getUserSites(uid) { return { sites }; } + + +export async function getUserFeedback(uid) { + const snapshot = await db + .collection('feedback') + .where('authorId', '==', uid) + .get(); + + const feedback = []; + + snapshot.forEach((doc) => { + feedback.push({ id: doc.id, ...doc.data() }); + }); + + return { feedback }; +} diff --git a/lib/db.js b/lib/db.js index 42e34bd..c4bd713 100644 --- a/lib/db.js +++ b/lib/db.js @@ -16,3 +16,7 @@ export function createSite(data) { export function createFeedback(data) { return firestore.collection('feedback').add(data); } + +export function deleteFeedback(id) { + return firestore.collection('feedback').doc(id).delete(); +} \ No newline at end of file diff --git a/pages/api/feedback.js b/pages/api/feedback.js new file mode 100644 index 0000000..8628dbb --- /dev/null +++ b/pages/api/feedback.js @@ -0,0 +1,13 @@ +import { auth } from '@/lib/firebase-admin'; +import { getUserFeedback } from '@/lib/db-admin'; + +export default async (req, res) => { + try { + const { uid } = await auth.verifyIdToken(req.headers.token); + const { feedback } = await getUserFeedback(uid); + + res.status(200).json({ feedback }); + } catch (error) { + res.status(500).json({ error }); + } +}; \ No newline at end of file diff --git a/pages/dashboard.js b/pages/dashboard.js index 780479f..2fe825c 100644 --- a/pages/dashboard.js +++ b/pages/dashboard.js @@ -7,6 +7,7 @@ import EmptyState from '@/components/EmptyState'; import DashboardShell from '@/components/DashboardShell'; import SiteTableSkeleton from '@/components/SiteTableSkeleton'; import SiteTable from '@/components/SiteTable'; +import SiteTableHeader from '@/components/SiteTableHeader'; import fetcher from '@/utils/fetcher'; const Dashboard = () => { @@ -14,12 +15,18 @@ const Dashboard = () => { const { data, error } = useSWR(user ? ['/api/sites', user.token] : null, fetcher); if (!data) { - return ; + return ( + + + + + ); } return ( - {data ?.sites ? : }; + + {data.sites.length ? : }; ); }; diff --git a/pages/feedback.js b/pages/feedback.js new file mode 100644 index 0000000..8228447 --- /dev/null +++ b/pages/feedback.js @@ -0,0 +1,37 @@ +import useSWR from 'swr'; + +import { useAuth } from '@/lib/auth'; +import fetcher from '@/utils/fetcher'; +import EmptyState from '@/components/EmptyState'; +import DashboardShell from '@/components/DashboardShell'; +import FeedbackTable from '@/components/FeedbackTable'; +import FeedbackTableHeader from '@/components/FeedbackTableHeader'; +import FeedbackTableSkeleton from '@/components/FeedbackTableSkeleton'; + +const MyFeedback = () => { + const { user } = useAuth(); + const { data } = useSWR(user ? ['/api/feedback', user.token] : null, fetcher); + + console.log("feedbackpage"); + if (!data) { + return ( + + + + + ); + } + + return ( + + + {data.feedback.length ? ( + + ) : ( + + )} + + ); +}; + +export default MyFeedback; \ No newline at end of file diff --git a/pages/index.js b/pages/index.js index 9998cd0..a0fa040 100644 --- a/pages/index.js +++ b/pages/index.js @@ -1,45 +1,77 @@ import Head from 'next/head'; -import { Button, Flex, Text, Code, Icon } from '@chakra-ui/core'; +import { Button, Flex, Text, Code, Icon, Box, Stack } from '@chakra-ui/core'; import { useAuth } from '@/lib/auth'; export default function Home() { const auth = useAuth(); return ( - - -