Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds the suggestion page with file upload to GCP #330

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
2 changes: 1 addition & 1 deletion src/enums/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ export enum EnvVariable {
FEATURE_FLAG_POSTHOG = "FEATURE_FLAG_POSTHOG",
FEATURE_FLAG_FEEDBACK_MODULE = "FEATURE_FLAG_FEEDBACK_MODULE",
POSTHOG_HOSTNAME_HTTP = "POSTHOG_HOSTNAME_HTTP",
POSTHOG_API_KEY = "POSTHOH_API_KEY",
POSTHOG_API_KEY = "POSTHOG_API_KEY",
}
16 changes: 13 additions & 3 deletions src/hooks/posthog/useCapture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,24 @@ import { featureFlags } from "../../constants"
import * as posthog from "../../posthog"
import { useAnalytics } from "../useAnalytics"

export const useCapture = (eventName: PosthogEvent) => {
export const useCapture = (
eventName: PosthogEvent,
overrideConsent = false
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe shouldOverrideConsent?

) => {
const { isAnalyticsEnabled } = useAnalytics()

return useCallback(
(params) => {
if (!featureFlags.POSTHOG) return
if (!isAnalyticsEnabled) return
posthog.capture(eventName, params)

if (overrideConsent) {
if (!isAnalyticsEnabled) {
posthog.init()
}
posthog.capture(eventName, params)
} else if (isAnalyticsEnabled) {
posthog.capture(eventName, params)
}
},
[eventName, isAnalyticsEnabled]
)
Expand Down
21 changes: 21 additions & 0 deletions src/hooks/useGCloudStorage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { useCallback } from "react"

const bucket = "threshold_dapp_feedback"

const useGCloudStorage: () => (file: File) => Promise<string> = () => {
return useCallback(async (file) => {
const formData = new FormData()

formData.append("file", file)
formData.append("key", file.name)

return fetch(`https://storage.googleapis.com/${bucket}`, {
method: "POST",
body: formData,
}).then((resp) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe let's add catch to log any errors and avoid app crashes.

return `https://storage.cloud.google.com/${bucket}/${file.name}`
})
Comment on lines +12 to +17
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already use axios as a http client see utils/exchangeApi.ts- we could use it, probably simplify code a little bit. Ofc non-blocking.

}, [])
}

export default useGCloudStorage
115 changes: 112 additions & 3 deletions src/pages/Feedback/Suggestions/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,118 @@
import React from "react"
import { Box } from "@threshold-network/components"
import React, { useState } from "react"
import {
BodyLg,
BodySm,
Box,
Button,
Card,
Divider,
FileUploader,
H5,
Select,
Stack,
Textarea,
} from "@threshold-network/components"
import { PageComponent } from "../../../types"
import useGCloudStorage from "../../../hooks/useGCloudStorage"
import Link from "../../../components/Link"
import { ExternalHref, ModalType } from "../../../enums"
import { useCapture } from "../../../hooks/posthog"
import { PosthogEvent } from "../../../types/posthog"
import { useModal } from "../../../hooks/useModal"
import { FeedbackSubmissionType } from "../../../components/Modal/FeedbackSubmissionModal"

const featureCategoryOptions = ["Upgrade", "Staking"]

const Suggestions: PageComponent = () => {
return <Box>suggestions page</Box>
const captureSuggestionSubmit = useCapture(
PosthogEvent.SuggestionSubmit,
true
)
const [file, setFile] = useState<File | null>(null)
const { openModal } = useModal()
const [isLoading, setIsLoading] = useState(false)
const uploadToGCP = useGCloudStorage()
const [featureCategory, setFeatureCategory] = useState("")
const [suggestionText, setSuggestionText] = useState("")

const handleSubmit = async () => {
setIsLoading(true)
let fileLink = ""
if (file) {
fileLink = await uploadToGCP(file)
}

captureSuggestionSubmit({
file: fileLink,
category: featureCategory,
suggestion: suggestionText,
})

setIsLoading(false)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably should set the loading indicator to false once we catch an error.

openModal(ModalType.FeedbackSubmission, {
type: FeedbackSubmissionType.Suggestion,
})
}

return (
<Card>
<Stack spacing={8}>
<H5>What suggestions do you have?</H5>
<Divider />
<BodyLg>
Submit your suggestions for product improvements by using this form.
To discuss ideas with other Threshold users and DAO members, consider
posting it in the{" "}
<Link href={ExternalHref.thresholdDiscord} isExternal>
Discord
</Link>
</BodyLg>
<Box>
<BodySm mb={2} fontWeight="bold">
Feature Category:
</BodySm>
<Select
placeholder="Select option"
value={featureCategory}
onChange={(e) => setFeatureCategory(e.target.value)}
>
{featureCategoryOptions.map((opt) => (
<option value={opt} key={opt}>
{opt}
</option>
))}
</Select>
</Box>
<Box>
<BodySm mb={2} fontWeight="bold">
Suggestions
</BodySm>
<Textarea
value={suggestionText}
onChange={(e) => setSuggestionText(e.target.value)}
placeholder="Enter text"
minH="220px"
/>
</Box>
<FileUploader
onFileUpload={(file) => setFile(file)}
headerHelperText="Optional"
footerHelperText="File can be video or photo. Must be less than 2MB"
accept="image/*"
m="auto"
w="full"
maxW="full"
/>
<Button
isLoading={isLoading}
disabled={suggestionText === "" || featureCategory === ""}
onClick={handleSubmit}
>
Submit Suggestion
</Button>
</Stack>
</Card>
)
}

Suggestions.route = {
Expand Down
1 change: 1 addition & 0 deletions src/types/posthog.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export enum PosthogEvent {
ClosedModal = "Closed Modal",
SuggestionSubmit = "Submitted Suggestion",
}
6 changes: 3 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5371,9 +5371,9 @@
"@openzeppelin/contracts" "^4.1.0"

"@threshold-network/components@development":
version "1.0.0-dev.23"
resolved "https://registry.npmjs.org/@threshold-network/components/-/components-1.0.0-dev.23.tgz#a08a61359a51654070b880e3f017edc2bb555d2e"
integrity sha512-eFAZ+xy7TEwXrttyyjJmJ8NwivvNIOmmU52VNlp3Zb42xJ5lLE65zbtgpHmODZ8ClMhFWQLYfqHoRIO4+fq74w==
version "1.0.0-dev.29"
resolved "https://registry.yarnpkg.com/@threshold-network/components/-/components-1.0.0-dev.29.tgz#5b837e86dad45d34e8056939c7be322c13439dd0"
integrity sha512-G76fuQxo/+yS0fk9DpryFajZyUi2tjuZEPSvyMpd1pdk/aXKlHy8R6ClbdcIDU9H/XDhgh1djS5K0+e+n/YljA==

"@threshold-network/[email protected]", "@threshold-network/solidity-contracts@development":
version "1.2.0-dev.17"
Expand Down