refactored to make use of the ServiceType enum throughout backend and frontend for typesafety

This commit is contained in:
2026-06-24 23:25:18 +02:00
parent 38c72d1bb8
commit fb64a7787f
24 changed files with 278 additions and 263 deletions
+2 -2
View File
@@ -1,5 +1,5 @@
import { apiFetch } from './client'
import type { AuthResponse, ConnectionStatus, LoginRequest } from '../types/connection'
import type { AuthResponse, ConnectionStatus, LoginRequest, ServiceType } from '../types/connection'
export const login = (req: LoginRequest) =>
apiFetch<AuthResponse>('/login', { method: 'POST', body: JSON.stringify(req) })
@@ -7,5 +7,5 @@ export const login = (req: LoginRequest) =>
export const getStatuses = () =>
apiFetch<ConnectionStatus[]>('/connections/status')
export const logout = (serviceType: string) =>
export const logout = (serviceType: ServiceType) =>
apiFetch<void>(`/connections/${serviceType}`, { method: 'DELETE' })
@@ -1,10 +1,10 @@
import { useEffect, useRef, useState, type SyntheticEvent } from 'react'
import { login } from '../../api/connections'
import type { LoginRequest } from '../../types/connection'
import type { LoginRequest, ServiceType } from '../../types/connection'
import '../ui/Modal.scss'
interface Props {
serviceType: string
serviceType: ServiceType
label: string
onClose: () => void
onSuccess: () => void
@@ -1,13 +1,13 @@
import { useState, useEffect } from "react"
import { getStatuses, logout } from "../../api/connections"
import type { ConnectionStatus } from "../../types/connection"
import { ServiceType, type ConnectionStatus } from "../../types/connection"
import { ServiceCard } from "./ServiceCard"
import { ConnectModal } from "./ConnectModal"
import "./Dashboard.scss"
import { SearchModal } from "../search/SearchModal"
const SERVICES = [
{ serviceType: 'HOMEBOX', label: 'Homebox', icon: '📦' },
{ serviceType: ServiceType.HOMEBOX, label: 'Homebox', icon: '📦' },
] as const
export function Dashboard() {
@@ -21,7 +21,7 @@ export function Dashboard() {
useEffect(() => { refresh() }, [])
const handleDisconnect = (serviceType: string) => {
const handleDisconnect = (serviceType: ServiceType) => {
logout(serviceType).then(refresh).catch(() => { })
}
@@ -1,9 +1,9 @@
import type { ConnectionStatus } from '../../types/connection'
import type { ConnectionStatus, ServiceType } from '../../types/connection'
import { ActionButton } from '../ui/ActionButton'
import './ServiceCard.scss'
interface Props {
serviceType: string
serviceType: ServiceType
label: string
icon: string
status: ConnectionStatus | null
@@ -2,9 +2,10 @@ import { useEffect, useRef, useState, type SyntheticEvent } from 'react'
import '../ui/Modal.scss'
import { type PagedSearchResponse, type SearchResponse, type SearchRequest } from '../../types/search'
import { search } from '../../api/searches'
import type { ServiceType } from '../../types/connection'
interface Props {
serviceType: string
serviceType: ServiceType
label: string
appUrl: string
username: string
+18 -12
View File
@@ -1,20 +1,26 @@
export const ServiceType = {
HOMEBOX: "HOMEBOX",
} as const;
export type ServiceType = (typeof ServiceType)[keyof typeof ServiceType];
export interface LoginRequest {
appUrl: string
serviceType: string
username: string
password: string
stayLoggedIn: boolean
appUrl: string;
serviceType: ServiceType;
username: string;
password: string;
stayLoggedIn: boolean;
}
export interface AuthResponse {
serviceType: string
expiresAt: string
serviceType: ServiceType;
expiresAt: string;
}
export interface ConnectionStatus {
serviceType: string
appUrl: string
username: string
expiresAt: string | null
connected: boolean
serviceType: ServiceType;
appUrl: string;
username: string;
expiresAt: string | null;
connected: boolean;
}
+17 -15
View File
@@ -1,23 +1,25 @@
import type { ServiceType } from "./connection";
export interface SearchRequest {
appUrl: string;
serviceType: string;
username: string;
query: string | null;
appUrl: string
serviceType: ServiceType
username: string
query: string | null
}
export interface SearchResponse {
id: string;
title: string;
description: string | null;
extraData: Record<string, unknown>;
id: string
title: string
description: string | null
extraData: Record<string, unknown>
}
export interface PagedSearchResponse<T> {
content: T[];
page: number;
pageSize: number;
totalElements: number;
first: boolean;
last: boolean;
sort: string;
content: T[]
page: number
pageSize: number
totalElements: number
first: boolean
last: boolean
sort: string
}