Compare commits

..

No commits in common. "1391e2d2f58dd1016171209e03f2e88c2cccd3de" and "b9a8c5bf523521d0b5be4fe9a347a6dc343d7e5b" have entirely different histories.

3 changed files with 149 additions and 194 deletions

View File

@ -234,6 +234,10 @@ function AppRoutes({ onLogout }: AppProps) {
setDynamicRequests([...dynamicRequests, newCustomRequest]); setDynamicRequests([...dynamicRequests, newCustomRequest]);
navigate('/my-requests'); navigate('/my-requests');
toast.success('Request Submitted Successfully!', {
description: `Your request "${requestData.title}" (${requestId}) has been created and sent for approval.`,
duration: 5000,
});
}; };
const handleApprovalSubmit = (action: 'approve' | 'reject', _comment: string) => { const handleApprovalSubmit = (action: 'approve' | 'reject', _comment: string) => {

View File

@ -59,29 +59,23 @@ export function TemplateSelectionStep({
className="w-full max-w-6xl grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8" className="w-full max-w-6xl grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8"
data-testid="template-selection-grid" data-testid="template-selection-grid"
> >
{templates.map((template) => { {templates.map((template) => (
const isComingSoon = template.id === 'existing-template'; <motion.div
const isDisabled = isComingSoon; key={template.id}
whileHover={{ scale: 1.03 }}
return ( whileTap={{ scale: 0.98 }}
<motion.div transition={{ type: "spring", stiffness: 300, damping: 20 }}
key={template.id} data-testid={`template-card-${template.id}`}
whileHover={!isDisabled ? { scale: 1.03 } : {}} >
whileTap={!isDisabled ? { scale: 0.98 } : {}} <Card
transition={{ type: "spring", stiffness: 300, damping: 20 }} className={`cursor-pointer h-full transition-all duration-300 border-2 ${
data-testid={`template-card-${template.id}`} selectedTemplate?.id === template.id
? 'border-blue-500 shadow-xl bg-blue-50/50 ring-2 ring-blue-200'
: 'border-gray-200 hover:border-blue-300 hover:shadow-lg'
}`}
onClick={() => onSelectTemplate(template)}
data-testid={`template-card-${template.id}-clickable`}
> >
<Card
className={`h-full transition-all duration-300 border-2 ${
isDisabled
? 'border-gray-200 bg-gray-50/50 opacity-85 cursor-not-allowed'
: selectedTemplate?.id === template.id
? 'border-blue-500 shadow-xl bg-blue-50/50 ring-2 ring-blue-200 cursor-pointer'
: 'border-gray-200 hover:border-blue-300 hover:shadow-lg cursor-pointer'
}`}
onClick={!isDisabled ? () => onSelectTemplate(template) : undefined}
data-testid={`template-card-${template.id}-clickable`}
>
<CardHeader className="space-y-4 pb-4"> <CardHeader className="space-y-4 pb-4">
<div className="flex items-start justify-between"> <div className="flex items-start justify-between">
<div <div
@ -114,20 +108,9 @@ export function TemplateSelectionStep({
)} )}
</div> </div>
<div className="text-left"> <div className="text-left">
<div className="flex items-start justify-between gap-2 mb-2"> <CardTitle className="text-xl mb-2" data-testid={`template-card-${template.id}-name`}>
<CardTitle className="text-xl" data-testid={`template-card-${template.id}-name`}> {template.name}
{template.name} </CardTitle>
</CardTitle>
{isComingSoon && (
<Badge
variant="outline"
className="text-xs bg-yellow-100 text-yellow-700 border-yellow-300 font-semibold"
data-testid={`template-card-${template.id}-coming-soon-badge`}
>
Coming Soon
</Badge>
)}
</div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Badge variant="secondary" className="text-xs" data-testid={`template-card-${template.id}-category`}> <Badge variant="secondary" className="text-xs" data-testid={`template-card-${template.id}-category`}>
{template.category} {template.category}
@ -157,8 +140,7 @@ export function TemplateSelectionStep({
</CardContent> </CardContent>
</Card> </Card>
</motion.div> </motion.div>
); ))}
})}
</div> </div>
{/* Template Details Card */} {/* Template Details Card */}

View File

@ -3,7 +3,6 @@
*/ */
import { useState } from 'react'; import { useState } from 'react';
import { toast } from 'sonner';
import { FormData, RequestTemplate } from '@/hooks/useCreateRequestForm'; import { FormData, RequestTemplate } from '@/hooks/useCreateRequestForm';
import { import {
buildCreatePayload, buildCreatePayload,
@ -73,12 +72,6 @@ export function useCreateRequestSubmission({
documentsToDelete documentsToDelete
); );
// Show toast after backend confirmation
toast.success('Request Submitted Successfully!', {
description: `Your request "${formData.title}" has been submitted and sent for approval.`,
duration: 5000,
});
onSubmit?.({ onSubmit?.({
...formData, ...formData,
backendId: editRequestId, backendId: editRequestId,
@ -94,24 +87,14 @@ export function useCreateRequestSubmission({
const result = await createAndSubmitWorkflow(createPayload, documents); const result = await createAndSubmitWorkflow(createPayload, documents);
// Show toast after backend confirmation
toast.success('Request Submitted Successfully!', {
description: `Your request "${formData.title}" has been created and sent for approval.`,
duration: 5000,
});
onSubmit?.({ onSubmit?.({
...formData, ...formData,
backendId: result.id, backendId: result.id,
template: selectedTemplate, template: selectedTemplate,
}); });
} }
} catch (error: any) { } catch (error) {
console.error('Failed to submit workflow:', error); console.error('Failed to submit workflow:', error);
toast.error('Failed to Submit Request', {
description: error?.response?.data?.message || error?.message || 'An error occurred while submitting the request.',
duration: 5000,
});
setSubmitting(false); setSubmitting(false);
} }
}; };
@ -147,11 +130,6 @@ export function useCreateRequestSubmission({
documentsToDelete documentsToDelete
); );
toast.success('Draft Saved Successfully!', {
description: `Your request "${formData.title}" has been saved as draft.`,
duration: 5000,
});
onSubmit?.({ onSubmit?.({
...formData, ...formData,
backendId: editRequestId, backendId: editRequestId,
@ -167,23 +145,14 @@ export function useCreateRequestSubmission({
const result = await createWorkflow(createPayload, documents); const result = await createWorkflow(createPayload, documents);
toast.success('Draft Saved Successfully!', {
description: `Your request "${formData.title}" has been saved as draft.`,
duration: 5000,
});
onSubmit?.({ onSubmit?.({
...formData, ...formData,
backendId: result.id, backendId: result.id,
template: selectedTemplate, template: selectedTemplate,
}); });
} }
} catch (error: any) { } catch (error) {
console.error('Failed to save draft:', error); console.error('Failed to save draft:', error);
toast.error('Failed to Save Draft', {
description: error?.response?.data?.message || error?.message || 'An error occurred while saving the draft.',
duration: 5000,
});
setSavingDraft(false); setSavingDraft(false);
} }
}; };