Compare commits
1 Commits
sgunter/fe
...
test-branc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
517fd4cc78 |
@@ -216,3 +216,5 @@ Special thanks to the developers and contributors behind these amazing tools and
|
|||||||
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=Longhorn-Developers/UT-Registration-Plus&type=Date" />
|
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=Longhorn-Developers/UT-Registration-Plus&type=Date" />
|
||||||
</picture>
|
</picture>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import ExtensionRoot from '@views/components/common/ExtensionRoot/ExtensionRoot';
|
|
||||||
import ReportIssueMain from '@views/components/ReportIssueMain';
|
import ReportIssueMain from '@views/components/ReportIssueMain';
|
||||||
import SentryProvider from '@views/contexts/SentryContext';
|
import SentryProvider from '@views/contexts/SentryContext';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
@@ -6,8 +5,6 @@ import { createRoot } from 'react-dom/client';
|
|||||||
|
|
||||||
createRoot(document.getElementById('root')!).render(
|
createRoot(document.getElementById('root')!).render(
|
||||||
<SentryProvider fullInit>
|
<SentryProvider fullInit>
|
||||||
<ExtensionRoot>
|
<ReportIssueMain />
|
||||||
<ReportIssueMain />
|
|
||||||
</ExtensionRoot>
|
|
||||||
</SentryProvider>
|
</SentryProvider>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -24,12 +24,6 @@ export interface IOptionsStore {
|
|||||||
|
|
||||||
/** whether the promo should be shown */
|
/** whether the promo should be shown */
|
||||||
showUTDiningPromo: boolean;
|
showUTDiningPromo: boolean;
|
||||||
|
|
||||||
/** whether the user's email address should be remembered by the extension */
|
|
||||||
rememberMyEmail: boolean;
|
|
||||||
|
|
||||||
/** the user's email address, if set and chosen to be remembered */
|
|
||||||
emailAddress: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const OptionsStore = createSyncStore<IOptionsStore>({
|
export const OptionsStore = createSyncStore<IOptionsStore>({
|
||||||
@@ -40,8 +34,6 @@ export const OptionsStore = createSyncStore<IOptionsStore>({
|
|||||||
alwaysOpenCalendarInNewTab: false,
|
alwaysOpenCalendarInNewTab: false,
|
||||||
showCalendarSidebar: true,
|
showCalendarSidebar: true,
|
||||||
showUTDiningPromo: true,
|
showUTDiningPromo: true,
|
||||||
rememberMyEmail: false,
|
|
||||||
emailAddress: '',
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -58,8 +50,6 @@ export const initSettings = async () =>
|
|||||||
alwaysOpenCalendarInNewTab: await OptionsStore.get('alwaysOpenCalendarInNewTab'),
|
alwaysOpenCalendarInNewTab: await OptionsStore.get('alwaysOpenCalendarInNewTab'),
|
||||||
showCalendarSidebar: await OptionsStore.get('showCalendarSidebar'),
|
showCalendarSidebar: await OptionsStore.get('showCalendarSidebar'),
|
||||||
showUTDiningPromo: await OptionsStore.get('showUTDiningPromo'),
|
showUTDiningPromo: await OptionsStore.get('showUTDiningPromo'),
|
||||||
rememberMyEmail: await OptionsStore.get('rememberMyEmail'),
|
|
||||||
emailAddress: await OptionsStore.get('emailAddress'),
|
|
||||||
}) satisfies IOptionsStore;
|
}) satisfies IOptionsStore;
|
||||||
|
|
||||||
// Clothing retailer right
|
// Clothing retailer right
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import 'uno.css';
|
import 'uno.css';
|
||||||
|
|
||||||
import { captureFeedback } from '@sentry/react';
|
import { captureFeedback } from '@sentry/react';
|
||||||
import { OptionsStore } from '@shared/storage/OptionsStore';
|
|
||||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
import { Button } from './common/Button';
|
import { Button } from './common/Button';
|
||||||
@@ -14,57 +12,19 @@ import Text from './common/Text/Text';
|
|||||||
* @returns The rendered component.
|
* @returns The rendered component.
|
||||||
*/
|
*/
|
||||||
export default function ReportIssueMain(): JSX.Element {
|
export default function ReportIssueMain(): JSX.Element {
|
||||||
const queryClient = useQueryClient();
|
const [email, setEmail] = useState('');
|
||||||
|
|
||||||
const { data: emailAddress } = useQuery({
|
|
||||||
queryKey: ['settings', 'emailAddress'],
|
|
||||||
queryFn: () => OptionsStore.get('emailAddress'),
|
|
||||||
staleTime: Infinity, // Prevent loading state on refocus
|
|
||||||
});
|
|
||||||
|
|
||||||
const { mutate: setEmailAddress } = useMutation({
|
|
||||||
mutationKey: ['settings', 'emailAddress'],
|
|
||||||
mutationFn: async ({ rememberMyEmail, emailAddress }: { rememberMyEmail: boolean; emailAddress: string }) => {
|
|
||||||
queryClient.setQueryData(['settings', 'emailAddress'], emailAddress);
|
|
||||||
if (rememberMyEmail) {
|
|
||||||
OptionsStore.set('emailAddress', emailAddress);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const { data: rememberMyEmail } = useQuery({
|
|
||||||
queryKey: ['settings', 'rememberMyEmail'],
|
|
||||||
queryFn: () => OptionsStore.get('rememberMyEmail'),
|
|
||||||
staleTime: Infinity, // Prevent loading state on refocus
|
|
||||||
});
|
|
||||||
|
|
||||||
const { mutate: setRememberMyEmail } = useMutation({
|
|
||||||
mutationKey: ['settings', 'rememberMyEmail'],
|
|
||||||
mutationFn: async ({ rememberMyEmail, emailAddress }: { rememberMyEmail: boolean; emailAddress: string }) => {
|
|
||||||
queryClient.setQueryData(['settings', 'rememberMyEmail'], rememberMyEmail);
|
|
||||||
OptionsStore.set('rememberMyEmail', rememberMyEmail);
|
|
||||||
|
|
||||||
if (rememberMyEmail) {
|
|
||||||
OptionsStore.set('emailAddress', emailAddress);
|
|
||||||
} else {
|
|
||||||
OptionsStore.set('emailAddress', '');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const [feedback, setFeedback] = useState('');
|
const [feedback, setFeedback] = useState('');
|
||||||
const [isSubmitted, setIsSubmitted] = useState(false);
|
const [isSubmitted, setIsSubmitted] = useState(false);
|
||||||
|
|
||||||
const submitFeedback = async () => {
|
const submitFeedback = async () => {
|
||||||
if (!emailAddress || !feedback) {
|
if (!email || !feedback) {
|
||||||
throw new Error('Email and feedback are required');
|
throw new Error('Email and feedback are required');
|
||||||
}
|
}
|
||||||
|
// Here you would typically send the feedback to a server
|
||||||
// Send the feedback to Sentry
|
await captureFeedback(
|
||||||
captureFeedback(
|
|
||||||
{
|
{
|
||||||
message: feedback || 'No feedback provided',
|
message: feedback || 'No feedback provided',
|
||||||
email: emailAddress,
|
email,
|
||||||
tags: {
|
tags: {
|
||||||
version: chrome.runtime.getManifest().version,
|
version: chrome.runtime.getManifest().version,
|
||||||
},
|
},
|
||||||
@@ -74,14 +34,16 @@ export default function ReportIssueMain(): JSX.Element {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// Close the dialog
|
// Reset form fields and close the dialog
|
||||||
|
setEmail('');
|
||||||
|
setFeedback('');
|
||||||
setIsSubmitted(true);
|
setIsSubmitted(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isSubmitted) {
|
if (isSubmitted) {
|
||||||
return (
|
return (
|
||||||
<div className='w-92 flex flex-col rounded-lg bg-white p-6 shadow-lg'>
|
<div className='w-80 flex flex-col rounded-lg bg-white p-6 shadow-lg'>
|
||||||
<Text variant='h2' className='my-4'>
|
<Text variant='h2' className='mb-4'>
|
||||||
Thank you
|
Thank you
|
||||||
</Text>
|
</Text>
|
||||||
<Text variant='p' className='mb-6'>
|
<Text variant='p' className='mb-6'>
|
||||||
@@ -94,13 +56,28 @@ export default function ReportIssueMain(): JSX.Element {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isSubmitted) {
|
||||||
|
return (
|
||||||
|
<div className='w-80 bg-white p-6'>
|
||||||
|
<h2 className='mb-4 text-2xl text-orange font-bold'>{`Hook'em Horns!`}</h2>
|
||||||
|
<p className='mb-6 text-gray-600'>Your feedback is music to our ears. Thanks for helping us improve!</p>
|
||||||
|
<button
|
||||||
|
className='w-full rounded bg-orange-600 px-4 py-2 text-white font-bold transition duration-300 hover:bg-orange-700'
|
||||||
|
onClick={() => window.close()}
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='w-92 bg-white p-6'>
|
<div className='w-80 bg-white p-6'>
|
||||||
<h2 className='my-4 text-2xl text-ut-burntorange font-bold'>Longhorn Feedback</h2>
|
<h2 className='mb-4 text-2xl text-ut-burntorange font-bold'>Longhorn Feedback</h2>
|
||||||
<p className='mb-4 text-sm text-ut-black'>Help us make UT Registration Plus even better!</p>
|
<p className='mb-4 text-sm text-ut-black'>Help us make UT Registration Plus even better!</p>
|
||||||
|
|
||||||
<form onSubmit={submitFeedback}>
|
<form onSubmit={submitFeedback}>
|
||||||
<div className='mb-1'>
|
<div className='mb-4'>
|
||||||
<label htmlFor='email' className='mb-1 block text-sm text-ut-black font-medium'>
|
<label htmlFor='email' className='mb-1 block text-sm text-ut-black font-medium'>
|
||||||
Your @utexas.edu email
|
Your @utexas.edu email
|
||||||
</label>
|
</label>
|
||||||
@@ -108,13 +85,8 @@ export default function ReportIssueMain(): JSX.Element {
|
|||||||
<input
|
<input
|
||||||
type='email'
|
type='email'
|
||||||
id='email'
|
id='email'
|
||||||
value={emailAddress}
|
value={email}
|
||||||
onChange={e =>
|
onChange={e => setEmail(e.target.value)}
|
||||||
setEmailAddress({
|
|
||||||
emailAddress: e.target.value,
|
|
||||||
rememberMyEmail: rememberMyEmail ?? false,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
className='w-full border border-gray-300 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-orange-500'
|
className='w-full border border-gray-300 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-orange-500'
|
||||||
placeholder='bevo@utexas.edu'
|
placeholder='bevo@utexas.edu'
|
||||||
required
|
required
|
||||||
@@ -122,23 +94,6 @@ export default function ReportIssueMain(): JSX.Element {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='mb-4'>
|
|
||||||
<label className='mb-1 flex cursor-pointer content-center gap-1.25 text-sm text-ut-black font-medium'>
|
|
||||||
<input
|
|
||||||
type='checkbox'
|
|
||||||
className='cursor-pointer'
|
|
||||||
checked={rememberMyEmail}
|
|
||||||
onChange={e =>
|
|
||||||
setRememberMyEmail({
|
|
||||||
rememberMyEmail: e.target.checked,
|
|
||||||
emailAddress: emailAddress ?? '',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/>{' '}
|
|
||||||
Remember my email
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='mb-4'>
|
<div className='mb-4'>
|
||||||
<label htmlFor='feedback' className='mb-1 block text-sm text-ut-black font-medium'>
|
<label htmlFor='feedback' className='mb-1 block text-sm text-ut-black font-medium'>
|
||||||
Your feedback
|
Your feedback
|
||||||
|
|||||||
Reference in New Issue
Block a user