Skip to content

Commit 177a027

Browse files
committed
Create survey component
1 parent a2b1fd6 commit 177a027

5 files changed

Lines changed: 81 additions & 3 deletions

File tree

src/Survey.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { useSurvey } from './hooks/useSurvey'
2+
3+
const Survey = () => {
4+
const { navigateToSurvey } = useSurvey()
5+
6+
navigateToSurvey()
7+
}
8+
9+
export default Survey

src/hooks/useSheets.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { useCallback, useEffect, useState } from 'react'
2+
import { getSheetsData } from '../services/sheets'
3+
4+
const useSheets = (query: string) => {
5+
const [value, setValue] = useState<string | null>(null)
6+
7+
const getLink = useCallback(() => {
8+
getSheetsData(query)
9+
.then(setValue)
10+
.catch(err => { throw new Error(err) })
11+
}, [query])
12+
13+
useEffect(() => {
14+
getLink()
15+
}, [getLink])
16+
17+
return { value }
18+
}
19+
20+
export default useSheets

src/hooks/useSurvey.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { useNavigate } from 'react-router-dom'
2+
import useSheets from './useSheets'
3+
4+
export const useSurvey = () => {
5+
const { value: link } = useSheets(`select A where A contains 'https' limit 1`)
6+
const navigate = useNavigate()
7+
8+
const navigateToSurvey = () => { if (link) window.location = link }
9+
10+
const openSurvey = () => {
11+
if (link) {
12+
window.open(link)
13+
navigate('/')
14+
}
15+
}
16+
17+
return { openSurvey, navigateToSurvey }
18+
}

src/routes.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ import { type ReactElement } from 'react'
33
import Home from './Home'
44
import Sponsorship from './Sponsorship'
55
import About from './About'
6+
import Survey from './Survey'
67

78
export default function Router (): ReactElement | null {
89
const routes = useRoutes([
9-
{ path: '/', element: <Home /> },
10-
{ path: '/about', element: <About /> },
11-
{ path: '/sponsorship', element: <Sponsorship /> },
10+
{ path: '/', element: <Home/> },
11+
{ path: '/about', element: <About/> },
12+
{ path: '/sponsorship', element: <Sponsorship/> },
13+
{ path: '/survey', element: <Survey/> },
1214
])
1315

1416
return routes

src/services/sheets.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// fixed value. Idially this should be taken from env
2+
const getSheetId = () => "1UrATDa3qAnoLDJtSCPFzawDZLoJbYAp3mNq4NKyI5wU"
3+
4+
const getSheetUrl = (query: string) => {
5+
const sheetsUrl = 'https://docs.google.com/spreadsheets/d/'
6+
const sheetsQueryPrefix = '/gviz/tq?tq='
7+
const id = getSheetId()
8+
9+
return `${sheetsUrl}${id}${sheetsQueryPrefix}${encodeURIComponent(query)}`
10+
}
11+
12+
const parseSheet = (rawSheet: string) => {
13+
const cleaned = rawSheet.replace(
14+
/.*google.visualization.Query.setResponse\({(.*?)}\);?/s,
15+
"{$1}"
16+
)
17+
18+
// First cell, first value
19+
return JSON.parse(cleaned).table.rows.at().c.at().v
20+
}
21+
22+
export const getSheetsData = async (query: string): Promise<string> => {
23+
return new Promise((resolve, reject) => {
24+
fetch(getSheetUrl(query))
25+
.then(data => data.text())
26+
.then(raw => resolve(parseSheet(raw)))
27+
.catch(reject)
28+
})
29+
}

0 commit comments

Comments
 (0)