Skip to content
This repository has been archived by the owner on Nov 21, 2024. It is now read-only.

Commit

Permalink
creating a note and displaying a list of note links that don't go any…
Browse files Browse the repository at this point in the history
…where yet.
  • Loading branch information
Courey committed Aug 11, 2023
1 parent 216185d commit 4476e7e
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 19 deletions.
6 changes: 6 additions & 0 deletions app.arc
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,9 @@ plugin-remix
runtime nodejs18.x
region us-east-1
architecture arm64

@tables
notes
userId *String
noteId **String
PointInTimeRecovery true
6 changes: 6 additions & 0 deletions app/lib/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// This is just for example. Typically you would get a user from the session.
// By making it reusable, you would only have to get the userId from the session
// in one place. This makes it portable.
export function getUserId() {
return 'test'
}
122 changes: 103 additions & 19 deletions app/routes/data.new.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { DataFunctionArgs } from '@remix-run/node'
import { useFetcher } from '@remix-run/react'
import { Link, useFetcher, useLoaderData } from '@remix-run/react'
import {
Button,
ButtonGroup,
Expand All @@ -10,37 +10,60 @@ import {
Label,
Select,
TextInput,
Textarea,
} from '@trussworks/react-uswds'
import { useState } from 'react'
import { getUserId } from 'app/lib/utils'
import { useEffect, useRef, useState } from 'react'

import { getInstrumentData } from './data/data.server'
import { createNewNote, getInstrumentData, getNotes } from './data/data.server'
import { tableOptions } from './data/data.table-options'

function validateResultCountInput(input: string) {
const numericalInput = parseFloat(input)
return numericalInput.toString() === input && numericalInput <= 100
}

export async function loader({ request }: DataFunctionArgs) {
const userID = getUserId()
return await getNotes(userID)
}

export async function action({ request }: DataFunctionArgs) {
const userID = getUserId()
const data = await request.formData()
const format = data.get('format')?.toString()
const resultCount = data.get('resultCount')?.toString()
const instrument = data.get('instrument')?.toString()
const ra = data.get('ra')?.toString()
const dec = data.get('dec')?.toString()
const radius = data.get('radius')?.toString()
const intent = data.get('intent')?.toString()

if (intent === 'get-data') {
const format = data.get('format')?.toString()
const resultCount = data.get('resultCount')?.toString()
const instrument = data.get('instrument')?.toString()
const ra = data.get('ra')?.toString()
const dec = data.get('dec')?.toString()
const radius = data.get('radius')?.toString()

if (!instrument || !format || !resultCount || !ra || !dec || !radius)
return null
const res = await getInstrumentData(
instrument,
format,
parseInt(resultCount),
parseFloat(ra),
parseFloat(dec),
parseInt(radius)
)
return res
} else if (intent === 'new-note') {
const noteTitle = data.get('title')?.toString()
const noteBody = data.get('notes')?.toString()
if (!noteBody || !noteTitle) {
return null
}
await createNewNote(noteTitle, noteBody, userID)

if (!instrument || !format || !resultCount || !ra || !dec || !radius)
return null
const res = await getInstrumentData(
instrument,
format,
parseInt(resultCount),
parseFloat(ra),
parseFloat(dec),
parseInt(radius)
)
return res
} else {
return null
}
}

export default function () {
Expand All @@ -51,13 +74,30 @@ export default function () {
const [radius, setRadius] = useState('')
const [resultCount, setResultCount] = useState('')
const isValid = validateResultCountInput(resultCount)
const [noteTitle, setNoteTitle] = useState('')
const [noteBody, setNoteBody] = useState('')

const noteRef = useRef<HTMLFormElement>(null)

const fetcher = useFetcher()
const results = fetcher.data
const fetchNotes = useFetcher()
const notes = useLoaderData<typeof loader>()
const resultArray = results?.request || ['no results']

const shouldDisableForm =
!instrument || !format || !resultCount || !isValid || !ra || !dec || !radius
const shouldDisableNotes = !noteTitle || !noteBody

useEffect(() => {
if (
fetchNotes.state === 'idle' &&
fetchNotes.data === null &&
noteRef.current
) {
noteRef.current.reset()
}
}, [fetchNotes.state, fetchNotes.data])

return (
<div>
Expand Down Expand Up @@ -163,6 +203,36 @@ export default function () {
</FormGroup>
</fetcher.Form>
</Grid>
<Grid tablet={{ col: true }} className="bg-primary-lighter">
<h2 className="text-center">Take Notes:</h2>
<fetchNotes.Form method="POST" className="margin-2" ref={noteRef}>
<input hidden name="intent" defaultValue="new-note" />
<Label htmlFor="title">Title</Label>
<TextInput
type="text"
id="title"
name="title"
placeholder="Title"
onChange={(e) => {
setNoteTitle(e.target.value)
}}
/>
<Label htmlFor="notes">Notes</Label>
<Textarea
id="notes"
name="notes"
placeholder="Notes"
onChange={(e) => {
setNoteBody(e.target.value)
}}
/>
<FormGroup>
<Button type="submit" disabled={shouldDisableNotes}>
Submit
</Button>
</FormGroup>
</fetchNotes.Form>
</Grid>
</Grid>
<hr></hr>
<Grid row>
Expand All @@ -179,6 +249,20 @@ export default function () {
)
})}
</Grid>
<Grid
tablet={{ col: true }}
className="bg-base-lightest margin-bottom-5"
>
<h2 className="margin-left-2">Notes:</h2>
<ul>
{notes &&
notes.map((x) => (
<li key={x.noteId}>
<Link to={`/notes/${x.noteId}`}>{x.noteTitle}</Link>
</li>
))}
</ul>
</Grid>
</Grid>
</GridContainer>
</div>
Expand Down
33 changes: 33 additions & 0 deletions app/routes/data/data.server.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { tables } from '@architect/functions'
import { v4 as uuidv4 } from 'uuid'

async function fetchData(
instrument: string,
format: string,
Expand Down Expand Up @@ -51,3 +54,33 @@ export async function getInstrumentData(
console.log(error)
}
}

export async function createNewNote(
noteTitle: string,
noteBody: string,
userId: string
) {
const db = await tables()
const noteId = uuidv4()

await db.notes.put({
userId,
noteId,
noteTitle,
noteBody,
})
}

export async function getNotes(userId: string) {
const db = await tables()
const results = await db.notes.query({
KeyConditionExpression: '#userId = :userId',
ExpressionAttributeNames: {
'#userId': 'userId',
},
ExpressionAttributeValues: {
':userId': userId,
},
})
return results.Items
}

0 comments on commit 4476e7e

Please sign in to comment.