Merged in feat/SW-165-correct-labels (pull request #427)

Feat/SW-165 correct labels

* feat(SW-165): sort friend transactions and return additional properties

* feat(SW-165): Added points being calculated label

* feat(SW-165): added transactionDate for transactions without checkinDate

* feat(SW-165): Updated description copy for various reward types

* feat(SW-165): filter out expired transactions

* feat(SW-165): removed Mobile table and unified them into Table instead

* feat(SW-165): Added bookingUrl to friend transactions

* fix(SW-165): style fixes

* fix(SW-165): fix issues from merge

* fix(SW-165): remove comment

* fix(SW-165): fixed booking urls not being set and smaller fixes

* fix(SW-165): added comment regarding 'BALFWD'


Approved-by: Michael Zetterberg
Approved-by: Christel Westerberg
This commit is contained in:
Tobias Johansson
2024-08-21 13:54:55 +00:00
parent 72ebc14f7d
commit 1ec1033267
21 changed files with 292 additions and 239 deletions

View File

@@ -7,9 +7,8 @@ import { trpc } from "@/lib/trpc/client"
import LoadingSpinner from "@/components/LoadingSpinner" import LoadingSpinner from "@/components/LoadingSpinner"
import DesktopTable from "./Desktop"
import MobileTable from "./Mobile"
import Pagination from "./Pagination" import Pagination from "./Pagination"
import Table from "./Table"
import { Transactions } from "@/types/components/myPages/myPage/earnAndBurn" import { Transactions } from "@/types/components/myPages/myPage/earnAndBurn"
@@ -40,8 +39,7 @@ export default function TransactionTable({
<LoadingSpinner /> <LoadingSpinner />
) : ( ) : (
<> <>
<MobileTable transactions={data?.data.transactions || []} /> <Table transactions={data?.data.transactions || []} />
<DesktopTable transactions={data?.data.transactions || []} />
{data && data.meta.totalPages > 1 ? ( {data && data.meta.totalPages > 1 ? (
<Pagination <Pagination
handlePageChange={setPage} handlePageChange={setPage}

View File

@@ -1,26 +0,0 @@
import { Lang } from "@/constants/languages"
import { awardPointsVariants } from "./awardPointsVariants"
import type {
AwardPointsProps,
AwardPointsVariantProps,
} from "@/types/components/myPages/myPage/earnAndBurn"
export default function AwardPoints({ awardPoints }: AwardPointsProps) {
let variant: AwardPointsVariantProps["variant"] = undefined
if (awardPoints > 0) {
variant = "addition"
} else if (awardPoints < 0) {
variant = "negation"
awardPoints = Math.abs(awardPoints)
}
const classNames = awardPointsVariants({
variant,
})
// sv hardcoded to force space on thousands
const formatter = new Intl.NumberFormat(Lang.sv)
return <td className={classNames}>{formatter.format(awardPoints)} pts</td>
}

View File

@@ -1,35 +0,0 @@
"use client"
import { useIntl } from "react-intl"
import { dt } from "@/lib/dt"
import useLang from "@/hooks/useLang"
import AwardPoints from "./AwardPoints"
import styles from "./row.module.css"
import type { RowProps } from "@/types/components/myPages/myPage/earnAndBurn"
export default function Row({ transaction }: RowProps) {
const intl = useIntl()
const lang = useLang()
const description =
transaction.hotelName && transaction.city
? `${transaction.hotelName}, ${transaction.city} ${transaction.nights} ${intl.formatMessage({ id: "nights" })}`
: `${transaction.nights} ${intl.formatMessage({ id: "nights" })}`
const arrival = dt(transaction.checkinDate).locale(lang).format("DD MMM YYYY")
const departure = dt(transaction.checkoutDate)
.locale(lang)
.format("DD MMM YYYY")
return (
<tr className={styles.tr}>
<td className={styles.td}>{arrival}</td>
<td className={styles.td}>{description}</td>
<td className={styles.td}>{transaction.confirmationNumber}</td>
<td className={styles.td}>{departure}</td>
<AwardPoints awardPoints={transaction.awardPoints} />
</tr>
)
}

View File

@@ -1,69 +0,0 @@
import { useIntl } from "react-intl"
import { dt } from "@/lib/dt"
import AwardPoints from "@/components/MyPages/Blocks/Points/EarnAndBurn/JourneyTable/Desktop/Row/AwardPoints"
import Body from "@/components/TempDesignSystem/Text/Body"
import useLang from "@/hooks/useLang"
import styles from "./mobile.module.css"
import type { TableProps } from "@/types/components/myPages/myPage/earnAndBurn"
export default function MobileTable({ transactions }: TableProps) {
const intl = useIntl()
const lang = useLang()
return (
<div className={styles.container}>
<table className={styles.table}>
<thead className={styles.thead}>
<tr>
<Body asChild>
<th className={styles.th}>
{intl.formatMessage({ id: "Transactions" })}
</th>
</Body>
<Body asChild>
<th className={styles.th}>
{intl.formatMessage({ id: "Points" })}
</th>
</Body>
</tr>
</thead>
<tbody>
{transactions.length ? (
transactions.map((transaction, idx) => (
<tr
className={styles.tr}
key={`${transaction.confirmationNumber}-${idx}`}
>
<td className={`${styles.td} ${styles.transactionDetails}`}>
<span className={styles.transactionDate}>
{dt(transaction.checkinDate)
.locale(lang)
.format("DD MMM YYYY")}
</span>
{transaction.hotelName && transaction.city ? (
<span>{`${transaction.hotelName}, ${transaction.city}`}</span>
) : null}
<span>
{`${transaction.nights} ${intl.formatMessage({ id: transaction.nights === 1 ? "night" : "nights" })}`}
</span>
</td>
<AwardPoints awardPoints={transaction.awardPoints} />
</tr>
))
) : (
<tr>
<td className={styles.placeholder} colSpan={2}>
{intl.formatMessage({
id: "There are no transactions to display",
})}
</td>
</tr>
)}
</tbody>
</table>
</div>
)
}

View File

@@ -1,52 +0,0 @@
.table {
border-collapse: collapse;
border-spacing: 0;
width: 100%;
}
.thead {
background-color: var(--Main-Grey-10);
}
.th {
padding: var(--Spacing-x2);
}
.tr {
border-top: 1px solid var(--Main-Grey-10);
}
.td {
padding: var(--Spacing-x2);
}
.transactionDetails {
display: grid;
font-size: var(--typography-Footnote-Regular-fontSize);
}
.transactionDate {
font-weight: 700;
}
.placeholder {
text-align: center;
padding: var(--Spacing-x4);
border: 1px solid var(--Main-Grey-10);
}
.loadMoreButton {
background-color: var(--Main-Grey-10);
border: none;
display: flex;
align-items: center;
justify-content: center;
gap: var(--Spacing-x-half);
padding: var(--Spacing-x2);
width: 100%;
}
@media screen and (min-width: 768px) {
.container {
display: none;
}
}

View File

@@ -0,0 +1,40 @@
import { useIntl } from "react-intl"
import { Lang } from "@/constants/languages"
import { awardPointsVariants } from "./awardPointsVariants"
import type { AwardPointsVariantProps } from "@/types/components/myPages/myPage/earnAndBurn"
export default function AwardPoints({
awardPoints,
isCalculated,
}: {
awardPoints: number
isCalculated: boolean
}) {
let variant: AwardPointsVariantProps["variant"] = undefined
const intl = useIntl()
if (isCalculated) {
if (awardPoints > 0) {
variant = "addition"
} else if (awardPoints < 0) {
variant = "negation"
awardPoints = Math.abs(awardPoints)
}
}
const classNames = awardPointsVariants({
variant,
})
// sv hardcoded to force space on thousands
const formatter = new Intl.NumberFormat(Lang.sv)
return (
<td className={classNames}>
{isCalculated
? formatter.format(awardPoints)
: intl.formatMessage({ id: "Points being calculated" })}
</td>
)
}

View File

@@ -0,0 +1,82 @@
"use client"
import { useIntl } from "react-intl"
import { dt } from "@/lib/dt"
import Link from "@/components/TempDesignSystem/Link"
import useLang from "@/hooks/useLang"
import AwardPoints from "./AwardPoints"
import styles from "./row.module.css"
import type { RowProps } from "@/types/components/myPages/myPage/earnAndBurn"
import { RewardTransactionTypes } from "@/types/components/myPages/myPage/enums"
export default function Row({ transaction }: RowProps) {
const intl = useIntl()
const lang = useLang()
const nightString = `${transaction.nights} ${transaction.nights === 1 ? intl.formatMessage({ id: "night" }) : intl.formatMessage({ id: "nights" })}`
let description =
transaction.hotelName && transaction.city
? `${transaction.hotelName}, ${transaction.city} ${nightString}`
: `${nightString}`
switch (transaction.type) {
case RewardTransactionTypes.stay:
if (transaction.hotelId === "ORS")
description = intl.formatMessage({ id: "Former Scandic Hotel" })
break
case RewardTransactionTypes.ancillary:
description = intl.formatMessage({ id: "Extras to your booking" })
break
case RewardTransactionTypes.enrollment:
description = intl.formatMessage({ id: "Sign up bonus" })
break
case RewardTransactionTypes.mastercard_points:
description = intl.formatMessage({ id: "Scandic Friends Mastercard" })
break
case RewardTransactionTypes.tui_points:
description = intl.formatMessage({ id: "TUI Points" })
case RewardTransactionTypes.stayAdj:
if (transaction.confirmationNumber === "BALFWD")
description = intl.formatMessage({
id: "Points earned prior to May 1, 2021",
})
break
case RewardTransactionTypes.pointShop:
description = intl.formatMessage({ id: "Scandic Friends Point Shop" })
break
}
const arrival = dt(transaction.checkinDate).locale(lang).format("DD MMM YYYY")
const transactionDate = dt(transaction.transactionDate)
.locale(lang)
.format("DD MMM YYYY")
return (
<tr className={styles.tr}>
<AwardPoints
awardPoints={transaction.awardPoints}
isCalculated={transaction.pointsCalculated}
/>
<td className={`${styles.td} ${styles.description}`}>{description}</td>
<td className={styles.td}>
{transaction.type === RewardTransactionTypes.stay &&
transaction.bookingUrl ? (
<Link variant="underscored" href={transaction.bookingUrl}>
{transaction.confirmationNumber}
</Link>
) : (
transaction.confirmationNumber
)}
</td>
<td className={styles.td}>
{transaction.checkinDate ? arrival : transactionDate}
</td>
</tr>
)
}

View File

@@ -1,13 +1,21 @@
.tr { .tr {
border: 1px solid #e6e9ec; border-bottom: 1px solid var(--Scandic-Brand-Pale-Peach);
&:last-child {
border-bottom: none;
}
} }
.td { .td {
background-color: #fff; background-color: #fff;
color: var(--UI-Text-High-contrast); color: var(--UI-Text-High-contrast);
padding: var(--Spacing-x2) var(--Spacing-x4); padding: var(--Spacing-x2);
position: relative; position: relative;
text-align: left; text-align: left;
text-wrap: nowrap;
}
.description {
font-weight: var(--typography-Body-Bold-fontWeight);
} }
.addition { .addition {
@@ -17,8 +25,7 @@
.addition::before { .addition::before {
color: var(--Secondary-Light-On-Surface-Accent); color: var(--Secondary-Light-On-Surface-Accent);
content: "+"; content: "+";
left: var(--Spacing-x2); margin-right: var(--Spacing-x-half);
position: absolute;
} }
.negation { .negation {
@@ -28,6 +35,11 @@
.negation::before { .negation::before {
color: var(--Base-Text-Accent); color: var(--Base-Text-Accent);
content: "-"; content: "-";
left: var(--Spacing-x2); margin-right: var(--Spacing-x-half);
position: absolute; }
@media screen and (min-width: 768px) {
.td {
padding: var(--Spacing-x3);
}
} }

View File

@@ -1,50 +1,48 @@
"use client"
import { useIntl } from "react-intl" import { useIntl } from "react-intl"
import Body from "@/components/TempDesignSystem/Text/Body" import Body from "@/components/TempDesignSystem/Text/Body"
import Row from "./Row" import Row from "./Row"
import styles from "./desktop.module.css" import styles from "./table.module.css"
import type { TableProps } from "@/types/components/myPages/myPage/earnAndBurn" import type { TableProps } from "@/types/components/myPages/myPage/earnAndBurn"
const tableHeadings = [ const tableHeadings = [
"Arrival date", "Points",
"Description", "Description",
"Booking number", "Booking number",
"Transaction date", "Arrival date",
"Points",
] ]
export default function DesktopTable({ transactions }: TableProps) { export default function Table({ transactions }: TableProps) {
const intl = useIntl() const intl = useIntl()
return ( return (
<div className={styles.container}> <div className={styles.container}>
{transactions.length ? ( {transactions.length ? (
<div> <table className={styles.table}>
<table className={styles.table}> <thead className={styles.thead}>
<thead className={styles.thead}> <tr>
<tr> {tableHeadings.map((heading) => (
{tableHeadings.map((heading) => ( <th key={heading} className={styles.th}>
<th key={heading} className={styles.th}> <Body textTransform="bold">
<Body textTransform="bold"> {intl.formatMessage({ id: heading })}
{intl.formatMessage({ id: heading })} </Body>
</Body> </th>
</th>
))}
</tr>
</thead>
<tbody>
{transactions.map((transaction, idx) => (
<Row
key={`${transaction.confirmationNumber}-${idx}`}
transaction={transaction}
/>
))} ))}
</tbody> </tr>
</table> </thead>
</div> <tbody>
{transactions.map((transaction, index) => (
<Row
key={`${transaction.confirmationNumber}-${index}`}
transaction={transaction}
/>
))}
</tbody>
</table>
) : ( ) : (
<table className={styles.table}> <table className={styles.table}>
<thead className={styles.thead}> <thead className={styles.thead}>

View File

@@ -1,5 +1,8 @@
.container { .container {
display: none; display: flex;
flex-direction: column;
overflow-x: auto;
border-radius: var(--Corner-radius-Small);
} }
.table { .table {
@@ -17,7 +20,8 @@
.th { .th {
text-align: left; text-align: left;
padding: 20px 32px; text-wrap: nowrap;
padding: var(--Spacing-x2);
} }
.placeholder { .placeholder {
@@ -49,9 +53,10 @@
} }
@media screen and (min-width: 768px) { @media screen and (min-width: 768px) {
.container { .container {
display: flex; border-radius: var(--Corner-radius-Large);
flex-direction: column; }
gap: 16px;
overflow-x: auto; .th {
padding: var(--Spacing-x2) var(--Spacing-x3);
} }
} }

View File

@@ -42,10 +42,12 @@
"Edit": "Redigere", "Edit": "Redigere",
"Edit profile": "Rediger profil", "Edit profile": "Rediger profil",
"Email": "E-mail", "Email": "E-mail",
"Extras to your booking": "Ekstra til din booking",
"There are no transactions to display": "Der er ingen transaktioner at vise", "There are no transactions to display": "Der er ingen transaktioner at vise",
"Explore all levels and benefits": "Udforsk alle niveauer og fordele", "Explore all levels and benefits": "Udforsk alle niveauer og fordele",
"Find booking": "Find booking", "Find booking": "Find booking",
"Flexibility": "Fleksibilitet", "Flexibility": "Fleksibilitet",
"Former Scandic Hotel": "Tidligere Scandic Hotel",
"From": "Fra", "From": "Fra",
"Get inspired": "Bliv inspireret", "Get inspired": "Bliv inspireret",
"Go back to overview": "Gå tilbage til oversigten", "Go back to overview": "Gå tilbage til oversigten",
@@ -95,7 +97,9 @@
"Phone is required": "Telefonnummer er påkrævet", "Phone is required": "Telefonnummer er påkrævet",
"Phone number": "Telefonnummer", "Phone number": "Telefonnummer",
"Please enter a valid phone number": "Indtast venligst et gyldigt telefonnummer", "Please enter a valid phone number": "Indtast venligst et gyldigt telefonnummer",
"Points": "Point", "Points": "Points",
"Points being calculated": "Point udregnes",
"Points earned prior to May 1, 2021": "Point optjent før 1. maj 2021",
"Points may take up to 10 days to be displayed.": "Det kan tage op til 10 dage at få vist point.", "Points may take up to 10 days to be displayed.": "Det kan tage op til 10 dage at få vist point.",
"Points needed to level up": "Point nødvendige for at komme i niveau", "Points needed to level up": "Point nødvendige for at komme i niveau",
"Points needed to stay on level": "Point nødvendige for at holde sig på niveau", "Points needed to stay on level": "Point nødvendige for at holde sig på niveau",
@@ -107,6 +111,8 @@
"Retype new password": "Gentag den nye adgangskode", "Retype new password": "Gentag den nye adgangskode",
"Rooms": "Værelser", "Rooms": "Værelser",
"Save": "Gemme", "Save": "Gemme",
"Scandic Friends Mastercard": "Scandic Friends Mastercard",
"Scandic Friends Point Shop": "Scandic Friends Point Shop",
"Select a country": "Vælg et land", "Select a country": "Vælg et land",
"Select country of residence": "Vælg bopælsland", "Select country of residence": "Vælg bopælsland",
"Select date of birth": "Vælg fødselsdato", "Select date of birth": "Vælg fødselsdato",
@@ -115,6 +121,7 @@
"Show more": "Vis mere", "Show more": "Vis mere",
"Show all amenities": "Vis alle faciliteter", "Show all amenities": "Vis alle faciliteter",
"Skip to main content": "Spring over og gå til hovedindhold", "Skip to main content": "Spring over og gå til hovedindhold",
"Sign up bonus": "Tilmeldingsbonus",
"Something went wrong!": "Noget gik galt!", "Something went wrong!": "Noget gik galt!",
"Street": "Gade", "Street": "Gade",
"special character": "speciel karakter", "special character": "speciel karakter",
@@ -124,6 +131,7 @@
"Transactions": "Transaktioner", "Transactions": "Transaktioner",
"Tripadvisor reviews": "{rating} ({count} anmeldelser på Tripadvisor)", "Tripadvisor reviews": "{rating} ({count} anmeldelser på Tripadvisor)",
"to": "til", "to": "til",
"TUI Points": "TUI-point",
"User information": "Brugeroplysninger", "User information": "Brugeroplysninger",
"uppercase letter": "stort bogstav", "uppercase letter": "stort bogstav",
"Visiting address": "Besøgsadresse", "Visiting address": "Besøgsadresse",

View File

@@ -41,10 +41,12 @@
"Edit": "Bearbeiten", "Edit": "Bearbeiten",
"Edit profile": "Profil bearbeiten", "Edit profile": "Profil bearbeiten",
"Email": "Email", "Email": "Email",
"Extras to your booking": "Extras zu Ihrer Buchung",
"There are no transactions to display": "Es sind keine Transaktionen zum Anzeigen vorhanden", "There are no transactions to display": "Es sind keine Transaktionen zum Anzeigen vorhanden",
"Explore all levels and benefits": "Entdecken Sie alle Levels und Vorteile", "Explore all levels and benefits": "Entdecken Sie alle Levels und Vorteile",
"Find booking": "Buchung finden", "Find booking": "Buchung finden",
"Flexibility": "Flexibilität", "Flexibility": "Flexibilität",
"Former Scandic Hotel": "Ehemaliges Scandic Hotel",
"From": "Fromm", "From": "Fromm",
"Get inspired": "Lassen Sie sich inspieren", "Get inspired": "Lassen Sie sich inspieren",
"Go back to overview": "Zurück zur Übersicht", "Go back to overview": "Zurück zur Übersicht",
@@ -93,6 +95,8 @@
"Phone number": "Telefonnummer", "Phone number": "Telefonnummer",
"Please enter a valid phone number": "Bitte geben Sie eine gültige Telefonnummer ein", "Please enter a valid phone number": "Bitte geben Sie eine gültige Telefonnummer ein",
"Points": "Punkte", "Points": "Punkte",
"Points being calculated": "Punkte werden berechnet",
"Points earned prior to May 1, 2021": "Vor dem 1. Mai 2021 gesammelte Punkte",
"Points may take up to 10 days to be displayed.": "Es kann bis zu 10 Tage dauern, bis Punkte angezeigt werden.", "Points may take up to 10 days to be displayed.": "Es kann bis zu 10 Tage dauern, bis Punkte angezeigt werden.",
"Points needed to level up": "Punkte, die zum Levelaufstieg benötigt werden", "Points needed to level up": "Punkte, die zum Levelaufstieg benötigt werden",
"Points needed to stay on level": "Erforderliche Punkte, um auf diesem Level zu bleiben", "Points needed to stay on level": "Erforderliche Punkte, um auf diesem Level zu bleiben",
@@ -102,6 +106,8 @@
"Read more about the hotel": "Lesen Sie mehr über das Hotel", "Read more about the hotel": "Lesen Sie mehr über das Hotel",
"Retype new password": "Neues Passwort erneut eingeben", "Retype new password": "Neues Passwort erneut eingeben",
"Save": "Speichern", "Save": "Speichern",
"Scandic Friends Mastercard": "Scandic Friends Mastercard",
"Scandic Friends Point Shop": "Scandic Friends Point Shop",
"Select a country": "Wähle ein Land", "Select a country": "Wähle ein Land",
"Select country of residence": "Wählen Sie das Land Ihres Wohnsitzes aus", "Select country of residence": "Wählen Sie das Land Ihres Wohnsitzes aus",
"Select date of birth": "Geburtsdatum auswählen", "Select date of birth": "Geburtsdatum auswählen",
@@ -110,6 +116,7 @@
"Show more": "Mehr anzeigen", "Show more": "Mehr anzeigen",
"Show all amenities": "Alle Annehmlichkeiten anzeigen", "Show all amenities": "Alle Annehmlichkeiten anzeigen",
"Skip to main content": "Direkt zum Inhalt", "Skip to main content": "Direkt zum Inhalt",
"Sign up bonus": "Anmeldebonus",
"Something went wrong!": "Etwas ist schief gelaufen!", "Something went wrong!": "Etwas ist schief gelaufen!",
"Street": "Straße", "Street": "Straße",
"special character": "sonderzeichen", "special character": "sonderzeichen",
@@ -119,6 +126,7 @@
"Transactions": "Transaktionen", "Transactions": "Transaktionen",
"Tripadvisor reviews": "{rating} ({count} Bewertungen auf Tripadvisor)", "Tripadvisor reviews": "{rating} ({count} Bewertungen auf Tripadvisor)",
"to": "zu", "to": "zu",
"TUI Points": "TUI Punkte",
"User information": "Nutzerinformation", "User information": "Nutzerinformation",
"uppercase letter": "großbuchstabe", "uppercase letter": "großbuchstabe",
"Visiting address": "Besuchsadresse", "Visiting address": "Besuchsadresse",

View File

@@ -45,8 +45,10 @@
"Email": "Email", "Email": "Email",
"There are no transactions to display": "There are no transactions to display", "There are no transactions to display": "There are no transactions to display",
"Explore all levels and benefits": "Explore all levels and benefits", "Explore all levels and benefits": "Explore all levels and benefits",
"Extras to your booking": "Extras to your booking",
"FAQ": "FAQ", "FAQ": "FAQ",
"Find booking": "Find booking", "Find booking": "Find booking",
"Former Scandic Hotel": "Former Scandic Hotel",
"Flexibility": "Flexibility", "Flexibility": "Flexibility",
"From": "From", "From": "From",
"Get inspired": "Get inspired", "Get inspired": "Get inspired",
@@ -101,6 +103,8 @@
"Phone number": "Phone number", "Phone number": "Phone number",
"Please enter a valid phone number": "Please enter a valid phone number", "Please enter a valid phone number": "Please enter a valid phone number",
"Points": "Points", "Points": "Points",
"Points being calculated": "Points being calculated",
"Points earned prior to May 1, 2021": "Points earned prior to May 1, 2021",
"Points may take up to 10 days to be displayed.": "Points may take up to 10 days to be displayed.", "Points may take up to 10 days to be displayed.": "Points may take up to 10 days to be displayed.",
"Points needed to level up": "Points needed to level up", "Points needed to level up": "Points needed to level up",
"Points needed to stay on level": "Points needed to stay on level", "Points needed to stay on level": "Points needed to stay on level",
@@ -113,6 +117,8 @@
"Rooms": "Rooms", "Rooms": "Rooms",
"Save": "Save", "Save": "Save",
"See room details": "See room details", "See room details": "See room details",
"Scandic Friends Mastercard": "Scandic Friends Mastercard",
"Scandic Friends Point Shop": "Scandic Friends Point Shop",
"Select a country": "Select a country", "Select a country": "Select a country",
"Select country of residence": "Select country of residence", "Select country of residence": "Select country of residence",
"Select date of birth": "Select date of birth", "Select date of birth": "Select date of birth",
@@ -121,6 +127,7 @@
"Show more": "Show more", "Show more": "Show more",
"Show all amenities": "Show all amenities", "Show all amenities": "Show all amenities",
"Skip to main content": "Skip to main content", "Skip to main content": "Skip to main content",
"Sign up bonus": "Sign up bonus",
"Something went wrong!": "Something went wrong!", "Something went wrong!": "Something went wrong!",
"Street": "Street", "Street": "Street",
"special character": "special character", "special character": "special character",
@@ -130,6 +137,7 @@
"Transactions": "Transactions", "Transactions": "Transactions",
"Tripadvisor reviews": "{rating} ({count} reviews on Tripadvisor)", "Tripadvisor reviews": "{rating} ({count} reviews on Tripadvisor)",
"to": "to", "to": "to",
"TUI Points": "TUI Points",
"User information": "User information", "User information": "User information",
"uppercase letter": "uppercase letter", "uppercase letter": "uppercase letter",
"Welcome": "Welcome", "Welcome": "Welcome",

View File

@@ -42,10 +42,12 @@
"Edit": "Muokata", "Edit": "Muokata",
"Edit profile": "Muokkaa profiilia", "Edit profile": "Muokkaa profiilia",
"Email": "Sähköposti", "Email": "Sähköposti",
"Extras to your booking": "Lisävarusteet varaukseesi",
"There are no transactions to display": "Näytettäviä tapahtumia ei ole", "There are no transactions to display": "Näytettäviä tapahtumia ei ole",
"Explore all levels and benefits": "Tutustu kaikkiin tasoihin ja etuihin", "Explore all levels and benefits": "Tutustu kaikkiin tasoihin ja etuihin",
"Find booking": "Etsi varaus", "Find booking": "Etsi varaus",
"Flexibility": "Joustavuus", "Flexibility": "Joustavuus",
"Former Scandic Hotel": "Entinen Scandic Hotel",
"From": "From", "From": "From",
"Get inspired": "Inspiroidu", "Get inspired": "Inspiroidu",
"Go back to overview": "Palaa yleiskatsaukseen", "Go back to overview": "Palaa yleiskatsaukseen",
@@ -96,6 +98,8 @@
"Phone number": "Puhelinnumero", "Phone number": "Puhelinnumero",
"Please enter a valid phone number": "Ole hyvä ja näppäile voimassaoleva puhelinnumero", "Please enter a valid phone number": "Ole hyvä ja näppäile voimassaoleva puhelinnumero",
"Points": "Pistettä", "Points": "Pistettä",
"Points being calculated": "Pisteitä lasketaan",
"Points earned prior to May 1, 2021": "Ennen 1. toukokuuta 2021 ansaitut pisteet",
"Points may take up to 10 days to be displayed.": "Pisteiden näyttäminen voi kestää jopa 10 päivää.", "Points may take up to 10 days to be displayed.": "Pisteiden näyttäminen voi kestää jopa 10 päivää.",
"Points needed to level up": "Pisteitä tarvitaan tasolle pääsemiseksi", "Points needed to level up": "Pisteitä tarvitaan tasolle pääsemiseksi",
"Points needed to stay on level": "Tällä tasolla pysymiseen tarvittavat pisteet", "Points needed to stay on level": "Tällä tasolla pysymiseen tarvittavat pisteet",
@@ -107,6 +111,8 @@
"Retype new password": "Kirjoita uusi salasana uudelleen", "Retype new password": "Kirjoita uusi salasana uudelleen",
"Rooms": "Huoneet", "Rooms": "Huoneet",
"Save": "Tallentaa", "Save": "Tallentaa",
"Scandic Friends Mastercard": "Scandic Friends Mastercard",
"Scandic Friends Point Shop": "Scandic Friends Point Shop",
"Select a country": "Valitse maa", "Select a country": "Valitse maa",
"Select country of residence": "Valitse asuinmaa", "Select country of residence": "Valitse asuinmaa",
"Select date of birth": "Valitse syntymäaika", "Select date of birth": "Valitse syntymäaika",
@@ -115,6 +121,7 @@
"Show more": "Näytä lisää", "Show more": "Näytä lisää",
"Show all amenities": "Näytä kaikki mukavuudet", "Show all amenities": "Näytä kaikki mukavuudet",
"Skip to main content": "Siirry pääsisältöön", "Skip to main content": "Siirry pääsisältöön",
"Sign up bonus": "Rekisteröidy bonus",
"Something went wrong!": "Jotain meni pieleen!", "Something went wrong!": "Jotain meni pieleen!",
"Street": "Katu", "Street": "Katu",
"special character": "erikoishahmo", "special character": "erikoishahmo",
@@ -124,6 +131,7 @@
"Transactions": "Tapahtumat", "Transactions": "Tapahtumat",
"Tripadvisor reviews": "{rating} ({count} arvostelua TripAdvisorissa)", "Tripadvisor reviews": "{rating} ({count} arvostelua TripAdvisorissa)",
"to": "to", "to": "to",
"TUI Points": "TUI-pisteet",
"User information": "Käyttäjän tiedot", "User information": "Käyttäjän tiedot",
"uppercase letter": "iso kirjain", "uppercase letter": "iso kirjain",
"Visiting address": "Käyntiosoite", "Visiting address": "Käyntiosoite",

View File

@@ -42,10 +42,12 @@
"Edit": "Redigere", "Edit": "Redigere",
"Edit profile": "Rediger profil", "Edit profile": "Rediger profil",
"Email": "E-post", "Email": "E-post",
"Extras to your booking": "Ekstra til din bestilling",
"There are no transactions to display": "Det er ingen transaksjoner å vise", "There are no transactions to display": "Det er ingen transaksjoner å vise",
"Explore all levels and benefits": "Utforsk alle nivåer og fordeler", "Explore all levels and benefits": "Utforsk alle nivåer og fordeler",
"Find booking": "Finn booking", "Find booking": "Finn booking",
"Flexibility": "Fleksibilitet", "Flexibility": "Fleksibilitet",
"Former Scandic Hotel": "Tidligere Scandic Hotel",
"From": "Fra", "From": "Fra",
"Get inspired": "Bli inspirert", "Get inspired": "Bli inspirert",
"Go back to overview": "Gå tilbake til oversikten", "Go back to overview": "Gå tilbake til oversikten",
@@ -96,6 +98,8 @@
"Phone number": "Telefonnummer", "Phone number": "Telefonnummer",
"Please enter a valid phone number": "Vennligst oppgi et gyldig telefonnummer", "Please enter a valid phone number": "Vennligst oppgi et gyldig telefonnummer",
"Points": "Poeng", "Points": "Poeng",
"Points being calculated": "Poeng beregnes",
"Points earned prior to May 1, 2021": "Poeng opptjent før 1. mai 2021",
"Points may take up to 10 days to be displayed.": "Det kan ta opptil 10 dager før poeng vises.", "Points may take up to 10 days to be displayed.": "Det kan ta opptil 10 dager før poeng vises.",
"Points needed to level up": "Poeng som trengs for å komme opp i nivå", "Points needed to level up": "Poeng som trengs for å komme opp i nivå",
"Points needed to stay on level": "Poeng som trengs for å holde seg på nivå", "Points needed to stay on level": "Poeng som trengs for å holde seg på nivå",
@@ -107,6 +111,8 @@
"Retype new password": "Skriv inn nytt passord på nytt", "Retype new password": "Skriv inn nytt passord på nytt",
"Rooms": "Rom", "Rooms": "Rom",
"Save": "Lagre", "Save": "Lagre",
"Scandic Friends Mastercard": "Scandic Friends Mastercard",
"Scandic Friends Point Shop": "Scandic Friends Point Shop",
"Select a country": "Velg et land", "Select a country": "Velg et land",
"Select country of residence": "Velg bostedsland", "Select country of residence": "Velg bostedsland",
"Select date of birth": "Velg fødselsdato", "Select date of birth": "Velg fødselsdato",
@@ -115,6 +121,7 @@
"Show more": "Vis mer", "Show more": "Vis mer",
"Show all amenities": "Vis alle fasiliteter", "Show all amenities": "Vis alle fasiliteter",
"Skip to main content": "Gå videre til hovedsiden", "Skip to main content": "Gå videre til hovedsiden",
"Sign up bonus": "Registreringsbonus",
"Something went wrong!": "Noe gikk galt!", "Something went wrong!": "Noe gikk galt!",
"Street": "Gate", "Street": "Gate",
"special character": "spesiell karakter", "special character": "spesiell karakter",
@@ -124,6 +131,7 @@
"Transactions": "Transaksjoner", "Transactions": "Transaksjoner",
"Tripadvisor reviews": "{rating} ({count} anmeldelser på Tripadvisor)", "Tripadvisor reviews": "{rating} ({count} anmeldelser på Tripadvisor)",
"to": "til", "to": "til",
"TUI Points": "TUI-poeng",
"User information": "Brukerinformasjon", "User information": "Brukerinformasjon",
"uppercase letter": "stor bokstav", "uppercase letter": "stor bokstav",
"Visiting address": "Besøksadresse", "Visiting address": "Besøksadresse",

View File

@@ -42,10 +42,12 @@
"Edit": "Redigera", "Edit": "Redigera",
"Edit profile": "Redigera profil", "Edit profile": "Redigera profil",
"Email": "E-post", "Email": "E-post",
"Extras to your booking": "Extra till din bokning",
"There are no transactions to display": "Det finns inga transaktioner att visa", "There are no transactions to display": "Det finns inga transaktioner att visa",
"Explore all levels and benefits": "Utforska alla nivåer och fördelar", "Explore all levels and benefits": "Utforska alla nivåer och fördelar",
"Find booking": "Hitta bokning", "Find booking": "Hitta bokning",
"Flexibility": "Flexibilitet", "Flexibility": "Flexibilitet",
"Former Scandic Hotel": "Tidigare Scandic Hotel",
"From": "Från", "From": "Från",
"Get inspired": "Bli inspirerad", "Get inspired": "Bli inspirerad",
"Go back to overview": "Gå tillbaka till översikten", "Go back to overview": "Gå tillbaka till översikten",
@@ -99,6 +101,8 @@
"Phone number": "Telefonnummer", "Phone number": "Telefonnummer",
"Please enter a valid phone number": "Var vänlig och ange ett giltigt telefonnummer", "Please enter a valid phone number": "Var vänlig och ange ett giltigt telefonnummer",
"Points": "Poäng", "Points": "Poäng",
"Points being calculated": "Poäng beräknas",
"Points earned prior to May 1, 2021": "Poäng intjänade före 1 maj 2021",
"Points may take up to 10 days to be displayed.": "Det kan ta upp till 10 dagar innan poäng visas.", "Points may take up to 10 days to be displayed.": "Det kan ta upp till 10 dagar innan poäng visas.",
"Points needed to level up": "Poäng som behövs för att gå upp i nivå", "Points needed to level up": "Poäng som behövs för att gå upp i nivå",
"Points needed to stay on level": "Poäng som behövs för att hålla sig på nivå", "Points needed to stay on level": "Poäng som behövs för att hålla sig på nivå",
@@ -110,6 +114,8 @@
"Retype new password": "Upprepa nytt lösenord", "Retype new password": "Upprepa nytt lösenord",
"Rooms": "Rum", "Rooms": "Rum",
"Save": "Spara", "Save": "Spara",
"Scandic Friends Mastercard": "Scandic Friends Mastercard",
"Scandic Friends Point Shop": "Scandic Friends Point Shop",
"Select a country": "Välj ett land", "Select a country": "Välj ett land",
"Select country of residence": "Välj bosättningsland", "Select country of residence": "Välj bosättningsland",
"Select date of birth": "Välj födelsedatum", "Select date of birth": "Välj födelsedatum",
@@ -118,6 +124,7 @@
"Show more": "Visa mer", "Show more": "Visa mer",
"Show all amenities": "Visa alla bekvämligheter", "Show all amenities": "Visa alla bekvämligheter",
"Skip to main content": "Fortsätt till huvudinnehåll", "Skip to main content": "Fortsätt till huvudinnehåll",
"Sign up bonus": "Registreringsbonus",
"Something went wrong!": "Något gick fel!", "Something went wrong!": "Något gick fel!",
"Street": "Gata", "Street": "Gata",
"special character": "speciell karaktär", "special character": "speciell karaktär",
@@ -127,6 +134,7 @@
"Transactions": "Transaktioner", "Transactions": "Transaktioner",
"Tripadvisor reviews": "{rating} ({count} recensioner på Tripadvisor)", "Tripadvisor reviews": "{rating} ({count} recensioner på Tripadvisor)",
"to": "till", "to": "till",
"TUI Points": "TUI-poäng",
"User information": "Användar information", "User information": "Användar information",
"uppercase letter": "stor bokstav", "uppercase letter": "stor bokstav",
"Visiting address": "Besöksadress", "Visiting address": "Besöksadress",

View File

@@ -115,6 +115,8 @@ export const getFriendTransactionsSchema = z.object({
hotelOperaId: z.string().default(""), hotelOperaId: z.string().default(""),
nights: z.number().default(1), nights: z.number().default(1),
pointsCalculated: z.boolean().default(true), pointsCalculated: z.boolean().default(true),
transactionDate: z.string().default(""),
bookingUrl: z.string().default(""),
hotelInformation: z hotelInformation: z
.object({ .object({
city: z.string().default(""), city: z.string().default(""),
@@ -170,6 +172,10 @@ export const getFriendTransactionsSchema = z.object({
.nullable(), .nullable(),
}) })
type GetFriendTransactionsData = z.infer<typeof getFriendTransactionsSchema>
export type FriendTransaction = GetFriendTransactionsData["data"][number]
export const getCreditCardsSchema = z.object({ export const getCreditCardsSchema = z.object({
data: z.array( data: z.array(
z.object({ z.object({

View File

@@ -26,6 +26,7 @@ import {
staysInput, staysInput,
} from "./input" } from "./input"
import { import {
FriendTransaction,
getCreditCardsSchema, getCreditCardsSchema,
getFriendTransactionsSchema, getFriendTransactionsSchema,
getMembershipCardsSchema, getMembershipCardsSchema,
@@ -38,6 +39,7 @@ import { benefits, extendedUser, nextLevelPerks } from "./temp"
import type { Session } from "next-auth" import type { Session } from "next-auth"
import { RewardTransactionTypes } from "@/types/components/myPages/myPage/enums"
import type { import type {
LoginType, LoginType,
TrackingSDKUserData, TrackingSDKUserData,
@@ -91,11 +93,23 @@ function fakingRequest<T>(payload: T): Promise<T> {
}) })
} }
const updateStaysBookingUrl = async ( async function updateStaysBookingUrl(
data: Stay[], data: Stay[],
token: string, token: string,
lang: Lang lang: Lang
) => { ): Promise<Stay[]>
async function updateStaysBookingUrl(
data: FriendTransaction[],
token: string,
lang: Lang
): Promise<FriendTransaction[]>
async function updateStaysBookingUrl(
data: Stay[] | FriendTransaction[],
token: string,
lang: Lang
) {
// Tenporary API call needed till we have user name in ctx session data // Tenporary API call needed till we have user name in ctx session data
const apiResponse = await api.get(api.endpoints.v1.profile, { const apiResponse = await api.get(api.endpoints.v1.profile, {
cache: "no-store", cache: "no-store",
@@ -135,9 +149,9 @@ const updateStaysBookingUrl = async (
if (apiResponse.ok) { if (apiResponse.ok) {
const apiJson = await apiResponse.json() const apiJson = await apiResponse.json()
if (apiJson.data?.attributes) { if (apiJson.data?.attributes) {
return data.map((stay: Stay) => { return data.map((d) => {
const originalString = const originalString =
stay.attributes.confirmationNumber.toString() + d.attributes.confirmationNumber.toString() +
"," + "," +
apiJson.data.attributes.lastName apiJson.data.attributes.lastName
const encryptedBookingValue = encryptValue(originalString) const encryptedBookingValue = encryptValue(originalString)
@@ -147,11 +161,11 @@ const updateStaysBookingUrl = async (
"?lastName=" + "?lastName=" +
apiJson.data.attributes.lastName + apiJson.data.attributes.lastName +
"&bookingId=" + "&bookingId=" +
stay.attributes.confirmationNumber d.attributes.confirmationNumber
return { return {
...stay, ...d,
attributes: { attributes: {
...stay.attributes, ...d.attributes,
bookingUrl: bookingUrl, bookingUrl: bookingUrl,
}, },
} }
@@ -492,15 +506,29 @@ export const userQueryRouter = router({
return null return null
} }
const pageData = verifiedData.data.data.slice( const updatedData = await updateStaysBookingUrl(
limit * (page - 1), verifiedData.data.data,
limit * page ctx.session.token.access_token,
ctx.lang
) )
const pageData = updatedData
.filter((t) => t.type !== RewardTransactionTypes.expired)
.sort((a, b) => {
// 'BALFWD' are transactions from Opera migration that happended in May 2021
const isBalfwd =
a.type === RewardTransactionTypes.stayAdj &&
a.attributes.confirmationNumber === "BALFWD"
if (isBalfwd) return 1
return a.attributes.checkinDate > b.attributes.checkinDate ? -1 : 1
})
.slice(limit * (page - 1), limit * page)
return { return {
data: { data: {
transactions: pageData.map(({ attributes }) => { transactions: pageData.map(({ type, attributes }) => {
return { return {
type,
awardPoints: attributes.awardPoints, awardPoints: attributes.awardPoints,
checkinDate: attributes.checkinDate, checkinDate: attributes.checkinDate,
checkoutDate: attributes.checkoutDate, checkoutDate: attributes.checkoutDate,
@@ -508,6 +536,10 @@ export const userQueryRouter = router({
confirmationNumber: attributes.confirmationNumber, confirmationNumber: attributes.confirmationNumber,
hotelName: attributes.hotelInformation?.name, hotelName: attributes.hotelInformation?.name,
nights: attributes.nights, nights: attributes.nights,
pointsCalculated: attributes.pointsCalculated,
hotelId: attributes.hotelOperaId,
transactionDate: attributes.transactionDate,
bookingUrl: attributes.bookingUrl,
} }
}), }),
}, },

View File

@@ -1,4 +1,4 @@
import { awardPointsVariants } from "@/components/MyPages/Blocks/Points/EarnAndBurn/JourneyTable/Desktop/Row/awardPointsVariants" import { awardPointsVariants } from "@/components/MyPages/Blocks/Points/EarnAndBurn/JourneyTable/Table/Row/awardPointsVariants"
import type { VariantProps } from "class-variance-authority" import type { VariantProps } from "class-variance-authority"

View File

@@ -16,3 +16,17 @@ export enum ContentEntries {
AccountPageContentShortcuts = "AccountPageContentShortcuts", AccountPageContentShortcuts = "AccountPageContentShortcuts",
AccountPageContentTextContent = "AccountPageContentTextContent", AccountPageContentTextContent = "AccountPageContentTextContent",
} }
export enum RewardTransactionTypes {
stay = "stay",
rewardNight = "rewardnight",
enrollment = "enrollment",
expired = "expired",
redgift = "redgift",
ancillary = "ancillary",
pointShop = "pointshop",
tui_points = "tui_points",
mastercard_points = "mastercard_points",
stayAdj = "stay/adj",
othersAdj = "others/adj",
}