Merge pull request 'feat: update row actions to include payment functionality and add corresponding icon' (#74) from dev into production
Reviewed-on: #74
This commit was merged in pull request #74.
This commit is contained in:
@@ -160,7 +160,7 @@ export function OrdersClient() {
|
|||||||
visible: (target) => target.status === 'Printed',
|
visible: (target) => target.status === 'Printed',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
action: 'edit',
|
action: 'pay',
|
||||||
label: 'Record payment',
|
label: 'Record payment',
|
||||||
onClick: handleRecordPayment,
|
onClick: handleRecordPayment,
|
||||||
visible: (target) => target.paymentStatus !== 'Paid',
|
visible: (target) => target.paymentStatus !== 'Paid',
|
||||||
|
|||||||
@@ -133,4 +133,46 @@
|
|||||||
.react-grid-item > .react-resizable-handle::after {
|
.react-grid-item > .react-resizable-handle::after {
|
||||||
border-right-color: var(--muted-foreground);
|
border-right-color: var(--muted-foreground);
|
||||||
border-bottom-color: var(--muted-foreground);
|
border-bottom-color: var(--muted-foreground);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Top loading strip: thin bar sliding across with a neon-red leading dot. */
|
||||||
|
.top-loader {
|
||||||
|
pointer-events: none;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
height: 2px;
|
||||||
|
overflow: visible;
|
||||||
|
z-index: 50;
|
||||||
|
}
|
||||||
|
.top-loader__bar {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background: linear-gradient(
|
||||||
|
90deg,
|
||||||
|
transparent 0%,
|
||||||
|
rgba(255, 60, 90, 0.35) 55%,
|
||||||
|
rgba(255, 90, 120, 0.9) 90%,
|
||||||
|
#ff2e63 100%
|
||||||
|
);
|
||||||
|
transform: translateX(-100%);
|
||||||
|
animation: top-loader-slide 1.2s cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
||||||
|
}
|
||||||
|
.top-loader__head {
|
||||||
|
position: absolute;
|
||||||
|
right: -4px;
|
||||||
|
top: -2px;
|
||||||
|
height: 6px;
|
||||||
|
width: 10px;
|
||||||
|
border-radius: 9999px;
|
||||||
|
background: #ff6b8a;
|
||||||
|
box-shadow:
|
||||||
|
0 0 6px 1px #ff2e63,
|
||||||
|
0 0 14px 2px rgba(255, 46, 99, 0.75),
|
||||||
|
0 0 24px 4px rgba(255, 46, 99, 0.35);
|
||||||
|
}
|
||||||
|
@keyframes top-loader-slide {
|
||||||
|
0% { transform: translateX(-100%); }
|
||||||
|
100% { transform: translateX(100%); }
|
||||||
}
|
}
|
||||||
@@ -13,7 +13,8 @@ export type RowActionKind =
|
|||||||
| 'cancel'
|
| 'cancel'
|
||||||
| 'print'
|
| 'print'
|
||||||
| 'finalize'
|
| 'finalize'
|
||||||
| 'generate';
|
| 'generate'
|
||||||
|
| 'pay';
|
||||||
|
|
||||||
export interface BadgeConfig {
|
export interface BadgeConfig {
|
||||||
colorMap?: Record<string, string>;
|
colorMap?: Record<string, string>;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
import { HugeiconsIcon } from "@hugeicons/react"
|
import { HugeiconsIcon } from "@hugeicons/react"
|
||||||
import {
|
import {
|
||||||
|
AddMoneyCircleIcon,
|
||||||
Cancel01Icon,
|
Cancel01Icon,
|
||||||
CheckmarkCircle02Icon,
|
CheckmarkCircle02Icon,
|
||||||
CheckmarkSquare01Icon,
|
CheckmarkSquare01Icon,
|
||||||
@@ -24,6 +25,7 @@ const ACTION_ICONS = {
|
|||||||
edit: PencilEdit01Icon,
|
edit: PencilEdit01Icon,
|
||||||
finalize: CheckmarkSquare01Icon,
|
finalize: CheckmarkSquare01Icon,
|
||||||
generate: CheckmarkSquare01Icon,
|
generate: CheckmarkSquare01Icon,
|
||||||
|
pay: AddMoneyCircleIcon,
|
||||||
print: PrinterIcon,
|
print: PrinterIcon,
|
||||||
view: EyeIcon,
|
view: EyeIcon,
|
||||||
} as const
|
} as const
|
||||||
|
|||||||
@@ -1,44 +1,29 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
export function TopLoader({ active }: { active: boolean }) {
|
import { useEffect, useState } from 'react'
|
||||||
if (!active) return null
|
|
||||||
|
/**
|
||||||
|
* Thin top strip shown while `active` is true. Stays visible for at least
|
||||||
|
* `minDurationMs` so quick fetches don't produce an invisible flicker.
|
||||||
|
*/
|
||||||
|
export function TopLoader({ active, minDurationMs = 350 }: { active: boolean; minDurationMs?: number }) {
|
||||||
|
const [visible, setVisible] = useState(active)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (active) {
|
||||||
|
setVisible(true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const t = setTimeout(() => setVisible(false), minDurationMs)
|
||||||
|
return () => clearTimeout(t)
|
||||||
|
}, [active, minDurationMs])
|
||||||
|
|
||||||
|
if (!visible) return null
|
||||||
return (
|
return (
|
||||||
<div className="pointer-events-none absolute inset-x-0 top-0 h-[2px] overflow-hidden">
|
<div className="top-loader">
|
||||||
<div className="top-loader-bar">
|
<div className="top-loader__bar">
|
||||||
<span className="top-loader-head" />
|
<span className="top-loader__head" />
|
||||||
</div>
|
</div>
|
||||||
<style jsx>{`
|
|
||||||
.top-loader-bar {
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
background: linear-gradient(
|
|
||||||
90deg,
|
|
||||||
transparent 0%,
|
|
||||||
rgba(255, 60, 90, 0.45) 50%,
|
|
||||||
rgba(255, 90, 120, 0.9) 85%,
|
|
||||||
#ff2e63 100%
|
|
||||||
);
|
|
||||||
transform: translateX(-100%);
|
|
||||||
animation: top-loader-slide 1.1s cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
||||||
}
|
|
||||||
.top-loader-head {
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
top: -2px;
|
|
||||||
height: 6px;
|
|
||||||
width: 10px;
|
|
||||||
border-radius: 9999px;
|
|
||||||
background: #ff6b8a;
|
|
||||||
box-shadow:
|
|
||||||
0 0 6px 1px #ff2e63,
|
|
||||||
0 0 14px 2px rgba(255, 46, 99, 0.75),
|
|
||||||
0 0 24px 4px rgba(255, 46, 99, 0.35);
|
|
||||||
}
|
|
||||||
@keyframes top-loader-slide {
|
|
||||||
0% { transform: translateX(-100%); }
|
|
||||||
100% { transform: translateX(100%); }
|
|
||||||
}
|
|
||||||
`}</style>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user