src/components/molecules/AdminSpaceCard/AdminSpaceCard.tsx
import React from "react";
import { Link } from "react-router-dom";
import { useCss } from "react-use";
import { faExternalLinkAlt, faUsers } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import classNames from "classnames";
import {
ATTENDEE_INSIDE_URL,
DEFAULT_VENUE_BANNER_COLOR,
DEFAULT_VENUE_LOGO,
PORTAL_INFO_ICON_MAPPING,
SPACE_TAXON,
} from "settings";
import { AnyVenue } from "types/venues";
import { WorldSlug } from "types/world";
import { WithId } from "utils/id";
import { adminNGVenueUrl, generateUrl } from "utils/url";
import { useValidImage } from "hooks/useCheckImage";
import { AdminCardTitle } from "components/organisms/AdminVenueView/components/AdminCardTitle";
import { ButtonNG } from "components/atoms/ButtonNG";
import "./AdminSpaceCard.scss";
export interface AdminSpaceCardProps {
venue: WithId<AnyVenue>;
worldSlug?: WorldSlug;
isEditable?: boolean;
}
export const AdminSpaceCard: React.FC<AdminSpaceCardProps> = ({
venue,
worldSlug,
isEditable,
}) => {
const [validBannerImageUrl] = useValidImage(
venue?.config?.landingPageConfig.coverImageUrl ||
venue?.config?.landingPageConfig.bannerImageUrl,
DEFAULT_VENUE_BANNER_COLOR
);
const backgroundStyle = useCss({
// @debt There should be a way to move the rgba() functions to SCSS and use $color-constant instead of literals
background: `linear-gradient(
rgba(25, 24, 26, 0.8),
rgba(25, 24, 26, 0.8)
), url(${validBannerImageUrl})`,
});
const backgroundClasses = classNames("AdminSpaceCard__bg", backgroundStyle);
const logoStyle = useCss({
"background-image": `url(${venue.host?.icon || DEFAULT_VENUE_LOGO})`,
});
const logoClasses = classNames("AdminSpaceCard__logo", logoStyle);
const spaceIcon = PORTAL_INFO_ICON_MAPPING[venue.template];
const spaceDescriptionText =
venue.config?.landingPageConfig?.description ||
"Description can be changed in space settings";
return (
<div className="AdminSpaceCard">
<div className={backgroundClasses}>
<div className="AdminSpaceCard__bg-container">
<Link
className="AdminSpaceCard__link"
to={generateUrl({
route: ATTENDEE_INSIDE_URL,
required: ["worldSlug", "spaceSlug"],
params: { worldSlug, spaceSlug: venue.slug },
})}
target="_blank"
rel="noopener noreferer"
>
Visit
<FontAwesomeIcon
className="AdminSpaceCard__link-icon"
icon={faExternalLinkAlt}
/>
</Link>
<div className="AdminSpaceCard__body">
<div className={logoClasses} />
<div className="AdminSpaceCard__body-info">
<AdminCardTitle>{venue.name}</AdminCardTitle>
<span className="AdminSpaceCard__text">
<img
alt={`the ${SPACE_TAXON.lower} icon`}
src={spaceIcon}
className="SpacesDropdown__item-icon"
/>
{venue.template}
</span>
{venue.rooms?.length ? (
<span className="AdminSpaceCard__text">{`${venue.rooms?.length} experiences`}</span>
) : null}
</div>
</div>
{!!venue.recentUserCount && (
<div className="AdminSpaceCard__user-count">
<FontAwesomeIcon
className="AdminSpaceCard__icon"
icon={faUsers}
/>
{venue.recentUserCount}
</div>
)}
</div>
</div>
<div className="AdminSpaceCard__footer">
<div className="AdminSpaceCard__footer-content">
<div className="AdminSpaceCard__description">
<span className="AdminSpaceCard__description-text">
{spaceDescriptionText}
</span>
</div>
<ButtonNG
linkTo={
worldSlug && venue.slug
? adminNGVenueUrl(worldSlug, venue.slug)
: "#"
}
disabled={!venue.slug || !isEditable}
>
Edit
</ButtonNG>
</div>
</div>
</div>
);
};