feat(portal): pulse animation, repeat-order button, 5-panel dashboard

1. Pulse animation on the active step indicator:
   - New @keyframes fp-pulse-teal / fp-pulse-amber in stepper.scss
   - Applied to .o_fp_step_active / _warn and .o_fp_timeline_active
     .o_fp_timeline_dot so dashboard stepper + detail-page timeline
     breathe in sync. 1.8s ease-in-out, ring grows 4px -> 9px and
     fades 20% -> 6% opacity. Two color variants so QC (warn) keeps
     its amber meaning.
   - prefers-reduced-motion: reduce kills the animation for users
     who opted out.

2. Repeat Order button on /my/jobs/<id> detail page:
   - New POST /my/jobs/<id>/repeat route that creates a draft
     fusion.plating.quote.request seeded with the user's contact +
     the job's quantity, posts a chatter link back to the original
     job, redirects to the new RFQ for review/submit.
   - Button placed in the detail footer next to 'Back to all jobs',
     CSRF-protected via the form's csrf_token hidden field.

3. Dashboard expanded from 3 secondary panels to 5 (Recent Quote
   Requests + Recent Purchase Orders added) so every previously-
   designed customer page is reachable from /my/home.
   - Auto-fit grid: 3+2 / 2+2+1 / single column depending on width.
   - Every panel header gets a 'View all ->' link to its list page
     (Quote Requests / POs / Certs / Deliveries / Invoices).
   - Empty-state for Quote Requests gets an inline 'Get a quote ->'
     CTA so first-time customers know where to start.

Version bump: 19.0.3.4.0 -> 19.0.3.5.0.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-05-17 03:56:53 -04:00
parent ba6f39375a
commit 49013c64fb
7 changed files with 151 additions and 7 deletions

View File

@@ -148,13 +148,11 @@
.o_fp_secondary_panels {
display: grid;
grid-template-columns: repeat(3, 1fr);
// Auto-fit so 5 panels arrange nicely as 3+2 / 2+2+1 / 1 column at
// various widths instead of overflowing or cramping.
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: $fp-space-3;
@media (max-width: 768px) {
grid-template-columns: 1fr;
}
.o_fp_panel {
@extend .o_fp_card_compact;
@@ -178,6 +176,14 @@
justify-content: center;
font-size: .78rem;
}
.o_fp_panel_view_all {
margin-left: auto;
font-size: .7rem;
color: $fp-teal;
text-decoration: none;
font-weight: 500;
&:hover { color: $fp-teal-dark; }
}
}
.o_fp_panel_row {
font-size: .72rem;
@@ -185,5 +191,12 @@
margin-top: .2rem;
&:first-of-type { margin-top: 0; }
}
.o_fp_panel_inline_cta {
margin-left: .35rem;
color: $fp-teal;
text-decoration: none;
font-weight: 500;
&:hover { color: $fp-teal-dark; }
}
}
}

View File

@@ -36,6 +36,7 @@
color: $fp-teal;
border: 2.5px solid $fp-teal;
box-shadow: $fp-glow-ring-teal;
animation: fp-pulse-teal 1.8s ease-in-out infinite;
}
.o_fp_step_active_warn {
// Used when the active step is in QC (amber)
@@ -43,6 +44,30 @@
color: $fp-amber-text;
border: 2.5px solid $fp-amber;
box-shadow: $fp-glow-ring-amber;
animation: fp-pulse-amber 1.8s ease-in-out infinite;
}
}
// Pulsing glow for the active step indicator. Kept subtle - the ring
// breathes in width + fades; the inner dot stays still. Two color
// variants (teal for normal flow, amber for QC) so the warn state
// retains its meaning. Defined here, used in both fp_portal_stepper.scss
// and fp_portal_timeline.scss.
@keyframes fp-pulse-teal {
0%, 100% { box-shadow: 0 0 0 4px rgba(46, 175, 147, 0.20); }
50% { box-shadow: 0 0 0 9px rgba(46, 175, 147, 0.06); }
}
@keyframes fp-pulse-amber {
0%, 100% { box-shadow: 0 0 0 4px rgba(245, 158, 11, 0.20); }
50% { box-shadow: 0 0 0 9px rgba(245, 158, 11, 0.06); }
}
// Accessibility: kill the animation for users who've opted out of motion.
@media (prefers-reduced-motion: reduce) {
.o_fp_step_active,
.o_fp_step_active_warn,
.o_fp_timeline_active .o_fp_timeline_dot {
animation: none;
}
.o_fp_step_line {

View File

@@ -56,6 +56,10 @@
background: $fp-card-bg;
border: 2.5px solid $fp-teal;
box-shadow: $fp-glow-ring-teal;
// Pulsing glow defined in fp_portal_stepper.scss (@keyframes
// fp-pulse-teal) - reused here so the active timeline dot
// breathes in sync with the stepper circle on /my/home.
animation: fp-pulse-teal 1.8s ease-in-out infinite;
}
.o_fp_timeline_title {