Update Dockerfile and SimDetailsCard component for compatibility and enhancements
- Updated Prisma client generation command in Dockerfile to use version 6.14.0 for consistency. - Refactored SimDetailsCard component to improve type handling and UI elements, including re-exporting SimDetails for backwards compatibility. - Adjusted display logic for SIM details, including changes to how plan types and service dates are presented. - Enhanced button states in SimManagementSection for better clarity on invoice payment status. - Added reissueEsim method in sim-actions.service for handling eSIM reissue requests. - Introduced CatalogPriceInfo type in domain catalog for improved type definitions.
This commit is contained in:
parent
9fb54fd0fc
commit
c397eb51c7
@ -106,7 +106,7 @@ COPY --from=builder /app/apps/bff/prisma ./apps/bff/prisma
|
||||
|
||||
# Generate Prisma client in production environment
|
||||
WORKDIR /app/apps/bff
|
||||
RUN pnpm dlx prisma generate
|
||||
RUN pnpm dlx prisma@6.14.0 generate
|
||||
|
||||
# Strip build toolchain to shrink image
|
||||
RUN apk del --no-cache python3 make g++ pkgconfig && rm -rf /root/.cache /var/cache/apk/*
|
||||
|
||||
@ -10,6 +10,10 @@ import {
|
||||
ExclamationTriangleIcon,
|
||||
XCircleIcon,
|
||||
} from "@heroicons/react/24/outline";
|
||||
import type { SimDetails } from "@customer-portal/domain/sim";
|
||||
|
||||
// Re-export for backwards compatibility
|
||||
export type { SimDetails };
|
||||
|
||||
// Inline formatPlanShort function
|
||||
function formatPlanShort(planCode?: string): string {
|
||||
@ -26,33 +30,6 @@ function formatPlanShort(planCode?: string): string {
|
||||
return planCode;
|
||||
}
|
||||
|
||||
export interface SimDetails {
|
||||
account: string;
|
||||
msisdn: string;
|
||||
iccid?: string;
|
||||
imsi?: string;
|
||||
eid?: string;
|
||||
planCode: string;
|
||||
status: "active" | "suspended" | "cancelled" | "pending";
|
||||
simType: "physical" | "esim";
|
||||
size: "standard" | "nano" | "micro" | "esim";
|
||||
hasVoice: boolean;
|
||||
hasSms: boolean;
|
||||
remainingQuotaKb: number;
|
||||
remainingQuotaMb: number;
|
||||
startDate?: string;
|
||||
ipv4?: string;
|
||||
ipv6?: string;
|
||||
voiceMailEnabled?: boolean;
|
||||
callWaitingEnabled?: boolean;
|
||||
internationalRoamingEnabled?: boolean;
|
||||
networkType?: string;
|
||||
pendingOperations?: Array<{
|
||||
operation: string;
|
||||
scheduledDate: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
interface SimDetailsCardProps {
|
||||
simDetails: SimDetails;
|
||||
isLoading?: boolean;
|
||||
@ -292,7 +269,7 @@ export function SimDetailsCard({
|
||||
<div>
|
||||
<h3 className="text-lg font-medium text-gray-900">Physical SIM Details</h3>
|
||||
<p className="text-sm text-gray-500">
|
||||
{formatPlan(simDetails.planCode)} • {`${simDetails.size} SIM`}
|
||||
{formatPlan(simDetails.planCode)} • {`${simDetails.simType} SIM`}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -321,12 +298,10 @@ export function SimDetailsCard({
|
||||
<p className="text-sm font-medium text-gray-900">{simDetails.msisdn}</p>
|
||||
</div>
|
||||
|
||||
{simDetails.simType === "physical" && (
|
||||
<div>
|
||||
<label className="text-xs text-gray-500">ICCID</label>
|
||||
<p className="text-sm font-mono text-gray-900 break-all">{simDetails.iccid}</p>
|
||||
</div>
|
||||
)}
|
||||
<div>
|
||||
<label className="text-xs text-gray-500">ICCID</label>
|
||||
<p className="text-sm font-mono text-gray-900 break-all">{simDetails.iccid}</p>
|
||||
</div>
|
||||
|
||||
{simDetails.eid && (
|
||||
<div>
|
||||
@ -342,10 +317,10 @@ export function SimDetailsCard({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{simDetails.startDate && (
|
||||
{simDetails.activatedAt && (
|
||||
<div>
|
||||
<label className="text-xs text-gray-500">Service Start Date</label>
|
||||
<p className="text-sm text-gray-900">{formatDate(simDetails.startDate)}</p>
|
||||
<p className="text-sm text-gray-900">{formatDate(simDetails.activatedAt)}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@ -368,37 +343,32 @@ export function SimDetailsCard({
|
||||
<div className="flex items-center space-x-4">
|
||||
<div className="flex items-center">
|
||||
<SignalIcon
|
||||
className={`h-4 w-4 mr-1 ${simDetails.hasVoice ? "text-green-500" : "text-gray-400"}`}
|
||||
className={`h-4 w-4 mr-1 ${simDetails.voiceMailEnabled ? "text-green-500" : "text-gray-400"}`}
|
||||
/>
|
||||
<span
|
||||
className={`text-sm ${simDetails.hasVoice ? "text-green-600" : "text-gray-500"}`}
|
||||
className={`text-sm ${simDetails.voiceMailEnabled ? "text-green-600" : "text-gray-500"}`}
|
||||
>
|
||||
Voice {simDetails.hasVoice ? "Enabled" : "Disabled"}
|
||||
Voicemail {simDetails.voiceMailEnabled ? "Enabled" : "Disabled"}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<DevicePhoneMobileIcon
|
||||
className={`h-4 w-4 mr-1 ${simDetails.hasSms ? "text-green-500" : "text-gray-400"}`}
|
||||
className={`h-4 w-4 mr-1 ${simDetails.callWaitingEnabled ? "text-green-500" : "text-gray-400"}`}
|
||||
/>
|
||||
<span
|
||||
className={`text-sm ${simDetails.hasSms ? "text-green-600" : "text-gray-500"}`}
|
||||
className={`text-sm ${simDetails.callWaitingEnabled ? "text-green-600" : "text-gray-500"}`}
|
||||
>
|
||||
SMS {simDetails.hasSms ? "Enabled" : "Disabled"}
|
||||
Call Waiting {simDetails.callWaitingEnabled ? "Enabled" : "Disabled"}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{(simDetails.ipv4 || simDetails.ipv6) && (
|
||||
<div>
|
||||
<label className="text-xs text-gray-500">IP Address</label>
|
||||
<div className="space-y-1">
|
||||
{simDetails.ipv4 && (
|
||||
<p className="text-sm font-mono text-gray-900">IPv4: {simDetails.ipv4}</p>
|
||||
)}
|
||||
{simDetails.ipv6 && (
|
||||
<p className="text-sm font-mono text-gray-900">IPv6: {simDetails.ipv6}</p>
|
||||
)}
|
||||
</div>
|
||||
{simDetails.internationalRoamingEnabled && (
|
||||
<div className="flex items-center">
|
||||
<WifiIcon className="h-4 w-4 mr-1 text-green-500" />
|
||||
<span className="text-sm text-green-600">
|
||||
International Roaming Enabled
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@ -406,21 +376,14 @@ export function SimDetailsCard({
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Pending Operations */}
|
||||
{simDetails.pendingOperations && simDetails.pendingOperations.length > 0 && (
|
||||
{/* Expiry Date */}
|
||||
{simDetails.expiresAt && (
|
||||
<div className="mt-6 pt-6 border-t border-gray-200">
|
||||
<h4 className="text-sm font-medium text-gray-500 uppercase tracking-wider mb-3">
|
||||
Pending Operations
|
||||
</h4>
|
||||
<div className="bg-blue-50 rounded-lg p-4">
|
||||
{simDetails.pendingOperations.map((operation, index) => (
|
||||
<div key={index} className="flex items-center text-sm">
|
||||
<ClockIcon className="h-4 w-4 text-blue-500 mr-2" />
|
||||
<span className="text-blue-800">
|
||||
{operation.operation} scheduled for {formatDate(operation.scheduledDate)}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
<div className="flex items-center text-sm">
|
||||
<ClockIcon className="h-4 w-4 text-amber-500 mr-2" />
|
||||
<span className="text-amber-800">
|
||||
Expires on {formatDate(simDetails.expiresAt)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@ -223,10 +223,10 @@ export function SimManagementSection({ subscriptionId }: SimManagementSectionPro
|
||||
</p>
|
||||
<button
|
||||
onClick={handlePayInvoice}
|
||||
disabled={createSsoLink.isPending || latestInvoice.status === 'paid'}
|
||||
disabled={createSsoLink.isPending || latestInvoice.status === 'Paid'}
|
||||
className="w-full px-4 py-2 bg-blue-600 text-white text-sm font-semibold rounded-lg hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors"
|
||||
>
|
||||
{latestInvoice.status === 'paid' ? 'PAID' : createSsoLink.isPending ? 'Loading...' : 'PAY'}
|
||||
{latestInvoice.status === 'Paid' ? 'PAID' : createSsoLink.isPending ? 'Loading...' : 'PAY'}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@ -4,6 +4,7 @@ import type {
|
||||
SimTopUpRequest,
|
||||
SimPlanChangeRequest,
|
||||
SimCancelRequest,
|
||||
SimReissueRequest,
|
||||
} from "@customer-portal/domain/sim";
|
||||
|
||||
// Types imported from domain - no duplication
|
||||
@ -45,4 +46,11 @@ export const simActionsService = {
|
||||
|
||||
return simInfoSchema.parse(response.data);
|
||||
},
|
||||
|
||||
async reissueEsim(subscriptionId: string, request: SimReissueRequest): Promise<void> {
|
||||
await apiClient.POST("/api/subscriptions/{subscriptionId}/sim/reissue-esim", {
|
||||
params: { path: { subscriptionId } },
|
||||
body: request,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
@ -11,6 +11,7 @@ export {
|
||||
type SalesforceProductFieldMap,
|
||||
type PricingTier,
|
||||
type CatalogFilter,
|
||||
type CatalogPriceInfo,
|
||||
} from "./contract";
|
||||
|
||||
// Schemas (includes derived types)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user