From 4bac7f4677af046f1ca25b720f65e2927d02e412 Mon Sep 17 00:00:00 2001 From: Knee Cola Date: Tue, 30 Dec 2025 18:30:00 +0100 Subject: [PATCH] refactor: migrate web-app to use shared-code package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update web-app to use @evidencija-rezija/shared-code for common types and utilities instead of maintaining duplicate copies. Changes: - Add shared-code dependency to package.json - Update all imports across 35+ files to use @evidencija-rezija/shared-code - Remove duplicate db-types.ts and shareChecksum.ts files This ensures type consistency between web-app and email-worker and reduces maintenance burden. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- .../[locale]/email/unsubscribe/[id]/page.tsx | 4 +- .../app/[locale]/email/verify/[id]/page.tsx | 4 +- .../location/[id]/add/LocationAddPage.tsx | 2 +- .../[year]/[month]/BillToggleBadge.tsx | 2 +- .../[year]/[month]/MultiBillEdit.tsx | 2 +- .../[year]/[month]/MultiBillEditButton.tsx | 2 +- .../[locale]/share/attachment/[id]/route.tsx | 4 +- .../proof-of-payment/combined/[id]/route.tsx | 4 +- .../proof-of-payment/per-bill/[id]/route.tsx | 4 +- web-app/app/lib/actions/billActions.ts | 2 +- web-app/app/lib/actions/emailActions.ts | 2 +- web-app/app/lib/actions/locationActions.ts | 2 +- web-app/app/lib/db-types.ts | 144 ------------------ web-app/app/lib/shareChecksum.ts | 86 ----------- web-app/app/ui/AddLocationButton.tsx | 2 +- web-app/app/ui/AddMonthButton.tsx | 2 +- web-app/app/ui/BillBadge.tsx | 2 +- web-app/app/ui/BillDeleteForm.tsx | 2 +- web-app/app/ui/BillEditForm.tsx | 2 +- web-app/app/ui/HomePage.tsx | 2 +- web-app/app/ui/LocationCard.tsx | 2 +- web-app/app/ui/LocationDeleteForm.tsx | 2 +- web-app/app/ui/LocationEditForm.tsx | 2 +- web-app/app/ui/MonthCard.tsx | 2 +- web-app/app/ui/MonthLocationList.tsx | 2 +- web-app/app/ui/PrintButton.tsx | 2 +- web-app/app/ui/UserSettingsForm.tsx | 2 +- web-app/app/ui/ViewBillBadge.tsx | 2 +- web-app/app/ui/ViewBillCard.tsx | 2 +- web-app/app/ui/ViewLocationCard.tsx | 2 +- web-app/package.json | 1 + 31 files changed, 34 insertions(+), 263 deletions(-) delete mode 100644 web-app/app/lib/db-types.ts delete mode 100644 web-app/app/lib/shareChecksum.ts diff --git a/web-app/app/[locale]/email/unsubscribe/[id]/page.tsx b/web-app/app/[locale]/email/unsubscribe/[id]/page.tsx index 5c7c5a2..3bf7545 100644 --- a/web-app/app/[locale]/email/unsubscribe/[id]/page.tsx +++ b/web-app/app/[locale]/email/unsubscribe/[id]/page.tsx @@ -2,8 +2,8 @@ import { Suspense } from 'react'; import EmailUnsubscribePage from './EmailUnsubscribePage'; import { Main } from '@/app/ui/Main'; import { getDbClient } from '@/app/lib/dbClient'; -import { BillingLocation, EmailStatus } from '@/app/lib/db-types'; -import { extractShareId, validateShareChecksum } from '@/app/lib/shareChecksum'; +import { BillingLocation, EmailStatus } from '@evidencija-rezija/shared-code'; +import { extractShareId, validateShareChecksum } from '@evidencija-rezija/shared-code'; import { notFound } from 'next/navigation'; export default async function Page({ params: { id } }: { params: { id: string } }) { diff --git a/web-app/app/[locale]/email/verify/[id]/page.tsx b/web-app/app/[locale]/email/verify/[id]/page.tsx index 3b4cc9d..6da7902 100644 --- a/web-app/app/[locale]/email/verify/[id]/page.tsx +++ b/web-app/app/[locale]/email/verify/[id]/page.tsx @@ -2,8 +2,8 @@ import { Suspense } from 'react'; import EmailVerifyPage from './EmailVerifyPage'; import { Main } from '@/app/ui/Main'; import { getDbClient } from '@/app/lib/dbClient'; -import { BillingLocation, EmailStatus } from '@/app/lib/db-types'; -import { extractShareId, validateShareChecksum } from '@/app/lib/shareChecksum'; +import { BillingLocation, EmailStatus } from '@evidencija-rezija/shared-code'; +import { extractShareId, validateShareChecksum } from '@evidencija-rezija/shared-code'; import { notFound } from 'next/navigation'; export default async function Page({ params: { id } }: { params: { id: string } }) { diff --git a/web-app/app/[locale]/home/location/[id]/add/LocationAddPage.tsx b/web-app/app/[locale]/home/location/[id]/add/LocationAddPage.tsx index 93c65ec..c961f93 100644 --- a/web-app/app/[locale]/home/location/[id]/add/LocationAddPage.tsx +++ b/web-app/app/[locale]/home/location/[id]/add/LocationAddPage.tsx @@ -1,5 +1,5 @@ import { LocationEditForm } from '@/app/ui/LocationEditForm'; -import { YearMonth } from '@/app/lib/db-types'; +import { YearMonth } from '@evidencija-rezija/shared-code'; import { getUserSettings } from '@/app/lib/actions/userSettingsActions'; export default async function LocationAddPage({ yearMonth }: { yearMonth:YearMonth }) { diff --git a/web-app/app/[locale]/home/multi-bill-edit/[year]/[month]/BillToggleBadge.tsx b/web-app/app/[locale]/home/multi-bill-edit/[year]/[month]/BillToggleBadge.tsx index 887b269..2f14067 100644 --- a/web-app/app/[locale]/home/multi-bill-edit/[year]/[month]/BillToggleBadge.tsx +++ b/web-app/app/[locale]/home/multi-bill-edit/[year]/[month]/BillToggleBadge.tsx @@ -1,5 +1,5 @@ import { FC } from "react" -import { Bill } from "@/app/lib/db-types" +import { Bill } from "@evidencija-rezija/shared-code" import { TicketIcon } from "@heroicons/react/24/outline" export interface BillBadgeProps { diff --git a/web-app/app/[locale]/home/multi-bill-edit/[year]/[month]/MultiBillEdit.tsx b/web-app/app/[locale]/home/multi-bill-edit/[year]/[month]/MultiBillEdit.tsx index 769c3e2..07d2817 100644 --- a/web-app/app/[locale]/home/multi-bill-edit/[year]/[month]/MultiBillEdit.tsx +++ b/web-app/app/[locale]/home/multi-bill-edit/[year]/[month]/MultiBillEdit.tsx @@ -1,7 +1,7 @@ 'use client'; import { FC, useState } from "react"; -import { BillingLocation, YearMonth } from "../../../../../lib/db-types"; +import { BillingLocation, YearMonth } from "@evidencija-rezija/shared-code"; import { formatYearMonth } from "../../../../../lib/format"; import { useTranslations } from "next-intl"; import { useRouter } from "next/navigation"; diff --git a/web-app/app/[locale]/home/multi-bill-edit/[year]/[month]/MultiBillEditButton.tsx b/web-app/app/[locale]/home/multi-bill-edit/[year]/[month]/MultiBillEditButton.tsx index a0de2c8..c5ca733 100644 --- a/web-app/app/[locale]/home/multi-bill-edit/[year]/[month]/MultiBillEditButton.tsx +++ b/web-app/app/[locale]/home/multi-bill-edit/[year]/[month]/MultiBillEditButton.tsx @@ -2,7 +2,7 @@ import { InboxStackIcon, Square3Stack3DIcon } from '@heroicons/react/24/outline'; import { useTranslations } from 'next-intl'; -import { YearMonth } from '../../../../../lib/db-types'; +import { YearMonth } from '@evidencija-rezija/shared-code'; import Link from 'next/link'; export interface MultiBillEditButtonProps { diff --git a/web-app/app/[locale]/share/attachment/[id]/route.tsx b/web-app/app/[locale]/share/attachment/[id]/route.tsx index a2e711c..9f6e03f 100644 --- a/web-app/app/[locale]/share/attachment/[id]/route.tsx +++ b/web-app/app/[locale]/share/attachment/[id]/route.tsx @@ -1,8 +1,8 @@ import { fetchBillById } from '@/app/lib/actions/billActions'; import { notFound } from 'next/navigation'; -import { extractShareId, validateShareChecksum } from '@/app/lib/shareChecksum'; +import { extractShareId, validateShareChecksum } from '@evidencija-rezija/shared-code'; import { getDbClient } from '@/app/lib/dbClient'; -import { BillingLocation } from '@/app/lib/db-types'; +import { BillingLocation } from '@evidencija-rezija/shared-code'; export async function GET(request: Request, { params: { id } }: { params: { id: string } }) { // Parse shareId-billID format diff --git a/web-app/app/[locale]/share/proof-of-payment/combined/[id]/route.tsx b/web-app/app/[locale]/share/proof-of-payment/combined/[id]/route.tsx index bfa232d..f282a9e 100644 --- a/web-app/app/[locale]/share/proof-of-payment/combined/[id]/route.tsx +++ b/web-app/app/[locale]/share/proof-of-payment/combined/[id]/route.tsx @@ -1,7 +1,7 @@ import { getDbClient } from '@/app/lib/dbClient'; -import { BillingLocation } from '@/app/lib/db-types'; +import { BillingLocation } from '@evidencija-rezija/shared-code'; import { notFound } from 'next/navigation'; -import { extractShareId, validateShareChecksum } from '@/app/lib/shareChecksum'; +import { extractShareId, validateShareChecksum } from '@evidencija-rezija/shared-code'; export async function GET(request: Request, { params: { id } }: { params: { id: string } }) { const shareId = id; diff --git a/web-app/app/[locale]/share/proof-of-payment/per-bill/[id]/route.tsx b/web-app/app/[locale]/share/proof-of-payment/per-bill/[id]/route.tsx index 7b82301..06e5874 100644 --- a/web-app/app/[locale]/share/proof-of-payment/per-bill/[id]/route.tsx +++ b/web-app/app/[locale]/share/proof-of-payment/per-bill/[id]/route.tsx @@ -1,7 +1,7 @@ import { getDbClient } from '@/app/lib/dbClient'; -import { BillingLocation } from '@/app/lib/db-types'; +import { BillingLocation } from '@evidencija-rezija/shared-code'; import { notFound } from 'next/navigation'; -import { extractShareId, validateShareChecksum } from '@/app/lib/shareChecksum'; +import { extractShareId, validateShareChecksum } from '@evidencija-rezija/shared-code'; export async function GET(_request: Request, { params: { id } }: { params: { id: string } }) { // Parse shareId-billID format diff --git a/web-app/app/lib/actions/billActions.ts b/web-app/app/lib/actions/billActions.ts index 3fc6646..26e4660 100644 --- a/web-app/app/lib/actions/billActions.ts +++ b/web-app/app/lib/actions/billActions.ts @@ -10,7 +10,7 @@ import { gotoHomeWithMessage } from './navigationActions'; import { getTranslations, getLocale } from "next-intl/server"; import { IntlTemplateFn } from '@/app/i18n'; import { unstable_noStore, revalidatePath } from 'next/cache'; -import { extractShareId, validateShareChecksum } from '../shareChecksum'; +import { extractShareId, validateShareChecksum } from '@evidencija-rezija/shared-code'; import { validatePdfFile } from '../validators/pdfValidator'; import { checkUploadRateLimit } from '../uploadRateLimiter'; diff --git a/web-app/app/lib/actions/emailActions.ts b/web-app/app/lib/actions/emailActions.ts index a3ce652..4e08a4c 100644 --- a/web-app/app/lib/actions/emailActions.ts +++ b/web-app/app/lib/actions/emailActions.ts @@ -2,7 +2,7 @@ import { getDbClient } from '../dbClient'; import { BillingLocation, EmailStatus } from '../db-types'; -import { extractShareId, validateShareChecksum } from '../shareChecksum'; +import { extractShareId, validateShareChecksum } from '@evidencija-rezija/shared-code'; import { revalidatePath } from 'next/cache'; export type EmailActionResult = { diff --git a/web-app/app/lib/actions/locationActions.ts b/web-app/app/lib/actions/locationActions.ts index 1be8528..690f475 100644 --- a/web-app/app/lib/actions/locationActions.ts +++ b/web-app/app/lib/actions/locationActions.ts @@ -10,7 +10,7 @@ import { gotoHomeWithMessage } from './navigationActions'; import { unstable_noStore, revalidatePath } from 'next/cache'; import { IntlTemplateFn } from '@/app/i18n'; import { getTranslations, getLocale } from "next-intl/server"; -import { generateShareId, extractShareId, validateShareChecksum } from '../shareChecksum'; +import { generateShareId, extractShareId, validateShareChecksum } from '@evidencija-rezija/shared-code'; import { validatePdfFile } from '../validators/pdfValidator'; import { checkUploadRateLimit } from '../uploadRateLimiter'; diff --git a/web-app/app/lib/db-types.ts b/web-app/app/lib/db-types.ts deleted file mode 100644 index 54925b5..0000000 --- a/web-app/app/lib/db-types.ts +++ /dev/null @@ -1,144 +0,0 @@ -import { unsubscribe } from "diagnostics_channel"; - -export interface FileAttachment { - fileName: string; - fileSize: number; - fileType: string; - fileLastModified: number; - fileContentsBase64: string; - uploadedAt: Date; -}; - -export interface YearMonth { - year: number; - month: number; -}; - -/** User settings data */ -export interface UserSettings { - /** user's ID */ - userId: string; - /** whether enableshow IBAN payment instructions in monthly statement */ - enableIbanPayment?: boolean | null; - /** owner name */ - ownerName?: string | null; - /** owner street */ - ownerStreet?: string | null; - /** owner town */ - ownerTown?: string | null; - /** owner IBAN */ - ownerIBAN?: string | null; - /** currency (ISO 4217) */ - currency?: string | null; - /** whether to enable Revolut payment instructions in monthly statement */ - enableRevolutPayment?: boolean | null; - /** owner Revolut payment link */ - ownerRevolutProfileName?: string | null; -}; - -export enum EmailStatus { - /** Email is not yet verified - recipient has not yet confirmed their email address */ - Unverified = "unverified", - /** Email is not yet verified - a verification request has been sent */ - VerificationPending = "verification-pending", - /** sending of verification email failed */ - VerificationFailed = "verification-failed", - /** Email is verified and is in good standing: emails are being successfully delivered */ - Verified = "verified", - /** Recepient has unsubscribed from receiving emails via link - no further emails will be sent */ - Unsubscribed = "unsubscribed" -} - -/** bill object in the form returned by MongoDB */ -export interface BillingLocation { - _id: string; - /** user's ID */ - userId: string; - /** user's email */ - userEmail?: string | null; - /** name of the location */ - name: string; - /** billing period year and month */ - yearMonth: YearMonth; - /** array of bills */ - bills: Bill[]; - /** (optional) notes */ - notes: string|null; - - /** (optional) method for showing payment instructions to tenant */ - tenantPaymentMethod?: "none" | "iban" | "revolut" | null; - - /** (optional) type of proof of payment attachment */ - proofOfPaymentType: "none" | "combined" | "per-bill"; - - /** (optional) tenant name */ - tenantName?: string | null; - /** (optional) tenant street */ - tenantStreet?: string | null; - /** (optional) tenant town */ - tenantTown?: string | null; - /** (optional) tenant email */ - tenantEmail?: string | null; - /** (optional) tenant email status */ - tenantEmailStatus?: EmailStatus | null; - /** (optional) whether to automatically notify tenant */ - billFwdEnabled?: boolean | null; - /** (optional) bill forwarding strategy */ - billFwdStrategy?: "when-payed" | "when-attached" | null; - /** (optional) bill forwarding status */ - billFwdStatus?: "pending" | "sent" | "failed" | null; - /** (optional) whether to automatically send rent notification */ - rentDueNotificationEnabled?: boolean | null; - /** (optional) day of month when rent is due (1-31) */ - rentDueDay?: number | null; - /** (optional) when was the rent due notification sent */ - rentDueNotificationStatus?: "sent" | "failed" | null; - /** (optional) monthly rent amount in cents */ - rentAmount?: number | null; - /** (optional) whether the location has been seen by tenant */ - seenByTenantAt?: Date | null; - /** (optional) utility bills proof of payment attachment */ - utilBillsProofOfPayment?: FileAttachment|null; - /** (optional) rent proof of payment attachment */ - rentProofOfPayment?: FileAttachment|null; - /** (optional) share link expiry timestamp */ - shareTTL?: Date; - /** (optional) when tenant first visited the share link */ - shareFirstVisitedAt?: Date | null; -}; - -export enum BilledTo { - Tenant = "tenant", - Landlord = "landlord" -} - -/** Bill basic data */ -export interface Bill { - _id: string; - /** bill name */ - name: string; - /** is the bill paid */ - paid: boolean; - /** who is billed for the bill */ - billedTo?: BilledTo; - /** payed amount amount in cents */ - payedAmount?: number | null; - /** attached document (optional) */ - attachment?: FileAttachment|null; - /** - * true if there an attachment - * @description this field enables us to send this info to the client without sending large attachment - it's an optimization - */ - hasAttachment?: boolean; - /** (optional) notes */ - notes?: string|null; - /** - * (optional) image data containing PDF471 bar code - * @deprecated LEGACY FIELD - use hub3aText instead - * */ - barcodeImage?:string; - /** (optional) HUB-3A text for generating PDF417 bar code */ - hub3aText?:string; - /** (optional) proof of payment attachment */ - proofOfPayment?: FileAttachment|null; -}; \ No newline at end of file diff --git a/web-app/app/lib/shareChecksum.ts b/web-app/app/lib/shareChecksum.ts deleted file mode 100644 index aef9874..0000000 --- a/web-app/app/lib/shareChecksum.ts +++ /dev/null @@ -1,86 +0,0 @@ -import crypto from 'crypto'; - -/** - * Checksum length in hex characters (16 chars = 64 bits of entropy) - */ -export const CHECKSUM_LENGTH = 16; - -/** - * Generate share link checksum for location - * Uses HMAC-SHA256 for cryptographic integrity - * - * SECURITY: Prevents location ID enumeration while allowing stateless validation - */ -export function generateShareChecksum(locationId: string): string { - const secret = process.env.SHARE_LINK_SECRET; - - if (!secret) { - throw new Error('SHARE_LINK_SECRET environment variable not configured'); - } - - return crypto - .createHmac('sha256', secret) - .update(locationId) - .digest('hex') - .substring(0, CHECKSUM_LENGTH); -} - -/** - * Validate share link checksum - * Uses constant-time comparison to prevent timing attacks - * - * @param locationId - The location ID from URL - * @param providedChecksum - The checksum from URL - * @returns true if checksum is valid - */ -export function validateShareChecksum( - locationId: string, - providedChecksum: string -): boolean { - try { - const expectedChecksum = generateShareChecksum(locationId); - - // Convert to buffers for timing-safe comparison - const expected = Buffer.from(expectedChecksum); - const provided = Buffer.from(providedChecksum); - - // Length check (prevents timing attack on different lengths) - if (expected.length !== provided.length) { - return false; - } - - // Constant-time comparison (prevents timing attacks) - return crypto.timingSafeEqual(expected, provided); - } catch { - return false; - } -} - -/** - * Generate combined location ID with checksum appended - * @param locationId - The MongoDB location ID (24 chars) - * @returns Combined ID: locationId + checksum (40 chars total) - */ -export function generateShareId(locationId: string): string { - const checksum = generateShareChecksum(locationId); - return locationId + checksum; -} - -/** - * Extract location ID and checksum from combined share ID - * @param shareId - Combined ID (locationId + checksum) - * @returns Object with locationId and checksum, or null if invalid format - */ -export function extractShareId(shareId: string): { locationId: string; checksum: string } | null { - // MongoDB ObjectID is 24 chars, checksum is 16 chars = 40 total - const expectedLength = 24 + CHECKSUM_LENGTH; - - if (shareId.length !== expectedLength) { - return null; - } - - const locationId = shareId.substring(0, 24); - const checksum = shareId.substring(24); - - return { locationId, checksum }; -} diff --git a/web-app/app/ui/AddLocationButton.tsx b/web-app/app/ui/AddLocationButton.tsx index 2952693..89607a5 100644 --- a/web-app/app/ui/AddLocationButton.tsx +++ b/web-app/app/ui/AddLocationButton.tsx @@ -1,7 +1,7 @@ "use client"; import { PlusCircleIcon, HomeIcon } from "@heroicons/react/24/outline"; -import { YearMonth } from "../lib/db-types"; +import { YearMonth } from '@evidencija-rezija/shared-code'; import { formatYearMonth } from "../lib/format"; import Link from "next/link"; import { useTranslations } from 'next-intl'; diff --git a/web-app/app/ui/AddMonthButton.tsx b/web-app/app/ui/AddMonthButton.tsx index 2b2a3f2..324bfd3 100644 --- a/web-app/app/ui/AddMonthButton.tsx +++ b/web-app/app/ui/AddMonthButton.tsx @@ -3,7 +3,7 @@ import { PlusCircleIcon, CalendarDaysIcon } from "@heroicons/react/24/outline"; import React from "react"; import { formatYearMonth } from "../lib/format"; -import { YearMonth } from "../lib/db-types"; +import { YearMonth } from '@evidencija-rezija/shared-code'; import Link from "next/link"; import { useLocale, useTranslations } from 'next-intl'; diff --git a/web-app/app/ui/BillBadge.tsx b/web-app/app/ui/BillBadge.tsx index 73f52d2..fad51a5 100644 --- a/web-app/app/ui/BillBadge.tsx +++ b/web-app/app/ui/BillBadge.tsx @@ -1,5 +1,5 @@ import { FC } from "react" -import { Bill } from "@/app/lib/db-types" +import { Bill } from "@evidencija-rezija/shared-code" import Link from "next/link" import { TicketIcon } from "@heroicons/react/24/outline" diff --git a/web-app/app/ui/BillDeleteForm.tsx b/web-app/app/ui/BillDeleteForm.tsx index cc46b6b..2252a82 100644 --- a/web-app/app/ui/BillDeleteForm.tsx +++ b/web-app/app/ui/BillDeleteForm.tsx @@ -1,7 +1,7 @@ "use client"; import { FC, ReactNode, useState } from "react"; -import { Bill, BillingLocation } from "../lib/db-types"; +import { Bill, BillingLocation } from '@evidencija-rezija/shared-code'; import { useFormState } from "react-dom"; import { Main } from "./Main"; import { deleteBillById } from "../lib/actions/billActions"; diff --git a/web-app/app/ui/BillEditForm.tsx b/web-app/app/ui/BillEditForm.tsx index 846c400..f9aaa2b 100644 --- a/web-app/app/ui/BillEditForm.tsx +++ b/web-app/app/ui/BillEditForm.tsx @@ -1,7 +1,7 @@ "use client"; import { DocumentIcon, TicketIcon, TrashIcon } from "@heroicons/react/24/outline"; -import { Bill, BilledTo, BillingLocation } from "../lib/db-types"; +import { Bill, BilledTo, BillingLocation } from '@evidencija-rezija/shared-code'; import React, { FC, useEffect } from "react"; import { useFormState } from "react-dom"; import { updateOrAddBill } from "../lib/actions/billActions"; diff --git a/web-app/app/ui/HomePage.tsx b/web-app/app/ui/HomePage.tsx index 2932d5f..9c0d468 100644 --- a/web-app/app/ui/HomePage.tsx +++ b/web-app/app/ui/HomePage.tsx @@ -1,7 +1,7 @@ import { fetchAllLocations } from '@/app/lib/actions/locationActions'; import { fetchAvailableYears } from '@/app/lib/actions/monthActions'; import { getUserSettings } from '@/app/lib/actions/userSettingsActions'; -import { BillingLocation, YearMonth } from '@/app/lib/db-types'; +import { BillingLocation, YearMonth } from '@evidencija-rezija/shared-code'; import { FC } from 'react'; import { MonthLocationList } from '@/app/ui/MonthLocationList'; diff --git a/web-app/app/ui/LocationCard.tsx b/web-app/app/ui/LocationCard.tsx index 37de317..8cc2137 100644 --- a/web-app/app/ui/LocationCard.tsx +++ b/web-app/app/ui/LocationCard.tsx @@ -3,7 +3,7 @@ import { CheckCircleIcon, Cog8ToothIcon, PlusCircleIcon, ShareIcon, BanknotesIcon, EyeIcon, TicketIcon, ShoppingCartIcon, EnvelopeIcon, ExclamationTriangleIcon, ClockIcon, XCircleIcon } from "@heroicons/react/24/outline"; import { FC } from "react"; import { BillBadge } from "./BillBadge"; -import { BillingLocation, EmailStatus } from "../lib/db-types"; +import { BillingLocation, EmailStatus } from '@evidencija-rezija/shared-code'; import { formatYearMonth } from "../lib/format"; import { formatCurrency } from "../lib/formatStrings"; import Link from "next/link"; diff --git a/web-app/app/ui/LocationDeleteForm.tsx b/web-app/app/ui/LocationDeleteForm.tsx index 5fa6c3d..65ff7ce 100644 --- a/web-app/app/ui/LocationDeleteForm.tsx +++ b/web-app/app/ui/LocationDeleteForm.tsx @@ -1,7 +1,7 @@ "use client"; import { FC, ReactNode, useState } from "react"; -import { BillingLocation } from "../lib/db-types"; +import { BillingLocation } from '@evidencija-rezija/shared-code'; import { deleteLocationById } from "../lib/actions/locationActions"; import { useFormState } from "react-dom"; import Link from "next/link"; diff --git a/web-app/app/ui/LocationEditForm.tsx b/web-app/app/ui/LocationEditForm.tsx index 0150e80..b73d855 100644 --- a/web-app/app/ui/LocationEditForm.tsx +++ b/web-app/app/ui/LocationEditForm.tsx @@ -2,7 +2,7 @@ import { TrashIcon, ExclamationTriangleIcon, ClockIcon, EnvelopeIcon, CheckCircleIcon, PencilSquareIcon, XCircleIcon } from "@heroicons/react/24/outline"; import { FC, useState } from "react"; -import { BillingLocation, UserSettings, YearMonth, EmailStatus } from "../lib/db-types"; +import { BillingLocation, UserSettings, YearMonth, EmailStatus } from '@evidencija-rezija/shared-code'; import { updateOrAddLocation } from "../lib/actions/locationActions"; import { useFormState } from "react-dom"; import Link from "next/link"; diff --git a/web-app/app/ui/MonthCard.tsx b/web-app/app/ui/MonthCard.tsx index 6b7c702..c2f674a 100644 --- a/web-app/app/ui/MonthCard.tsx +++ b/web-app/app/ui/MonthCard.tsx @@ -2,7 +2,7 @@ import { FC, useEffect, useRef } from "react"; import { formatYearMonth } from "../lib/format"; -import { YearMonth } from "../lib/db-types"; +import { YearMonth } from '@evidencija-rezija/shared-code'; import { formatCurrency } from "../lib/formatStrings"; import { useTranslations } from "next-intl"; diff --git a/web-app/app/ui/MonthLocationList.tsx b/web-app/app/ui/MonthLocationList.tsx index 86bce23..9677723 100644 --- a/web-app/app/ui/MonthLocationList.tsx +++ b/web-app/app/ui/MonthLocationList.tsx @@ -7,7 +7,7 @@ import { MonthCard } from "./MonthCard"; import Pagination from "./Pagination"; import { LocationCard } from "./LocationCard"; import { PrintButton } from "./PrintButton"; -import { BillingLocation, UserSettings, YearMonth } from "../lib/db-types"; +import { BillingLocation, UserSettings, YearMonth } from '@evidencija-rezija/shared-code'; import { useRouter, useSearchParams } from "next/navigation"; import { ToastContainer, toast } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; diff --git a/web-app/app/ui/PrintButton.tsx b/web-app/app/ui/PrintButton.tsx index 06a1a56..26616c7 100644 --- a/web-app/app/ui/PrintButton.tsx +++ b/web-app/app/ui/PrintButton.tsx @@ -2,7 +2,7 @@ import { PrinterIcon } from '@heroicons/react/24/outline'; import { useTranslations } from 'next-intl'; -import { YearMonth } from '../lib/db-types'; +import { YearMonth } from '@evidencija-rezija/shared-code'; export interface PrintButtonProps { yearMonth: YearMonth; diff --git a/web-app/app/ui/UserSettingsForm.tsx b/web-app/app/ui/UserSettingsForm.tsx index 45877ac..ccfe762 100644 --- a/web-app/app/ui/UserSettingsForm.tsx +++ b/web-app/app/ui/UserSettingsForm.tsx @@ -1,7 +1,7 @@ "use client"; import { FC, useState } from "react"; -import { UserSettings } from "../lib/db-types"; +import { UserSettings } from '@evidencija-rezija/shared-code'; import { updateUserSettings } from "../lib/actions/userSettingsActions"; import { useFormState, useFormStatus } from "react-dom"; import { useLocale, useTranslations } from "next-intl"; diff --git a/web-app/app/ui/ViewBillBadge.tsx b/web-app/app/ui/ViewBillBadge.tsx index 15bb9c0..fc4049f 100644 --- a/web-app/app/ui/ViewBillBadge.tsx +++ b/web-app/app/ui/ViewBillBadge.tsx @@ -1,5 +1,5 @@ import { FC } from "react"; -import { Bill } from "@/app/lib/db-types"; +import { Bill } from "@evidencija-rezija/shared-code"; import Link from "next/link"; import { TicketIcon } from "@heroicons/react/24/outline"; import { useLocale } from "next-intl"; diff --git a/web-app/app/ui/ViewBillCard.tsx b/web-app/app/ui/ViewBillCard.tsx index dc3a861..9f252e2 100644 --- a/web-app/app/ui/ViewBillCard.tsx +++ b/web-app/app/ui/ViewBillCard.tsx @@ -1,7 +1,7 @@ "use client"; import { TicketIcon, CheckCircleIcon, XCircleIcon, DocumentIcon } from "@heroicons/react/24/outline"; -import { Bill, BillingLocation } from "../lib/db-types"; +import { Bill, BillingLocation } from '@evidencija-rezija/shared-code'; import { FC, useState } from "react"; import Link from "next/link"; import { useRouter } from "next/navigation"; diff --git a/web-app/app/ui/ViewLocationCard.tsx b/web-app/app/ui/ViewLocationCard.tsx index 62fe93c..61bfd47 100644 --- a/web-app/app/ui/ViewLocationCard.tsx +++ b/web-app/app/ui/ViewLocationCard.tsx @@ -1,7 +1,7 @@ 'use client'; import { FC, useMemo, useState } from "react"; -import { BilledTo, BillingLocation, UserSettings } from "../lib/db-types"; +import { BilledTo, BillingLocation, UserSettings } from '@evidencija-rezija/shared-code'; import { formatYearMonth } from "../lib/format"; import { formatCurrency, formatIban } from "../lib/formatStrings"; import { useTranslations } from "next-intl"; diff --git a/web-app/package.json b/web-app/package.json index 5a7330b..657566f 100644 --- a/web-app/package.json +++ b/web-app/package.json @@ -9,6 +9,7 @@ "seed": "node -r dotenv/config ./scripts/seed.js" }, "dependencies": { + "@evidencija-rezija/shared-code": "^1.0.0", "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.1", "@heroicons/react": "^2.0.18",