Cleanup assets
This commit is contained in:
@@ -15,7 +15,7 @@ import { useMessages, useTranslation } from "../../../contexts/MessagesContext";
|
||||
import Chip from "../../../components/controls/Chip";
|
||||
import IncrementerBlock from "../../../components/controls/IncrementerBlock";
|
||||
import Upload from "../../../components/controls/Upload";
|
||||
import { getAssetPath } from "../../../../lib/assetUtils";
|
||||
import { ASSETS, getAssetPath } from "../../../../lib/assetUtils";
|
||||
import ApplicableScopeField from "./ApplicableScopeField";
|
||||
import InputLabel from "../../../components/type/InputLabel";
|
||||
import type { CustomMethodCardFieldBlock } from "../../../../lib/create/customMethodCardFieldBlocks";
|
||||
@@ -139,7 +139,7 @@ function CustomMethodCardUploadBlockRow({
|
||||
>
|
||||
{/* eslint-disable-next-line @next/next/no-img-element -- matches ModalHeader close control */}
|
||||
<img
|
||||
src={getAssetPath("assets/Icon_Close.svg")}
|
||||
src={getAssetPath(ASSETS.ICON_CLOSE)}
|
||||
alt=""
|
||||
className="h-[16px] w-[16px]"
|
||||
style={{
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { memo } from "react";
|
||||
import { getAssetPath } from "../../../../../lib/assetUtils";
|
||||
import { ASSETS, getAssetPath } from "../../../../../lib/assetUtils";
|
||||
import InputWithCounter from "../../../../components/controls/InputWithCounter";
|
||||
import TextArea from "../../../../components/controls/TextArea";
|
||||
import TextInput from "../../../../components/controls/TextInput";
|
||||
@@ -140,7 +140,7 @@ function CustomMethodCardWizardFieldBodiesViewComponent({
|
||||
>
|
||||
{/* eslint-disable-next-line @next/next/no-img-element -- matches ModalHeader close control */}
|
||||
<img
|
||||
src={getAssetPath("assets/Icon_Close.svg")}
|
||||
src={getAssetPath(ASSETS.ICON_CLOSE)}
|
||||
alt=""
|
||||
className="h-[16px] w-[16px]"
|
||||
style={{
|
||||
|
||||
@@ -14,7 +14,7 @@ import { CreateFlowHeaderLockup } from "../../components/CreateFlowHeaderLockup"
|
||||
import { CreateFlowStepShell } from "../../components/CreateFlowStepShell";
|
||||
import { CREATE_FLOW_MD_UP_COLUMN_MAX_CLASS } from "../../components/createFlowLayoutTokens";
|
||||
import { fetchAuthSession } from "../../../../../lib/create/api";
|
||||
import { getAssetPath } from "../../../../../lib/assetUtils";
|
||||
import { ASSETS, getAssetPath } from "../../../../../lib/assetUtils";
|
||||
import {
|
||||
UploadToServerError,
|
||||
uploadCreateFlowFile,
|
||||
@@ -177,7 +177,7 @@ export function CommunityUploadScreen() {
|
||||
>
|
||||
{/* eslint-disable-next-line @next/next/no-img-element -- matches ModalHeader close control */}
|
||||
<img
|
||||
src={getAssetPath("assets/Icon_Close.svg")}
|
||||
src={getAssetPath(ASSETS.ICON_CLOSE)}
|
||||
alt=""
|
||||
className="h-[16px] w-[16px]"
|
||||
style={{
|
||||
|
||||
@@ -135,7 +135,7 @@ export default async function BlogPostPage({ params }: PageProps) {
|
||||
url: "https://communityrule.com",
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
url: "https://communityrule.com/assets/logo/Logo.svg",
|
||||
url: "https://communityrule.com/assets/logos/community-rule.svg",
|
||||
},
|
||||
},
|
||||
datePublished: post.frontmatter.date,
|
||||
|
||||
@@ -7,10 +7,10 @@ export type CaseStudySurfaceValue = (typeof CASE_STUDY_SURFACE_OPTIONS)[number];
|
||||
export interface CaseStudyProps {
|
||||
surface: CaseStudySurfaceValue;
|
||||
/**
|
||||
* Alt text for built-in raster art (`public/assets/use-cases/`) when **`visual`** is omitted.
|
||||
* Alt text for built-in SVG art (`public/assets/case-study/`) when **`visual`** is omitted.
|
||||
*/
|
||||
imageAlt?: string;
|
||||
/** Overrides built-in raster with custom slot content when provided. */
|
||||
/** Overrides built-in artwork with custom slot content when provided. */
|
||||
visual?: ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import Image from "next/image";
|
||||
import { memo } from "react";
|
||||
import { caseStudyVisualPath, getAssetPath } from "../../../../lib/assetUtils";
|
||||
import type { CaseStudyProps } from "./CaseStudy.types";
|
||||
|
||||
const SURFACE_CLASS: Record<CaseStudyProps["surface"], string> = {
|
||||
@@ -12,9 +13,9 @@ const SURFACE_CLASS: Record<CaseStudyProps["surface"], string> = {
|
||||
|
||||
/** Default art per tile: Figma-exported SVG composites (305×305 incl. rounded bg). */
|
||||
const SURFACE_ART: Record<CaseStudyProps["surface"], string> = {
|
||||
lavender: "/assets/case-study/case-study-mutual-aid.svg",
|
||||
neutral: "/assets/case-study/case-study-food-not-bombs.svg",
|
||||
rose: "/assets/case-study/case-study-boulder-county-street-medics.svg",
|
||||
lavender: getAssetPath(caseStudyVisualPath("lavender")),
|
||||
neutral: getAssetPath(caseStudyVisualPath("neutral")),
|
||||
rose: getAssetPath(caseStudyVisualPath("rose")),
|
||||
};
|
||||
|
||||
/** Figma: ~23px corner (“Card / CaseStudy” shells). */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import ListItem from "../../layout/ListItem";
|
||||
import Popover from "../Popover";
|
||||
import { getAssetPath } from "../../../../lib/assetUtils";
|
||||
import { ASSETS, getAssetPath } from "../../../../lib/assetUtils";
|
||||
import type { ModalHeaderProps } from "./ModalHeader.types";
|
||||
|
||||
const iconButtonClass =
|
||||
@@ -37,7 +37,7 @@ export function ModalHeaderView({
|
||||
>
|
||||
{/* eslint-disable-next-line @next/next/no-img-element -- icon asset */}
|
||||
<img
|
||||
src={getAssetPath("assets/Icon_Close.svg")}
|
||||
src={getAssetPath(ASSETS.ICON_CLOSE)}
|
||||
alt=""
|
||||
className="w-[16px] h-[16px]"
|
||||
style={{
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
import Image from "next/image";
|
||||
import { memo } from "react";
|
||||
import {
|
||||
getAssetPath,
|
||||
shareIconPath,
|
||||
type ShareIconName,
|
||||
} from "../../../../lib/assetUtils";
|
||||
import ContentLockup from "../../type/ContentLockup";
|
||||
import Button from "../../buttons/Button";
|
||||
import ModalHeader from "../ModalHeader";
|
||||
@@ -9,21 +14,16 @@ import ModalFooter from "../ModalFooter";
|
||||
import { CreateModalFrameView } from "../Create/CreateModalFrame.view";
|
||||
import type { ShareChannelTileProps, ShareViewProps } from "./Share.types";
|
||||
|
||||
/** Decorative glyphs in `public/assets/Share/` — sizes match prior inline SVGs within the 60×60 circles. */
|
||||
/** Decorative glyphs in `public/assets/share/` — sizes match prior inline SVGs within the 60×60 circles. */
|
||||
function ShareAssetIcon(props: {
|
||||
src:
|
||||
| "/assets/Share/Discord.svg"
|
||||
| "/assets/Share/Link.svg"
|
||||
| "/assets/Share/Mail.svg"
|
||||
| "/assets/Share/Signal.svg"
|
||||
| "/assets/Share/Slack.svg";
|
||||
name: ShareIconName;
|
||||
width: number;
|
||||
height: number;
|
||||
}) {
|
||||
const { src, width, height } = props;
|
||||
const { name, width, height } = props;
|
||||
return (
|
||||
<Image
|
||||
src={src}
|
||||
src={getAssetPath(shareIconPath(name))}
|
||||
alt=""
|
||||
width={width}
|
||||
height={height}
|
||||
@@ -111,31 +111,31 @@ export const ShareView = memo(function ShareView({
|
||||
label={copyLinkLabel}
|
||||
onClick={onCopyLink}
|
||||
circleClassName="border-[#444444] bg-[#333333]"
|
||||
icon={<ShareAssetIcon src="/assets/Share/Link.svg" width={24} height={24} />}
|
||||
icon={<ShareAssetIcon name="link" width={24} height={24} />}
|
||||
/>
|
||||
<ShareChannelTile
|
||||
label={signalLabel}
|
||||
onClick={onSignalShare}
|
||||
circleClassName="border-[#3a76f0] bg-[#3a76f0]"
|
||||
icon={<ShareAssetIcon src="/assets/Share/Signal.svg" width={26} height={26} />}
|
||||
icon={<ShareAssetIcon name="signal" width={26} height={26} />}
|
||||
/>
|
||||
<ShareChannelTile
|
||||
label={slackLabel}
|
||||
onClick={onSlackShare}
|
||||
circleClassName="border-[#4a154b] bg-[#4a154b]"
|
||||
icon={<ShareAssetIcon src="/assets/Share/Slack.svg" width={26} height={26} />}
|
||||
icon={<ShareAssetIcon name="slack" width={26} height={26} />}
|
||||
/>
|
||||
<ShareChannelTile
|
||||
label={discordLabel}
|
||||
onClick={onDiscordShare}
|
||||
circleClassName="border-[#5865f2] bg-[#5865f2]"
|
||||
icon={<ShareAssetIcon src="/assets/Share/Discord.svg" width={30} height={30} />}
|
||||
icon={<ShareAssetIcon name="discord" width={30} height={30} />}
|
||||
/>
|
||||
<ShareChannelTile
|
||||
label={emailLabel}
|
||||
onClick={onEmailShare}
|
||||
circleClassName="border-[var(--color-surface-default-brand-kiwi)] bg-[var(--color-surface-default-brand-kiwi)]"
|
||||
icon={<ShareAssetIcon src="/assets/Share/Mail.svg" width={24} height={24} />}
|
||||
icon={<ShareAssetIcon name="mail" width={24} height={24} />}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -25,9 +25,9 @@ const NAV_SIZE_TO_MENU_ITEM_SIZE: Record<NavSize, MenuClusterSize> = {
|
||||
};
|
||||
|
||||
export const avatarImages = [
|
||||
{ src: getAssetPath(ASSETS.AVATAR_1), alt: "Avatar 1" },
|
||||
{ src: getAssetPath(ASSETS.AVATAR_2), alt: "Avatar 2" },
|
||||
{ src: getAssetPath(ASSETS.AVATAR_3), alt: "Avatar 3" },
|
||||
{ src: getAssetPath(ASSETS.AVATAR_2), alt: "Avatar 2" },
|
||||
{ src: getAssetPath(ASSETS.AVATAR_1), alt: "Avatar 1" },
|
||||
];
|
||||
|
||||
const TopContainer = memo<TopProps>(
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { memo } from "react";
|
||||
import Script from "next/script";
|
||||
import { useTranslation } from "../../../contexts/MessagesContext";
|
||||
import { getAssetPath } from "../../../../lib/assetUtils";
|
||||
import { ASSETS, getAssetPath } from "../../../../lib/assetUtils";
|
||||
import Menu from "../Menu";
|
||||
import type { TopViewProps } from "./Top.types";
|
||||
|
||||
@@ -61,21 +61,21 @@ function TopView({
|
||||
{/* Decorative Union images for tab appearance */}
|
||||
{/* eslint-disable-next-line @next/next/no-img-element -- decorative SVG, not content */}
|
||||
<img
|
||||
src={getAssetPath("assets/Union_xsm.svg")}
|
||||
src={getAssetPath(ASSETS.UNION_XSM)}
|
||||
alt=""
|
||||
role="presentation"
|
||||
className="absolute -bottom-[3px] -right-[52px] w-[61px] h-[24px] sm:w-[61px] sm:h-[31.5px] sm:hidden -z-10"
|
||||
/>
|
||||
{/* eslint-disable-next-line @next/next/no-img-element -- decorative SVG */}
|
||||
<img
|
||||
src={getAssetPath("assets/Union_sm_md_lg.svg")}
|
||||
src={getAssetPath(ASSETS.UNION_SM_MD_LG)}
|
||||
alt=""
|
||||
role="presentation"
|
||||
className="absolute -bottom-[3.7px] -right-[53px] w-[61px] h-[24px] sm:w-[61px] sm:h-[31.5px] hidden sm:block xl:hidden -z-10"
|
||||
/>
|
||||
{/* eslint-disable-next-line @next/next/no-img-element -- decorative SVG */}
|
||||
<img
|
||||
src={getAssetPath("assets/Union_xlg.svg")}
|
||||
src={getAssetPath(ASSETS.UNION_XLG)}
|
||||
alt=""
|
||||
role="presentation"
|
||||
className="absolute -bottom-[6px] -right-[94px] w-[105px] h-[53px] hidden xl:block -z-10"
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { memo } from "react";
|
||||
import {
|
||||
ASSETS,
|
||||
getAssetPath,
|
||||
contentBlogHorizontalPath,
|
||||
contentBlogSectionPath,
|
||||
@@ -36,7 +37,7 @@ const ContentBannerContainer = memo<ContentBannerProps>(
|
||||
return contentBlogHorizontalPath(blogPost.slug);
|
||||
}
|
||||
|
||||
return getAssetPath("assets/Content_Banner.svg");
|
||||
return getAssetPath(ASSETS.CONTENT_BANNER);
|
||||
};
|
||||
|
||||
const resolveSectionImage = (blogPost: BlogPost): string => {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { memo, useMemo } from "react";
|
||||
import { getAssetPath, featurePanelPath } from "../../../../lib/assetUtils";
|
||||
import { useTranslation } from "../../../contexts/MessagesContext";
|
||||
import FeatureGridView from "./FeatureGrid.view";
|
||||
import type { FeatureGridProps, Feature } from "./FeatureGrid.types";
|
||||
@@ -19,7 +20,7 @@ const FeatureGridContainer = memo<FeatureGridProps>(
|
||||
labelLine2: t(
|
||||
"pages.home.featureGrid.features.decisionMaking.labelLine2",
|
||||
),
|
||||
panelContent: "/assets/Feature_Support.png",
|
||||
panelContent: getAssetPath(featurePanelPath("support")),
|
||||
ariaLabel: t("featureGrid.features.decisionMaking.ariaLabel"),
|
||||
href: "#decision-making",
|
||||
},
|
||||
@@ -31,7 +32,7 @@ const FeatureGridContainer = memo<FeatureGridProps>(
|
||||
labelLine2: t(
|
||||
"pages.home.featureGrid.features.valuesAlignment.labelLine2",
|
||||
),
|
||||
panelContent: "/assets/Feature_Exercises.png",
|
||||
panelContent: getAssetPath(featurePanelPath("exercises")),
|
||||
ariaLabel: t("featureGrid.features.valuesAlignment.ariaLabel"),
|
||||
href: "#values-alignment",
|
||||
},
|
||||
@@ -43,7 +44,7 @@ const FeatureGridContainer = memo<FeatureGridProps>(
|
||||
labelLine2: t(
|
||||
"pages.home.featureGrid.features.membershipGuidance.labelLine2",
|
||||
),
|
||||
panelContent: "/assets/Feature_Guidance.png",
|
||||
panelContent: getAssetPath(featurePanelPath("guidance")),
|
||||
ariaLabel: t("featureGrid.features.membershipGuidance.ariaLabel"),
|
||||
href: "#membership-guidance",
|
||||
},
|
||||
@@ -55,7 +56,7 @@ const FeatureGridContainer = memo<FeatureGridProps>(
|
||||
labelLine2: t(
|
||||
"pages.home.featureGrid.features.conflictResolution.labelLine2",
|
||||
),
|
||||
panelContent: "/assets/Feature_Tools.png",
|
||||
panelContent: getAssetPath(featurePanelPath("tools")),
|
||||
ariaLabel: t("featureGrid.features.conflictResolution.ariaLabel"),
|
||||
href: "#conflict-resolution",
|
||||
},
|
||||
|
||||
@@ -4,7 +4,7 @@ import { memo } from "react";
|
||||
import { useTranslation } from "../../../contexts/MessagesContext";
|
||||
import ContentLockup from "../../type/ContentLockup";
|
||||
import HeroDecor from "./HeroDecor";
|
||||
import { getAssetPath } from "../../../../lib/assetUtils";
|
||||
import { ASSETS, getAssetPath } from "../../../../lib/assetUtils";
|
||||
|
||||
interface HeroBannerProps {
|
||||
title?: string;
|
||||
@@ -48,7 +48,7 @@ const HeroBanner = memo<HeroBannerProps>(
|
||||
<div className="w-full h-full md:flex-1 rounded-[8px] overflow-hidden relative z-10 flex items-center justify-center">
|
||||
{/* eslint-disable-next-line @next/next/no-img-element -- dynamic path from getAssetPath */}
|
||||
<img
|
||||
src={getAssetPath("assets/HeroImage.png")}
|
||||
src={getAssetPath(ASSETS.HERO_IMAGE)}
|
||||
alt={imageAlt}
|
||||
className="w-full h-auto"
|
||||
loading="eager"
|
||||
|
||||
@@ -1,42 +1,43 @@
|
||||
"use client";
|
||||
|
||||
import { memo, useState, useEffect, useMemo } from "react";
|
||||
import { getAssetPath, partnerLogoPath } from "../../../../lib/assetUtils";
|
||||
import LogoWallView from "./LogoWall.view";
|
||||
import type { LogoWallProps } from "./LogoWall.types";
|
||||
|
||||
const defaultLogos = [
|
||||
{
|
||||
src: "/assets/Section/Logo_FoodNotBombs.png",
|
||||
src: getAssetPath(partnerLogoPath("food-not-bombs")),
|
||||
alt: "Food Not Bombs",
|
||||
size: "h-11 lg:h-14 xl:h-[70px]",
|
||||
order: "order-1 sm:order-4", // Mobile: row 1 col 1, SM: row 2 col 1 (bottom left)
|
||||
},
|
||||
{
|
||||
src: "/assets/Section/Logo_StartCOOP.png",
|
||||
src: getAssetPath(partnerLogoPath("start-coop")),
|
||||
alt: "Start COOP",
|
||||
size: "h-[42px] lg:h-[53px] xl:h-[66px]",
|
||||
order: "order-2 sm:order-2", // Mobile: row 1 col 2, SM: row 1 col 2 (top middle)
|
||||
},
|
||||
{
|
||||
src: "/assets/Section/Logo_Metagov.png",
|
||||
src: getAssetPath(partnerLogoPath("metagov")),
|
||||
alt: "Metagov",
|
||||
size: "h-6 lg:h-8 xl:h-[41px]",
|
||||
order: "order-3 sm:order-1", // Mobile: row 2 col 1, SM: row 1 col 1 (top left)
|
||||
},
|
||||
{
|
||||
src: "/assets/Section/Logo_OpenCivics.png",
|
||||
src: getAssetPath(partnerLogoPath("open-civics")),
|
||||
alt: "Open Civics",
|
||||
size: "h-8 lg:h-10 xl:h-[50px]",
|
||||
order: "order-4 sm:order-5 md:order-6", // Mobile: row 2 col 2, SM: row 2 col 2, MD: swapped with Mutual Aid CO
|
||||
},
|
||||
{
|
||||
src: "/assets/Section/Logo_MutualAidCO.png",
|
||||
src: getAssetPath(partnerLogoPath("mutual-aid-co")),
|
||||
alt: "Mutual Aid CO",
|
||||
size: "h-11 lg:h-14 xl:h-[70px]",
|
||||
order: "order-5 sm:order-6 md:order-5", // Mobile: row 3 col 1, SM: row 2 col 3, MD: swapped with OpenCivics
|
||||
},
|
||||
{
|
||||
src: "/assets/Section/Logo_CUBoulder.png",
|
||||
src: getAssetPath(partnerLogoPath("cu-boulder")),
|
||||
alt: "CU Boulder",
|
||||
size: "h-10 lg:h-12 xl:h-[60px]",
|
||||
order: "order-6 sm:order-3", // Mobile: row 3 col 2, SM: row 1 col 3 (top right)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { memo, useState } from "react";
|
||||
import { ASSETS, getAssetPath } from "../../../../lib/assetUtils";
|
||||
import { logger } from "../../../../lib/logger";
|
||||
import QuoteBlockView from "./QuoteBlock.view";
|
||||
import type { QuoteBlockProps, VariantConfig } from "./QuoteBlock.types";
|
||||
@@ -14,9 +15,9 @@ const QuoteBlockContainer = memo<QuoteBlockProps>(
|
||||
quoteSecondary,
|
||||
author = "Jo Freeman",
|
||||
source = "The Tyranny of Structurelessness",
|
||||
avatarSrc = "/assets/Quote_Avatar.svg",
|
||||
avatarSrc = getAssetPath(ASSETS.QUOTE_AVATAR),
|
||||
id,
|
||||
fallbackAvatarSrc = "/assets/Quote_Avatar.svg",
|
||||
fallbackAvatarSrc = getAssetPath(ASSETS.QUOTE_AVATAR),
|
||||
onError,
|
||||
}) => {
|
||||
const [imageError, setImageError] = useState(false);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { memo } from "react";
|
||||
import { getAssetPath } from "../../../lib/assetUtils";
|
||||
import { getAssetPath, sectionNumberPath } from "../../../lib/assetUtils";
|
||||
|
||||
interface SectionNumberProps {
|
||||
number: number;
|
||||
@@ -9,19 +9,8 @@ interface SectionNumberProps {
|
||||
|
||||
const SectionNumber = memo<SectionNumberProps>(({ number }) => {
|
||||
const getImageSrc = (num: number): string => {
|
||||
const assetPath = (() => {
|
||||
switch (num) {
|
||||
case 1:
|
||||
return "assets/SectionNumber_1.png";
|
||||
case 2:
|
||||
return "assets/SectionNumber_2.png";
|
||||
case 3:
|
||||
return "assets/SectionNumber_3.png";
|
||||
default:
|
||||
return "assets/SectionNumber_1.png";
|
||||
}
|
||||
})();
|
||||
return getAssetPath(assetPath);
|
||||
const n = num === 2 || num === 3 ? num : 1;
|
||||
return getAssetPath(sectionNumberPath(n));
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -75,7 +75,7 @@ function ContentLockupView({
|
||||
<>
|
||||
{/* eslint-disable-next-line @next/next/no-img-element -- decorative shape SVG */}
|
||||
<img
|
||||
src={getAssetPath("assets/Shapes_1.svg")}
|
||||
src={getAssetPath("assets/shapes/shapes-1.svg")}
|
||||
alt=""
|
||||
className={styles.shape}
|
||||
role="presentation"
|
||||
|
||||
Reference in New Issue
Block a user