front-end/src/pages/Services.tsx
2022-07-18 11:38:44 +03:00

133 lines
5.2 KiB
TypeScript

/* -------------------------------------------------------------------------- */
/* Libraries */
/* -------------------------------------------------------------------------- */
import React, { useEffect, useState } from "react";
/* -------------------------------------------------------------------------- */
/* Components */
/* -------------------------------------------------------------------------- */
import ServiceComponent from "components/containers/ServiceComponent";
import Switch from "components/controls/Switch";
import TextAction from "components/controls/TextAction";
import ThinSingleColumn from "components/layouts/ThinSingleColumn";
import { useServicesStore } from "services/data/servicesSlice";
import { useServicesViewModel } from "services/controller/servicesViewModel";
import _ from "lodash";
import { useUIStore } from "ui/data/uiSlice";
import { useSubscriptionsStore } from "subscriptions/data/subscriptionsSlice";
import { useSubscriptionsViewModel } from "subscriptions/controller/subscriptionsViewModel";
import { Service } from "services/domain/serviceEntity";
import PasswordConfirmation from "user/views/PasswordConfirmation";
import CircleLoader from "components/CircleLoader";
import Failure from "core/failure";
/* -------------------------------------------------------------------------- */
/* Component */
/* -------------------------------------------------------------------------- */
const Services = () => {
const [password, setPassword] = useState<string | null>();
const [confirmShown, toggleConfirm] = useState(false);
const [selectedService, setSelectedService] = useState<
Service["id"] | null
>();
/* ---------------------------------- Store --------------------------------- */
const servicesStore = useServicesStore();
const uiStore = useUIStore();
const subscriptionsStore = useSubscriptionsStore();
const { services, isLoading, loadServices } = useServicesViewModel({
...servicesStore,
notify: uiStore.notify,
});
const { hasSubscription, subscribe, processingSubscription } =
useSubscriptionsViewModel(subscriptionsStore, uiStore);
/* ---------------------------------- Hooks --------------------------------- */
useEffect(() => {
loadServices();
}, [loadServices]);
useEffect(() => {
if(!selectedService || password) return;
toggleConfirm(true);
}, [selectedService, password]);
useEffect(() => {
if (!selectedService) {
return;
}
if (hasSubscription(selectedService)) {
return;
}
if (!password) {
return;
}
if (password !== null) {
subscribe(selectedService, password!)?.catch((failure) => {
if(Failure.isFailure(failure) && failure.status === 403) {
setPassword(null);
}
});
setSelectedService(null);
}
}, [selectedService, hasSubscription, subscribe, password]);
const handleSubscription = (serviceId: Service["id"]) => {
setSelectedService(serviceId);
};
/* --------------------------------- Markup --------------------------------- */
return (
<ThinSingleColumn>
<div className="space-y-8">
{!services?.length || isLoading
? _.times(3, (number) => (
<ServiceComponent key={number} variant="gray" clipText="tch">
<div className="flex items-center justify-between">
<div>
<div className="text-lg font-bold">Techpal</div>
<TextAction variant="gray">about service</TextAction>
</div>
<div>
<Switch enabled={false} onChange={() => null} />
</div>
</div>
</ServiceComponent>
))
: services!.map((item, index) => {
return (
<ServiceComponent
key={index}
variant={item.variant ?? "gray"}
clipText={item.shortName}
>
<div className="flex items-center justify-between">
<div>
<div className="text-lg font-bold">{item.name}</div>
<TextAction variant="gray">about service</TextAction>
</div>
<div>
{processingSubscription(item.id) ? (
<div className="h-6 w-6">
<CircleLoader />
</div>
) : (
<Switch
enabled={hasSubscription(item.id)}
onChange={() => handleSubscription(item.id)}
/>
)}
</div>
</div>
</ServiceComponent>
);
})}
</div>
{confirmShown && selectedService && (
<PasswordConfirmation
onSubmit={(p) => setPassword(p)}
isShown={true}
onClose={() => toggleConfirm(false)}
/>
)}
</ThinSingleColumn>
);
};
export default Services;