feat: add credit cards endpoint

This commit is contained in:
Matilda Landström
2024-06-18 15:48:50 +02:00
parent 9931d9edef
commit fa5638aaed
6 changed files with 79 additions and 2 deletions

View File

@@ -73,6 +73,7 @@ function getInitialState(user?: User) {
selectedLevelCDesktop: getLevelByTier(3),
}
}
if (!membership.membershipLevel) return null
const tier = membershipLevels[membership.membershipLevel]
switch (tier) {

View File

@@ -1,5 +1,18 @@
.container {
align-items: center;
display: flex;
flex-direction: column;
justify-content: center;
}
}
.card {
margin-top: 2rem;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(3, auto);
gap: 0.5rem;
}
.subTitle {
grid-column: span 2;
}

View File

@@ -1,14 +1,34 @@
import { serverClient } from "@/lib/trpc/server"
import Card from "@/components/MyProfile/Card"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import Title from "@/components/TempDesignSystem/Text/Title"
import { getIntl } from "@/i18n"
import styles from "./creditCards.module.css"
export default async function CreditCards() {
const creditCards = await serverClient().user.creditCards()
if (!creditCards) {
return null
}
const { formatMessage } = await getIntl()
return (
<Card className={styles.container}>
<Title level="h4">{formatMessage({ id: "My credit cards" })}</Title>
{creditCards.map((card, idx) => (
<div className={styles.card} key={idx}>
<Subtitle className={styles.subTitle}>
Name: {card.attribute.cardName}
</Subtitle>
<span> Type: {card.attribute.cardType} </span>
<span> Alias: {card.attribute.alias}</span>
<span> Number: {card.attribute.truncatedNumber}</span>
<span>
Expiration Date: {card.attribute.expirationDate.split("T")[0]}
</span>
</div>
))}
</Card>
)
}

View File

@@ -7,9 +7,10 @@ export namespace endpoints {
}
export const enum v1 {
profile = "profile/v1/Profile",
creditCards = `${profile}/creditCards`,
friendTransactions = "profile/v1/Transaction/friendTransactions",
upcomingStays = "booking/v1/Stays/future",
previousStays = "booking/v1/Stays/past",
friendTransactions = "profile/v1/Transaction/friendTransactions",
}
}

View File

@@ -166,3 +166,17 @@ export const getFriendTransactionsSchema = z.object({
})
.nullable(),
})
export const getCreditCardsSchema = z.object({
data: z.array(
z.object({
attribute: z.object({
cardName: z.string().optional(),
alias: z.string(),
truncatedNumber: z.string(),
expirationDate: z.string(),
cardType: z.string(),
}),
})
),
})

View File

@@ -3,6 +3,7 @@ import { protectedProcedure, router } from "@/server/trpc"
import { friendTransactionsInput, staysInput } from "./input"
import {
getCreditCardsSchema,
getFriendTransactionsSchema,
getStaysSchema,
getUserSchema,
@@ -270,4 +271,31 @@ export const userQueryRouter = router({
}
}),
}),
creditCards: protectedProcedure.query(async function ({ ctx }) {
const apiResponse = await api.get(api.endpoints.v1.creditCards, {
cache: "no-store",
headers: {
Authorization: `Bearer ${ctx.session.token.access_token}`,
},
})
if (!apiResponse.ok) {
console.info(`API Response Failed - Getting Creadit Cards`)
console.info(`User: (${JSON.stringify(ctx.session.user)})`)
console.error(apiResponse)
return null
}
const apiJson = await apiResponse.json()
const verifiedData = getCreditCardsSchema.safeParse(apiJson)
if (!verifiedData.success) {
console.info(`Failed to validate Credit Cards Data`)
console.info(`User: (${JSON.stringify(ctx.session.user)})`)
console.error(verifiedData.error)
return null
}
return verifiedData.data.data
}),
})