Skip to content

Commit

Permalink
adds feedback widget
Browse files Browse the repository at this point in the history
  • Loading branch information
Stephen Cefali committed Jan 11, 2024
1 parent 6414320 commit 6fe9cb6
Show file tree
Hide file tree
Showing 9 changed files with 330 additions and 237 deletions.
2 changes: 1 addition & 1 deletion app/@/components/ui/input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
<input
type={type}
className={cn(
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 mt-4 max-w-md",
className
)}
ref={ref}
Expand Down
24 changes: 24 additions & 0 deletions app/@/components/ui/textarea.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as React from "react"

import { cn } from "app/@/lib/utils"

export interface TextareaProps
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}

const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
({ className, ...props }, ref) => {
return (
<textarea
className={cn(
"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 mt-4 max-w-md",
className
)}
ref={ref}
{...props}
/>
)
}
)
Textarea.displayName = "Textarea"

export { Textarea }
56 changes: 56 additions & 0 deletions app/components/feedback-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { Form, useLoaderData } from '@remix-run/react'
import { GrAnnounce } from 'react-icons/gr'
import * as Sentry from '@sentry/browser'
import { createPortal } from 'react-dom'

import { Button } from '~/@/components/ui/button'
import { Input } from '~/@/components/ui/input'
import { Textarea } from '~/@/components/ui/textarea'
import { useState } from 'react'

export default function FeedbackButton() {
const { user } = useLoaderData()
const [showModal, setShowModal] = useState(false)
return (
<>
{showModal &&
createPortal(
<div
className="fixed left-1/2 top-1/2 rounded-sm bg-accent p-8 "
style={{ transform: 'translate(-50%, -50%)', width: '320px' }}
>
<Form
className="m-auto flex flex-col"
onSubmit={event => {
event.preventDefault()
console.log(event.target)
const eventId = Sentry.captureMessage('User Feedback')
const userFeedback = {
event_id: eventId,
...event.target,
}
Sentry.captureUserFeedback(userFeedback)
setShowModal(false)
}}
>
<Input type="text" placeholder="Name" value={user.name} />
<Input type="email" placeholder="Email" value={user.email} />
<Textarea placeholder="Enter your feedback" />
<Button className="mt-4 max-w-md w-max" type="submit">
Submit
</Button>
</Form>
</div>,
document.body,
)}
<Button
className="gap-2"
type="button"
onClick={() => setShowModal(!showModal)}
>
<GrAnnounce />
Feedback
</Button>
</>
)
}
27 changes: 13 additions & 14 deletions app/components/github-contribution-summary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ function GithubContributionSummary({ userName, timePeriod }: Props) {
useEffect(() => {
// set up the metadata
streamArray.forEach(stream => {
console.log('stream', stream)
if (!stream) return
if (stream.action === 'metadata') {
setPrs(prevPrs => {
Expand Down Expand Up @@ -103,19 +102,19 @@ function GithubContributionSummary({ userName, timePeriod }: Props) {
}
if (prs.length) {
return prs.map(pr => (
<div key={pr.id} className="mt-4">
<div className="mt-4 whitespace-pre-wrap">
{new Date(pr.closedAt).toLocaleDateString()}
<div key={pr.id}>
<div className="flex gap-2">
{new Date(pr.closedAt).toLocaleDateString()}:
<a
className="text-blue-500 underline"
href={pr.link}
target="_blank"
rel="noopener noreferrer"
>
{pr.title}
</a>
</div>
<a
className="text-blue-500 underline"
href={pr.link}
target="_blank"
rel="noopener noreferrer"
>
{pr.title}
</a>
<div className="mt-2">{pr.summary}</div>
<div>{pr.summary}</div>
<br />
</div>
))
Expand All @@ -124,7 +123,7 @@ function GithubContributionSummary({ userName, timePeriod }: Props) {
return (
<div className="flex flex-col pt-4 text-left">
{error && <p className="text-red-500">{error}</p>}
<div className="mt-4 whitespace-pre-wrap">{renderContent()}</div>
<div className="whitespace-pre-wrap">{renderContent()}</div>
</div>
)
}
Expand Down
19 changes: 13 additions & 6 deletions app/routes/app.summary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import {
} from '~/@/components/ui/select.tsx'
import GithubContributionSummary from '~/components/github-contribution-summary.tsx'
import AppLayout from '~/components/app-layout'
import FeedbackButton from '~/components/feedback-button'
import { prisma } from '~/utils/db.server'

type ActionData =
| { status: 'error'; message: string }
Expand All @@ -46,7 +48,10 @@ export async function loader({ request }: DataFunctionArgs) {
if (!userId) {
return redirect('/github/install')
}
return null
const user = await prisma.user.findUniqueOrThrow({
where: { id: userId },
})
return { user }
}

export default function Summary() {
Expand All @@ -55,22 +60,24 @@ export default function Summary() {
const timePeriod = queryParams.get('timePeriod')
const navigation = useNavigation()
const submitting = navigation.state === 'submitting'
const disableButton = submitting
const disableButton = submitting;
return (
<AppLayout>
<Form
className="m-auto rounded-sm bg-secondary p-8 "
action="/app/summary"
method="GET"
>
<h1 className="text-lg font-bold">
See a Summary of Github Contributions
</h1>
<div className="flex justify-between ">
<h1 className="text-lg font-bold">
See a Summary of Github Contributions
</h1>
<FeedbackButton />
</div>
<Input
type="text"
placeholder="GitHub Username"
name="userName"
className="mt-4 max-w-md"
required
defaultValue={queryParams.get('userName') || ''}
/>
Expand Down
25 changes: 12 additions & 13 deletions app/utils/ai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,13 @@ export async function generateSummaryForPrs({
}) {
const prDataArray = await Promise.all(
prs.map(async pr => {
let diff = ''
// TODO: add comment data
if (pr?.pull_request?.diff_url) {
const response = await fetch(pr.pull_request.diff_url)
const diffText = await response.text()
diff = diffText.substring(0, MAX_DIFF_LENGTH)
}

// Add metadata related to the PR
const prContent = {
title: pr.title,
body: pr.body,
link: pr.html_url,
diff: diff,
id: pr.id,
diffUrl: pr?.pull_request?.diff_url,
closedAt: pr.closed_at as string, // we've already filtered out PRs that are open
}
return prContent
Expand All @@ -39,6 +31,16 @@ export async function generateSummaryForPrs({

return Promise.all(
prDataArray.map(async function* (pr) {
// load the diff if it's avaialable on-demand
let diff = ''
if (pr.diffUrl) {
const response = await fetch(pr.diffUrl)
const diffText = await response.text()
diff = diffText.substring(0, MAX_DIFF_LENGTH)
}

// TODO: add comment data

const prMetadata = {
action: 'metadata',
data: {
Expand All @@ -48,9 +50,7 @@ export async function generateSummaryForPrs({
closedAt: pr.closedAt,
},
} as const
console.log('prMetadata', prMetadata)
yield prMetadata
console.log('here')
// Construct the prompt for OpenAI
const prompt = `
Create a summary of this PR based on the JSON representation of the PR below.
Expand All @@ -64,10 +64,9 @@ export async function generateSummaryForPrs({
${JSON.stringify({
title: pr.title,
body: pr.body,
diff: pr.diff,
diff: diff,
})}`
const generator = createSimpleCompletion(prompt, userId)
console.log('ran complete')

// Generate the summary using OpenAI
while (true) {
Expand Down
11 changes: 11 additions & 0 deletions app/utils/monitoring.client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,18 @@ export function init() {
}),
// Replay is only available in the client
new Sentry.Replay(),
new Sentry.Feedback({
// Additional SDK configuration goes in here, for example:
colorScheme: 'dark',
}),
],
beforeSend(event, hint) {
// Check if it is an exception, and if so, show the report dialog
if (event.exception) {
Sentry.showReportDialog({ eventId: event.event_id })
}
return event
},

// Set tracesSampleRate to 1.0 to capture 100%
// of transactions for performance monitoring.
Expand Down
Loading

0 comments on commit 6fe9cb6

Please sign in to comment.