From 3b178572aa6dd9c0b7c3bb48b9a954ec13441ce4 Mon Sep 17 00:00:00 2001 From: Oliver Barnwell Date: Sun, 1 Sep 2024 17:07:26 +0100 Subject: [PATCH] improve feedback system so people can provide their email and we store a record of it in our database --- schema.prisma | 29 ++++++++--------- src/api/prisma/queries.ts | 37 ++++++++++----------- src/components/Feedback/Feedback.tsx | 48 ++++++++++++++++------------ src/pages/api/feedback/index.page.ts | 27 +++++++++++++--- 4 files changed, 82 insertions(+), 59 deletions(-) diff --git a/schema.prisma b/schema.prisma index 7bca41491..a84dd9390 100644 --- a/schema.prisma +++ b/schema.prisma @@ -1,12 +1,12 @@ generator client { provider = "prisma-client-js" - previewFeatures = ["multiSchema", "filteredRelationCount", "postgresqlExtensions"] + previewFeatures = ["multiSchema", "postgresqlExtensions"] } datasource db { provider = "postgresql" url = env("POSTGRES_URI") - extensions = [postgis(schema: "public"), uuid_ossp(map: "uuid-ossp", schema: "extensions")] + extensions = [postgis(schema: "extensions"), uuid_ossp(map: "uuid-ossp", schema: "extensions")] schemas = ["audit", "public"] } @@ -30,9 +30,9 @@ model record_version { } model areas { - id String @id(map: "area_id") @db.Char(24) + id String @id @db.Char(24) geometry Unsupported("geography")? - name String? @unique(map: "area_name") + name String? @unique priority Int? type String? dataset_id Int? @@ -42,18 +42,8 @@ model areas { @@schema("public") } -model spatial_ref_sys { - srid Int @id - auth_name String? @db.VarChar(256) - auth_srid Int? - srtext String? @db.VarChar(2048) - proj4text String? @db.VarChar(2048) - - @@schema("public") -} - model toilets { - id String @id(map: "toilet_id") @db.Char(24) + id String @id @db.Char(24) created_at DateTime? @db.Timestamptz(6) contributors String[] accessible Boolean? @@ -84,6 +74,15 @@ model toilets { @@schema("public") } +model feedback { + id Int @id @default(autoincrement()) + email String @db.VarChar(255) + feedback_text String + created_at DateTime? @default(now()) @db.Timestamp(6) + + @@schema("public") +} + enum operation { INSERT UPDATE diff --git a/src/api/prisma/queries.ts b/src/api/prisma/queries.ts index 7a8a1679e..de28d3a58 100644 --- a/src/api/prisma/queries.ts +++ b/src/api/prisma/queries.ts @@ -1,12 +1,10 @@ import { Prisma, PrismaClient, toilets, areas } from '@prisma/client'; import { RemovalReportInput } from '../../api-client/graphql'; - import { ToiletUpsertReport } from '../graphql/helpers'; -import { LooFilter } from '../../@types/resolvers-types'; export const getLooById = async ( prisma: PrismaClient, - id: string + id: string, ): Promise }> => { const res = await prisma.toilets.findUnique({ where: { id }, @@ -17,7 +15,7 @@ export const getLooById = async ( export const getLooNamesByIds = async ( prisma: PrismaClient, - idList: string[] + idList: string[], ) => { return prisma.toilets.findMany({ where: { @@ -36,7 +34,7 @@ export const setLooLocation = async ( prisma: PrismaClient, id: string, lat: number, - lng: number + lng: number, ) => { return prisma.$executeRaw` UPDATE toilets SET @@ -52,7 +50,7 @@ export const setLooLocation = async ( export const getLoosWithinGeohash = async ( prisma: PrismaClient, geohash: string, - active = true + active = true, ) => prisma.toilets.findMany({ where: { @@ -80,7 +78,7 @@ export const getAreas = async (prisma: PrismaClient) => export const upsertLoo = async ( prisma: PrismaClient, report: ToiletUpsertReport, - returnFinal = true + returnFinal = true, ) => { try { const result = await prisma.toilets.upsert({ @@ -97,7 +95,7 @@ export const upsertLoo = async ( prisma, result.id, report.extras.location.lat, - report.extras.location.lng + report.extras.location.lng, ); } @@ -114,7 +112,7 @@ export const upsertLoo = async ( export const removeLoo = async ( prisma: PrismaClient, report: RemovalReportInput, - nickname: string + nickname: string, ) => { const { edit: id, reason } = report; return prisma.toilets.update({ @@ -155,7 +153,7 @@ export const upsertArea = async ( priority: number; type: string; version: number; - } + }, ) => { const areaResult = await prisma.areas.upsert({ where: { id: area.id }, @@ -190,23 +188,26 @@ export const getLoosByProximity = async ( prisma: PrismaClient, lat: number, lng: number, - radius = 1000 + radius = 1000, ) => { const nearbyLoos = (await prisma.$queryRaw` SELECT - loo.id, loo.name, active, men, women, no_payment, notes, opening_times, payment_details, - accessible, active, all_gender, attended, automatic, location, baby_change, children, created_at, - removal_reason, radar, urinal_only, verified_at,updated_at,geohash, + loo.id, loo.name, loo.active, loo.men, loo.women, loo.no_payment, loo.notes, loo.opening_times, + loo.payment_details, loo.accessible, loo.all_gender, loo.attended, loo.automatic, loo.location, + loo.baby_change, loo.children, loo.created_at, loo.removal_reason, loo.radar, loo.urinal_only, + loo.verified_at, loo.updated_at, loo.geohash, st_distancesphere( - geography::geometry, + loo.geography::geometry, ST_MakePoint(${lng}, ${lat}) ) as distance, area.name as area_name, - area.type as area_type from toilets loo inner join areas area on area.id = loo.area_id - where st_distancesphere( + area.type as area_type + FROM toilets loo + INNER JOIN areas area ON area.id = loo.area_id + WHERE st_distancesphere( loo.geography::geometry, ST_MakePoint(${lng}, ${lat}) - ) <= ${radius} + ) <= ${radius} `) as (toilets & { distance: number; area_name?: string; diff --git a/src/components/Feedback/Feedback.tsx b/src/components/Feedback/Feedback.tsx index e8ccffb55..5a75e4f74 100644 --- a/src/components/Feedback/Feedback.tsx +++ b/src/components/Feedback/Feedback.tsx @@ -2,8 +2,9 @@ import { Stack } from '@mui/material'; import React, { useRef, useState } from 'react'; import Badge from '../../design-system/components/Badge'; import Button from '../../design-system/components/Button'; -import Box from '../Box'; import InputField from '../../design-system/components/InputField'; +import Link from 'next/link'; +import TextArea from '../../design-system/components/TextArea'; enum FeedbackState { SUCCESS = 0, @@ -15,7 +16,6 @@ const Feedback = () => { const [submitState, setSubmitState] = useState(FeedbackState.PENDING); const feedbackTextArea = useRef(); - const nameInput = useRef(); const emailInput = useRef(); const submitFeedback = async () => { @@ -25,13 +25,10 @@ const Feedback = () => { const hasUserInputText = feedbackTextArea.current?.value.length > 0; if (hasUserInputText) { - const input = ` -Feedback :love_letter: : ${feedbackTextArea.current.value} -Name: ${nameInput.current.value ?? 'Not provided'} -Email: ${emailInput.current.value ?? 'Not provided'} - `; + const input = feedbackTextArea.current.value; const payload = { text: input, + email: emailInput.current.value, }; try { @@ -46,8 +43,6 @@ Email: ${emailInput.current.value ?? 'Not provided'} // eslint-disable-next-line functional/immutable-data feedbackTextArea.current.value = ''; // eslint-disable-next-line functional/immutable-data - nameInput.current.value = ''; - // eslint-disable-next-line functional/immutable-data emailInput.current.value = ''; setSubmitState(FeedbackState.SUCCESS); @@ -59,29 +54,40 @@ Email: ${emailInput.current.value ?? 'Not provided'} return ( - - + {submitState === FeedbackState.SUCCESS && Thank you!} - + - - + Feedback + + + + + Privacy Policy + - {submitState === FeedbackState.SUCCESS && Thank you!}