1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-08-09 07:25:19 +02:00

update and fix merge conflict

This commit is contained in:
Tyler Myracle 2024-01-15 11:00:31 -06:00
commit 004a94f48e
10 changed files with 66 additions and 192 deletions

View file

@ -21,8 +21,6 @@ NX_FINICITY_PARTNER_SECRET=
NX_TELLER_SIGNING_SECRET=
NX_TELLER_APP_ID=
NEXT_PUBLIC_ZAPIER_FEEDBACK_HOOK_URL=
# Email credentials
NX_POSTMARK_FROM_ADDRESS=account@example.com
NX_POSTMARK_REPLY_TO_ADDRESS=support@example.com

40
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View file

@ -0,0 +1,40 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

View file

@ -0,0 +1,19 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View file

@ -187,7 +187,9 @@ export default function AccountsSidebar() {
label={title}
balances={balances.data}
inverted={classification === 'liability'}
onToggle={(isExpanded) => updateToggleState(title, isExpanded)}
onToggle={(isExpanded) =>
updateToggleState(`${title}-${classification}`, isExpanded)
}
expanded={toggleState[title] !== false}
level={1}
syncing={items.some((a) => a.syncing)}

View file

@ -1,62 +0,0 @@
import Link from 'next/link'
import { useUserApi } from '@maybe-finance/client/shared'
import { Button } from '@maybe-finance/design-system'
import toast from 'react-hot-toast'
import { signOut } from 'next-auth/react'
export function CountryWaitlist({ country }: { country?: string }) {
const { useDelete } = useUserApi()
const deleteUser = useDelete({
onSuccess() {
toast.success(`Account deleted`)
setTimeout(() => signOut(), 500)
},
onError() {
toast.error(`Error deleting account`)
},
})
return (
<div className="w-full max-w-md mx-auto">
<h3 className="text-center">
Unfortunately we're only accepting users from the US for now
</h3>
<div className="mt-4 space-y-4 text-base text-gray-50">
<p>We hate doing this, but for now were only accepting users from the US. Why?</p>
<p>
Well besides not being able to automatically connect to your institution, our
financial advisors wouldnt be able to give you relevant localized advice and
would likely breach some regulations.
</p>
<p>
That being said, we do plan on expanding Maybe to other countries soon. So well
let you know via email once we launch Maybe in {country || 'your country'}.
</p>
</div>
<Link href="https://maybe.co" passHref>
<Button as="a" fullWidth className="mt-8">
Got it
</Button>
</Link>
<Button
variant="warn"
fullWidth
className="mt-4"
disabled={deleteUser.isLoading}
onClick={() => {
if (
// eslint-disable-next-line
confirm(
'Are you sure you want to delete your account? This cannot be undone.'
)
) {
deleteUser.mutate({})
}
}}
>
{deleteUser.isLoading ? 'Deleting account...' : 'Delete my account'}
</Button>
</div>
)
}

View file

@ -29,7 +29,6 @@ import type { StepProps } from './StepProps'
import { Switch } from '@headlessui/react'
import { BrowserUtil, useUserApi } from '@maybe-finance/client/shared'
import type { Household, MaybeGoal } from '@prisma/client'
import { CountryWaitlist } from './CountryWaitlist'
import { DateUtil, Geo } from '@maybe-finance/shared'
type FormValues = {
@ -73,7 +72,7 @@ export function Profile({ title, onNext }: StepProps) {
dob: data.dob,
household: data.household,
country: data.country,
state: data.country === 'US' ? data.state : null, // should be NULL if country is not US
state: null, // should always be null for now
maybeGoals: data.maybeGoals,
maybeGoalsDescription: data.maybeGoalsDescription,
})
@ -108,7 +107,6 @@ function ProfileForm({ title, onSubmit, defaultValues }: ProfileViewProps) {
})
const country = watch('country')
const [showCountryWaitlist, setShowCountryWaitlist] = useState(false)
useEffect(() => {
trigger()
@ -116,9 +114,7 @@ function ProfileForm({ title, onSubmit, defaultValues }: ProfileViewProps) {
const { errors } = useFormState({ control })
return showCountryWaitlist ? (
<CountryWaitlist country={Geo.countries.find((c) => c.code === country)?.name} />
) : (
return (
<div className="w-full max-w-md mx-auto">
<h3 className="text-center">{title}</h3>
<p className="mt-4 text-base text-gray-50">
@ -211,18 +207,12 @@ function ProfileForm({ title, onSubmit, defaultValues }: ProfileViewProps) {
<Question
open={currentQuestion === 'residence'}
valid={!errors.country && (!errors.state || country !== 'US')}
valid={!errors.country}
icon={RiMapPin2Line}
label="Where are you based?"
onClick={() => setCurrentQuestion('residence')}
back={() => setCurrentQuestion('household')}
next={() => {
if (country === 'US') {
setCurrentQuestion('goals')
} else {
setShowCountryWaitlist(true)
}
}}
next={() => setCurrentQuestion('goals')}
>
<div className="space-y-2">
<Controller
@ -246,29 +236,6 @@ function ProfileForm({ title, onSubmit, defaultValues }: ProfileViewProps) {
</Listbox>
)}
/>
{country === 'US' && (
<Controller
name="state"
control={control}
rules={{ required: true }}
render={({ field }) => (
<Listbox {...field}>
<Listbox.Button label="State">
{Geo.states.find((s) => s.code === field.value)?.name ||
'Select'}
</Listbox.Button>
<Listbox.Options className="max-h-[300px] custom-gray-scroll">
{Geo.states.map((state) => (
<Listbox.Option key={state.code} value={state.code}>
{state.name}
</Listbox.Option>
))}
</Listbox.Options>
</Listbox>
)}
/>
)}
</div>
<Tooltip
placement="bottom-start"

View file

@ -1,74 +0,0 @@
import { useSession } from 'next-auth/react'
import { Button, Dialog } from '@maybe-finance/design-system'
import { useState } from 'react'
import axios from 'axios'
import toast from 'react-hot-toast'
export interface FeedbackDialogProps {
isOpen: boolean
onClose: () => void
notImplementedNotice?: boolean
}
export function FeedbackDialog({ isOpen, onClose, notImplementedNotice }: FeedbackDialogProps) {
const [feedback, setFeedback] = useState('')
const { data: session } = useSession()
return (
<Dialog isOpen={isOpen} onClose={onClose}>
<Dialog.Title>Send us your feedback!</Dialog.Title>
<Dialog.Content>
{notImplementedNotice ? (
<p className="text-sm text-white mb-6">
This feature has not been implemented yet, but is coming soon! Mind helping
us out and telling us what you want with this particular feature below?
</p>
) : (
<p className="text-sm text-gray-100 mb-6">
Maybe is built in public and relies heavily on user feedback. We'd love to
hear what you think could be better (please be constructive, we're still in
the early days!{' '}
<span role="img" aria-label="happy emoji">
😄
</span>
)
</p>
)}
<form
onSubmit={async (e) => {
e.preventDefault()
try {
await axios
.create({ transformRequest: [(data) => JSON.stringify(data)] })
.post(
process.env.NEXT_PUBLIC_ZAPIER_FEEDBACK_HOOK_URL ||
'REPLACE_THIS',
{
comment: `**From user:** ${session?.user?.email}\n\n${feedback}`,
page: `**Main app feedback**: ${window.location.href}`,
}
)
toast.success('Your feedback was submitted!')
} catch (e) {
toast.error('Feedback not submitted')
}
onClose()
}}
>
<textarea
value={feedback}
onChange={(e) => setFeedback(e.target.value)}
className="w-full rounded bg-gray-500 text-base border-0 focus:ring focus:ring-opacity-60 focus:ring-cyan"
rows={6}
></textarea>
<Button className="mt-4" type="submit" disabled={feedback.length < 10}>
Submit
</Button>
</form>
</Dialog.Content>
</Dialog>
)
}

View file

@ -1,2 +1 @@
export * from './FeedbackDialog'
export * from './NonUSDDialog'

View file

@ -1,14 +0,0 @@
import { Button } from '@maybe-finance/design-system'
import { useState } from 'react'
import { FeedbackDialog } from '../dialogs'
export function FeedbackButton() {
const [isOpen, setIsOpen] = useState(false)
return (
<div className="mt-6 text-center">
<Button onClick={() => setIsOpen(true)}>Send us your feedback</Button>
<FeedbackDialog isOpen={isOpen} onClose={() => setIsOpen(false)} />
</div>
)
}

View file

@ -1,4 +1,3 @@
export * from './FeedbackButton'
export * from './TrendBadge'
export * from './Toaster'
export * from './BoxIcon'