104 lines
5.2 KiB
JavaScript
104 lines
5.2 KiB
JavaScript
import { account } from './appwrite'
|
|
import { createFinanceRequest } from './financeRequest'
|
|
import { createJwtCache } from './serverpulsAuth'
|
|
|
|
/**
|
|
* Client fuer den Team-Eingang des Kundenportals (/api/team): alle Mitarbeiter, Appwrite-JWT (Bearer).
|
|
* Anfrage-Kern (JWT-Cache, Wiederholung bei 401, deutsche Fehlertexte) wie bei den Finanzen: financeRequest.js.
|
|
*/
|
|
export const PORTAL_URL =
|
|
import.meta.env.VITE_PROJECT_ADMIN_URL || 'https://project.webklar.com'
|
|
|
|
const request = createFinanceRequest({ baseUrl: `${PORTAL_URL}/api/team`, createJWT: () => account.createJWT() })
|
|
|
|
// Eigenes JWT fuer Anfragen, die nicht ueber request laufen (Hochladen im Chat-Baustein), 10 Minuten gecacht
|
|
const jwtCache = createJwtCache({ createJWT: () => account.createJWT() })
|
|
|
|
const enc = encodeURIComponent
|
|
|
|
/** { hasAccess, lastLoginAt } */
|
|
export const getCustomerPortalStatus = (customerId) => request(`/customers/${enc(customerId)}/portal`)
|
|
|
|
/** { entries: [{ id, at, staffName, action, detail }] }, neueste zuerst */
|
|
export const getCustomerViewLog = (customerId) => request(`/customers/${enc(customerId)}/protokoll`)
|
|
|
|
/** Einmal-Link (60 s) in die Kundenansicht des Portals */
|
|
export async function createKundenansichtLink(customerId) {
|
|
const { openUrl } = await request(`/customers/${enc(customerId)}/kundenansicht`, { method: 'POST', body: {} })
|
|
return openUrl
|
|
}
|
|
|
|
/** Einmal-Link fuer die Preview eines Projekts */
|
|
export async function createPreviewLink({ subdomain, previewUrl }) {
|
|
const { openUrl } = await request('/preview-link', { method: 'POST', body: { subdomain, previewUrl } })
|
|
return openUrl
|
|
}
|
|
|
|
// --- Chat (Messenger, Reiter "Chat", Zahl in der Sidebar) ---
|
|
|
|
/** { chats: [{ customerId, customerName, lastText, lastSender, lastAt, unreadFromCustomer }] } */
|
|
export const listChats = () => request('/chats')
|
|
|
|
/** { unread } */
|
|
export const getChatUnreadCount = () => request('/chats/unread-count')
|
|
|
|
/** { messages }; mit since nur neuere (Abfrage im offenen Gespraech) */
|
|
export const getChatMessages = (customerId, since = '') =>
|
|
request(`/chats/${enc(customerId)}/messages${since ? `?since=${enc(since)}` : ''}`)
|
|
|
|
/** { message, notice } */
|
|
export const sendChatMessage = (customerId, { text, attachmentIds }) =>
|
|
request(`/chats/${enc(customerId)}/messages`, { method: 'POST', body: { text, attachmentIds } })
|
|
|
|
export const markChatRead = (customerId) => request(`/chats/${enc(customerId)}/read`, { method: 'POST', body: {} })
|
|
|
|
/** Upload-Adresse fuer den Chat-Baustein (POST roh, DELETE <url>/<id>) */
|
|
export const chatUploadUrl = (customerId) => `${PORTAL_URL}/api/team/chats/${enc(customerId)}/attachments`
|
|
|
|
/** Header fuer den Chat-Baustein (Option requestHeaders) */
|
|
export async function teamAuthHeaders() {
|
|
return { Authorization: `Bearer ${await jwtCache.get()}` }
|
|
}
|
|
|
|
// --- Gutschriften (Uebernahmegutschriften) ---
|
|
|
|
const query = (params) => {
|
|
const q = new URLSearchParams(Object.entries(params).filter(([, v]) => v !== undefined && v !== null && v !== '')).toString()
|
|
return q ? `?${q}` : ''
|
|
}
|
|
|
|
/** { requests, openCount }; status 'open' (Standard) oder 'all', optional nur ein Kunde */
|
|
export const listCredits = ({ status = 'open', customerId } = {}) => request(`/takeover-credits${query({ status, customerId })}`)
|
|
export const getCreditOpenCount = () => request('/takeover-credits/open-count')
|
|
export const getCredit = (id) => request(`/takeover-credits/${enc(id)}`)
|
|
export const calcCredit = (body) => request('/takeover-credits/calc', { method: 'POST', body })
|
|
export const decideCredit = (id, body) => request(`/takeover-credits/${enc(id)}/decision`, { method: 'POST', body })
|
|
export const applyCredit = (id) => request(`/takeover-credits/${enc(id)}/apply`, { method: 'POST', body: {} })
|
|
|
|
// --- Abo-Angebote ---
|
|
|
|
export const listOffers = ({ customerId } = {}) => request(`/offers${query({ customerId })}`)
|
|
export const getOfferContext = (customerId) => request(`/offers/context/${enc(customerId)}`)
|
|
export const createOffer = (body) => request('/offers', { method: 'POST', body })
|
|
export const withdrawOffer = (id) => request(`/offers/${enc(id)}/withdraw`, { method: 'POST', body: {} })
|
|
export const notifyOffer = (id) => request(`/offers/${enc(id)}/notify`, { method: 'POST', body: {} })
|
|
|
|
// --- E-Mail-Speicher ---
|
|
|
|
export const listStorageTasks = () => request('/storage-tasks')
|
|
export const getStorageOpenCount = () => request('/storage-tasks/open-count')
|
|
export const markStorageDone = (id) => request(`/storage-tasks/${enc(id)}/done`, { method: 'POST', body: {} })
|
|
|
|
// --- Funktionen (News-Pinnwand, Terminplaner je Projekt) ---
|
|
|
|
export const getFunktionen = (customerId) => request(`/funktionen/${enc(customerId)}`)
|
|
/** Aktivieren (ohne Zahlung) oder Abschalten einer Funktion (key: news | termine); Antwort { projects: [das eine Projekt] }. */
|
|
export const setFeature = (customerId, key, { projectId, action, note }) =>
|
|
request(`/funktionen/${enc(customerId)}/${enc(key)}`, { method: 'POST', body: { projectId, action, note } })
|
|
export const setNewsFeature = (customerId, body) => setFeature(customerId, 'news', body)
|
|
|
|
// --- Abo-Status (alle Mitarbeiter) ---
|
|
|
|
/** { productKey, active, status, storageUnits, startedAt, serviceStart, currentPeriodEnd, cancelAt } */
|
|
export const getCustomerAboStatus = (customerId) => request(`/customers/${enc(customerId)}/abo`)
|