@tomako/tools-runtime 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +13 -4
- package/src/components/tools/workspace/tool-workspace-layout.tsx +1 -1
- package/src/constants/related-tools.ts +4 -0
- package/src/features/tools/app-icon-resizer/app-icon-resizer.container.tsx +15 -2
- package/src/features/tools/app-icon-resizer/app-icon-resizer.spec.ts +1 -1
- package/src/features/tools/app-icon-resizer/widget/app-icon-resizer.tsx +54 -11
- package/src/features/tools/app-icon-resizer/widget/platform-icons.tsx +2 -5
- package/src/features/tools/mrr-calculator/mrr-calculator.container.tsx +23 -0
- package/src/features/tools/mrr-calculator/mrr-calculator.spec.ts +15 -0
- package/src/features/tools/mrr-calculator/widget/calculations.ts +74 -0
- package/src/features/tools/mrr-calculator/widget/index.ts +1 -0
- package/src/features/tools/mrr-calculator/widget/mrr-calculator.tsx +581 -0
- package/src/features/tools/registry.ts +6 -0
- package/src/features/tools/runtime-registry.ts +4 -0
- package/src/features/tools/shared/create-standard-landing-container.tsx +35 -5
- package/src/features/tools/shared/tool-page-shell.tsx +4 -4
- package/src/features/tools/shared/tool-standard-landing-sections.tsx +262 -52
- package/src/features/tools/spec-registry.ts +2 -0
- package/src/features/tools/widget-registry.ts +2 -0
- package/src/i18n/messages/en/tools/app-icon-resizer.ts +90 -62
- package/src/i18n/messages/en/tools/index.ts +2 -0
- package/src/i18n/messages/en/tools/mrr-calculator.ts +202 -0
- package/src/i18n/messages/en/tools-ui.ts +3 -2
- package/src/i18n/messages/zh/page/tools.ts +2 -3
- package/src/i18n/messages/zh/tools/app-icon-resizer.ts +90 -62
- package/src/i18n/messages/zh/tools/index.ts +2 -0
- package/src/i18n/messages/zh/tools/mrr-calculator.ts +112 -0
- package/src/i18n/messages/zh/tools-ui.ts +3 -2
- package/src/i18n/messages/zh-tw/tools/app-icon-resizer.ts +90 -62
- package/src/i18n/messages/zh-tw/tools/index.ts +2 -0
- package/src/i18n/messages/zh-tw/tools/mrr-calculator.ts +52 -0
- package/src/i18n/messages/zh-tw/tools-ui.ts +3 -2
- package/src/lib/tools/resolve-tool-locale-copy.ts +7 -1
|
@@ -3,9 +3,11 @@ import type { ComponentType } from "react";
|
|
|
3
3
|
|
|
4
4
|
import type {
|
|
5
5
|
ToolStandardFaqItem,
|
|
6
|
+
ToolStandardEditorialSection,
|
|
6
7
|
ToolStandardGenerationStep,
|
|
7
8
|
ToolStandardImageTextSection,
|
|
8
9
|
ToolStandardNarrativeSection,
|
|
10
|
+
ToolStandardReferenceTable,
|
|
9
11
|
ToolStandardReportPreview,
|
|
10
12
|
ToolStandardSectionId,
|
|
11
13
|
} from "../../../features/tools/shared/tool-standard-landing-sections";
|
|
@@ -33,6 +35,10 @@ export type StandardLandingCopyKeys = {
|
|
|
33
35
|
reportPreview?: string;
|
|
34
36
|
/** Optional answer-first sections for decision and strategy tools. */
|
|
35
37
|
narrativeSections?: string;
|
|
38
|
+
/** Optional structured reading sections for rules, limits, and next actions. */
|
|
39
|
+
editorialSections?: string;
|
|
40
|
+
/** Optional searchable specifications table. */
|
|
41
|
+
referenceTable?: string;
|
|
36
42
|
};
|
|
37
43
|
|
|
38
44
|
export type StandardLandingContainerConfig = {
|
|
@@ -50,6 +56,14 @@ export type StandardLandingContainerConfig = {
|
|
|
50
56
|
passFaqToShell?: boolean;
|
|
51
57
|
/** A content CTA may navigate to a real, cost-free action. */
|
|
52
58
|
contentCtaHref?: string;
|
|
59
|
+
/** Hide repeated content CTAs when the primary action is already the workspace above. */
|
|
60
|
+
showContentCtas?: boolean;
|
|
61
|
+
/** Some tools have a useful step list but no extra illustration to repeat it. */
|
|
62
|
+
showGenerationImage?: boolean;
|
|
63
|
+
/** Only render a standalone guide when the tool has a real sequential workflow. */
|
|
64
|
+
showGeneration?: boolean;
|
|
65
|
+
/** Use less vertical padding and a grouped benefit list below mobile breakpoints. */
|
|
66
|
+
compactMobileSections?: boolean;
|
|
53
67
|
/** Override the default section sequence when the tool archetype needs a different reading flow. */
|
|
54
68
|
sectionOrder?: readonly ToolStandardSectionId[];
|
|
55
69
|
};
|
|
@@ -73,6 +87,10 @@ export function createStandardLandingContainer(
|
|
|
73
87
|
workspaceHeadingLevel = "h1",
|
|
74
88
|
passFaqToShell = true,
|
|
75
89
|
contentCtaHref,
|
|
90
|
+
showContentCtas = true,
|
|
91
|
+
showGenerationImage = true,
|
|
92
|
+
showGeneration = true,
|
|
93
|
+
compactMobileSections = false,
|
|
76
94
|
sectionOrder,
|
|
77
95
|
} = config;
|
|
78
96
|
|
|
@@ -96,9 +114,12 @@ export function createStandardLandingContainer(
|
|
|
96
114
|
const narrativeSections = copyKeys?.narrativeSections
|
|
97
115
|
? (t.raw(copyKeys.narrativeSections) as readonly ToolStandardNarrativeSection[])
|
|
98
116
|
: [];
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
117
|
+
const editorialSections = copyKeys?.editorialSections
|
|
118
|
+
? (t.raw(copyKeys.editorialSections) as readonly ToolStandardEditorialSection[])
|
|
119
|
+
: [];
|
|
120
|
+
const generationSteps = showGeneration
|
|
121
|
+
? (t.raw("standard.generation.steps") as readonly ToolStandardGenerationStep[])
|
|
122
|
+
: [];
|
|
102
123
|
const faqRaw = t.raw("faqItems");
|
|
103
124
|
const faqItems = (
|
|
104
125
|
Array.isArray(faqRaw) ? faqRaw : []
|
|
@@ -106,6 +127,9 @@ export function createStandardLandingContainer(
|
|
|
106
127
|
const reportPreview = copyKeys?.reportPreview
|
|
107
128
|
? (t.raw(copyKeys.reportPreview) as ToolStandardReportPreview)
|
|
108
129
|
: undefined;
|
|
130
|
+
const referenceTable = copyKeys?.referenceTable
|
|
131
|
+
? (t.raw(copyKeys.referenceTable) as ToolStandardReferenceTable)
|
|
132
|
+
: undefined;
|
|
109
133
|
const shellFaq = faqItems.filter(
|
|
110
134
|
(item): item is { question: string; answer: string } =>
|
|
111
135
|
typeof item.answer === "string",
|
|
@@ -137,7 +161,8 @@ export function createStandardLandingContainer(
|
|
|
137
161
|
}}
|
|
138
162
|
imageTextSections={imageTextSections}
|
|
139
163
|
narrativeSections={narrativeSections}
|
|
140
|
-
|
|
164
|
+
editorialSections={editorialSections}
|
|
165
|
+
generation={showGeneration ? {
|
|
141
166
|
title: t("standard.generation.title"),
|
|
142
167
|
image: {
|
|
143
168
|
src: generationImageSrc,
|
|
@@ -146,15 +171,20 @@ export function createStandardLandingContainer(
|
|
|
146
171
|
steps: generationSteps,
|
|
147
172
|
ctaLabel: t("standard.generation.ctaLabel"),
|
|
148
173
|
ctaHref: contentCtaHref,
|
|
149
|
-
|
|
174
|
+
showCta: showContentCtas,
|
|
175
|
+
showImage: showGenerationImage,
|
|
176
|
+
} : undefined}
|
|
150
177
|
reportPreview={reportPreview}
|
|
178
|
+
referenceTable={referenceTable}
|
|
151
179
|
faq={{
|
|
152
180
|
title: t(faqTitleKey),
|
|
153
181
|
intro: t("standard.faqIntro"),
|
|
154
182
|
ctaLabel: t("standard.faqCtaLabel"),
|
|
155
183
|
ctaHref: contentCtaHref,
|
|
184
|
+
showCta: showContentCtas,
|
|
156
185
|
items: faqItems,
|
|
157
186
|
}}
|
|
187
|
+
mobileDensity={compactMobileSections ? "compact" : "default"}
|
|
158
188
|
sectionOrder={sectionOrder}
|
|
159
189
|
/>
|
|
160
190
|
</ToolPageShell>
|
|
@@ -104,7 +104,7 @@ export async function ToolPageShell({
|
|
|
104
104
|
) : null}
|
|
105
105
|
|
|
106
106
|
<div className="relative z-10 flex min-h-[min(72svh,680px)] flex-col">
|
|
107
|
-
<div className="mx-auto flex w-full max-w-
|
|
107
|
+
<div className="mx-auto flex w-full max-w-[76rem] flex-1 flex-col justify-center gap-10 px-4 pb-8 pt-8 sm:px-8 lg:pt-12">
|
|
108
108
|
<div className="grid flex-1 gap-10 lg:grid-cols-[0.9fr_1.1fr] lg:items-center">
|
|
109
109
|
<div className="max-w-4xl">
|
|
110
110
|
<p className="inline-flex items-center gap-2 rounded-full border border-[#2B211A]/14 bg-[#FFF8EA]/45 px-4 py-2 text-sm font-semibold text-[#4C3C31] shadow-[0_12px_36px_rgba(83,48,28,0.08)] backdrop-blur">
|
|
@@ -136,13 +136,13 @@ export async function ToolPageShell({
|
|
|
136
136
|
</div>
|
|
137
137
|
</section>
|
|
138
138
|
|
|
139
|
-
<div className="mx-auto flex max-w-
|
|
139
|
+
<div className="mx-auto flex max-w-[76rem] flex-col gap-16 px-4 py-16 sm:px-8 md:gap-20 md:py-24">
|
|
140
140
|
{children}
|
|
141
141
|
</div>
|
|
142
142
|
</>
|
|
143
143
|
) : (
|
|
144
144
|
<>
|
|
145
|
-
<div className="mx-auto max-w-
|
|
145
|
+
<div className="mx-auto max-w-[76rem] px-4 py-5 sm:px-8">
|
|
146
146
|
{heroVariant === "showcase" && heroVisual ? (
|
|
147
147
|
<section className="pb-14 pt-14 md:pb-16 md:pt-16">
|
|
148
148
|
<div className="mx-auto max-w-4xl text-center">
|
|
@@ -211,7 +211,7 @@ export async function ToolPageShell({
|
|
|
211
211
|
</>
|
|
212
212
|
)}
|
|
213
213
|
{relatedToolSlugs?.length ? (
|
|
214
|
-
<div className="mx-auto w-full max-w-
|
|
214
|
+
<div className="mx-auto w-full max-w-[76rem] px-4 pb-16 sm:px-8 md:pb-20">
|
|
215
215
|
<RelatedTools locale={locale} currentToolSlug={spec.slug} slugs={relatedToolSlugs} />
|
|
216
216
|
</div>
|
|
217
217
|
) : null}
|