@tandem-language-exchange/content-store 1.2.20 → 1.2.22

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/dist/sanity.js CHANGED
@@ -2929,323 +2929,7 @@ var schemaTypes_default = [
2929
2929
  sliderSection_default,
2930
2930
  statsBlock_default
2931
2931
  ];
2932
-
2933
- // src/client/sanity/studio.tsx
2934
- import dynamic from "next/dynamic";
2935
-
2936
- // src/client/sanity/config.ts
2937
- import { defineConfig } from "sanity";
2938
- import { structureTool } from "sanity/structure";
2939
- import { documentInternationalization } from "@sanity/document-internationalization";
2940
- import { markdownSchema } from "sanity-plugin-markdown/next";
2941
- import { media } from "sanity-plugin-media";
2942
- import { references, referencesView } from "sanity-plugin-references";
2943
-
2944
- // src/shared/sanity/structure.ts
2945
- var structure = (S) => S.list().title("Content").items([
2946
- S.listItem().title("Pages").child(
2947
- S.list().title("Pages").items([
2948
- S.documentTypeListItem("page").title("Page"),
2949
- S.documentTypeListItem("longtailPage").title("Longtail Page"),
2950
- S.documentTypeListItem("pageSection").title("Page Section")
2951
- ])
2952
- ),
2953
- S.listItem().title("Components").child(
2954
- S.list().title("Page Section Components").items([
2955
- S.documentTypeListItem("audioPhrase").title("Audio Phrase"),
2956
- S.documentTypeListItem("banner").title("Banner"),
2957
- S.documentTypeListItem("button").title("Button"),
2958
- S.documentTypeListItem("columnizedText").title("Columnized Text"),
2959
- S.documentTypeListItem("cookieBanner").title("Cookie Banner"),
2960
- S.documentTypeListItem("customJson").title("Custom JSON"),
2961
- S.documentTypeListItem("freeformText").title("Freeform Text"),
2962
- S.documentTypeListItem("gridLayout").title("Grid Layout"),
2963
- S.documentTypeListItem("heroBlock").title("Hero Block"),
2964
- S.documentTypeListItem("heroImage").title("Hero Image"),
2965
- S.documentTypeListItem("imageAndContent").title("Image and Content"),
2966
- S.documentTypeListItem("profile").title("Profile"),
2967
- S.documentTypeListItem("menu").title("Menu"),
2968
- S.documentTypeListItem("refsList").title("References List")
2969
- ])
2970
- ),
2971
- S.listItem().title("Blog").child(
2972
- S.list().title("Blog").items([
2973
- S.documentTypeListItem("blogPost").title("Blog Post"),
2974
- S.documentTypeListItem("blogGetAppBanner").title("Blog Post Get App Banner"),
2975
- S.documentTypeListItem("blogPopup").title("Blog Popup"),
2976
- S.documentTypeListItem("blogLanguagesSidebar").title("Blog Languages Sidebar")
2977
- ])
2978
- ),
2979
- S.divider(),
2980
- S.listItem().title("Utils (Ignore)").child(
2981
- S.list().title("Utils (Ignore)").items([
2982
- S.documentTypeListItem("translation.metadata").title(
2983
- "Translation Metadata"
2984
- ),
2985
- S.documentTypeListItem("media.tag").title("Media Tag")
2986
- ])
2987
- )
2988
- ]);
2989
-
2990
- // src/shared/sanity/documentCountsTool.tsx
2991
- import { useEffect, useState, useCallback } from "react";
2992
- import { definePlugin, useClient } from "sanity";
2993
- import {
2994
- Card,
2995
- Stack,
2996
- Text,
2997
- Heading,
2998
- Flex,
2999
- Spinner,
3000
- Button,
3001
- Badge,
3002
- Container
3003
- } from "@sanity/ui";
3004
- import { DocumentsIcon } from "@sanity/icons";
3005
- import { jsx, jsxs } from "react/jsx-runtime";
3006
- var DocumentCountsDashboard = () => {
3007
- const client = useClient({ apiVersion: "2024-01-01" });
3008
- const [counts, setCounts] = useState([]);
3009
- const [loading, setLoading] = useState(true);
3010
- const [totals, setTotals] = useState({ published: 0, drafts: 0, total: 0 });
3011
- const fetchCounts = useCallback(async () => {
3012
- setLoading(true);
3013
- try {
3014
- const types = await client.fetch(
3015
- "array::unique(*[]._type)"
3016
- );
3017
- if (!types.length) {
3018
- setCounts([]);
3019
- setTotals({ published: 0, drafts: 0, total: 0 });
3020
- setLoading(false);
3021
- return;
3022
- }
3023
- const projections = types.map(
3024
- (t) => `"${t}": { "published": count(*[_type == "${t}" && !(_id in path("drafts.**"))]), "drafts": count(*[_type == "${t}" && _id in path("drafts.**")]) }`
3025
- ).join(", ");
3026
- const result = await client.fetch(`{ ${projections} }`);
3027
- const typeCounts = types.map((type) => ({
3028
- type,
3029
- published: result[type]?.published || 0,
3030
- drafts: result[type]?.drafts || 0,
3031
- total: (result[type]?.published || 0) + (result[type]?.drafts || 0)
3032
- })).sort((a, b) => b.total - a.total);
3033
- setCounts(typeCounts);
3034
- setTotals(
3035
- typeCounts.reduce(
3036
- (acc, tc) => ({
3037
- published: acc.published + tc.published,
3038
- drafts: acc.drafts + tc.drafts,
3039
- total: acc.total + tc.total
3040
- }),
3041
- { published: 0, drafts: 0, total: 0 }
3042
- )
3043
- );
3044
- } catch (err) {
3045
- console.error("Failed to fetch document counts:", err);
3046
- } finally {
3047
- setLoading(false);
3048
- }
3049
- }, [client]);
3050
- useEffect(() => {
3051
- fetchCounts();
3052
- }, [fetchCounts]);
3053
- if (loading) {
3054
- return /* @__PURE__ */ jsx(Flex, { align: "center", justify: "center", padding: 5, height: "fill", children: /* @__PURE__ */ jsx(Spinner, { muted: true }) });
3055
- }
3056
- return /* @__PURE__ */ jsx(Container, { width: 2, padding: 4, children: /* @__PURE__ */ jsxs(Stack, { space: 5, children: [
3057
- /* @__PURE__ */ jsxs(Flex, { align: "center", justify: "space-between", children: [
3058
- /* @__PURE__ */ jsxs(Stack, { space: 3, children: [
3059
- /* @__PURE__ */ jsx(Heading, { size: 3, children: "Document Counts" }),
3060
- /* @__PURE__ */ jsxs(Flex, { gap: 4, children: [
3061
- /* @__PURE__ */ jsxs(Text, { muted: true, size: 2, children: [
3062
- "Total: ",
3063
- totals.total.toLocaleString()
3064
- ] }),
3065
- /* @__PURE__ */ jsxs(Text, { muted: true, size: 2, children: [
3066
- "Published: ",
3067
- totals.published.toLocaleString()
3068
- ] }),
3069
- /* @__PURE__ */ jsxs(Text, { muted: true, size: 2, children: [
3070
- "Drafts: ",
3071
- totals.drafts.toLocaleString()
3072
- ] })
3073
- ] })
3074
- ] }),
3075
- /* @__PURE__ */ jsx(
3076
- Button,
3077
- {
3078
- text: "Refresh",
3079
- tone: "primary",
3080
- mode: "ghost",
3081
- onClick: () => fetchCounts()
3082
- }
3083
- )
3084
- ] }),
3085
- /* @__PURE__ */ jsx(Card, { border: true, radius: 3, overflow: "hidden", children: /* @__PURE__ */ jsxs(Stack, { children: [
3086
- /* @__PURE__ */ jsx(Card, { borderBottom: true, padding: 3, tone: "transparent", children: /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 3, children: [
3087
- /* @__PURE__ */ jsx(Flex, { flex: 1, children: /* @__PURE__ */ jsx(Text, { size: 1, weight: "semibold", muted: true, children: "Document Type" }) }),
3088
- /* @__PURE__ */ jsx(Flex, { style: { width: 80 }, justify: "flex-end", children: /* @__PURE__ */ jsx(Text, { size: 1, weight: "semibold", muted: true, children: "Published" }) }),
3089
- /* @__PURE__ */ jsx(Flex, { style: { width: 80 }, justify: "flex-end", children: /* @__PURE__ */ jsx(Text, { size: 1, weight: "semibold", muted: true, children: "Drafts" }) }),
3090
- /* @__PURE__ */ jsx(Flex, { style: { width: 80 }, justify: "flex-end", children: /* @__PURE__ */ jsx(Text, { size: 1, weight: "semibold", muted: true, children: "Total" }) })
3091
- ] }) }),
3092
- counts.map(({ type, published, drafts, total }, index) => /* @__PURE__ */ jsx(
3093
- Card,
3094
- {
3095
- borderBottom: index < counts.length - 1,
3096
- padding: 3,
3097
- children: /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 3, children: [
3098
- /* @__PURE__ */ jsx(Flex, { flex: 1, children: /* @__PURE__ */ jsx(Text, { size: 2, children: type }) }),
3099
- /* @__PURE__ */ jsx(Flex, { style: { width: 80 }, justify: "flex-end", children: /* @__PURE__ */ jsx(Badge, { tone: "positive", fontSize: 1, children: published.toLocaleString() }) }),
3100
- /* @__PURE__ */ jsx(Flex, { style: { width: 80 }, justify: "flex-end", children: /* @__PURE__ */ jsx(Badge, { tone: "caution", fontSize: 1, children: drafts.toLocaleString() }) }),
3101
- /* @__PURE__ */ jsx(Flex, { style: { width: 80 }, justify: "flex-end", children: /* @__PURE__ */ jsx(Badge, { tone: "primary", fontSize: 1, children: total.toLocaleString() }) })
3102
- ] })
3103
- },
3104
- type
3105
- )),
3106
- counts.length === 0 && /* @__PURE__ */ jsx(Card, { padding: 4, children: /* @__PURE__ */ jsx(Text, { align: "center", muted: true, children: "No documents found" }) })
3107
- ] }) })
3108
- ] }) });
3109
- };
3110
- var documentCountsPlugin = definePlugin({
3111
- name: "document-counts",
3112
- tools: [
3113
- {
3114
- name: "document-counts",
3115
- title: "Document Counts",
3116
- component: DocumentCountsDashboard,
3117
- icon: DocumentsIcon
3118
- }
3119
- ]
3120
- });
3121
-
3122
- // src/shared/sanity/previewInspector.ts
3123
- import { useEffect as useEffect2, useRef } from "react";
3124
- import { useEditState } from "sanity";
3125
- import { EyeOpenIcon } from "@sanity/icons";
3126
- var STAGING_BASE_URL = "https://devtandem.net";
3127
- var lastOpenByKey = /* @__PURE__ */ new Map();
3128
- var OPEN_DEDUPE_MS = 800;
3129
- var buildPreviewUrl = (slug) => `${STAGING_BASE_URL}${slug.startsWith("/") ? slug : `/${slug}`}`;
3130
- var getSlugFromEditState = (editState) => editState.draft?.slug ?? editState.published?.slug;
3131
- var usePreviewMenuItem = () => ({
3132
- icon: EyeOpenIcon,
3133
- showAsAction: true,
3134
- title: "Preview on Staging"
3135
- });
3136
- var PreviewInspector = ({
3137
- documentId,
3138
- documentType,
3139
- onClose
3140
- }) => {
3141
- const publishedId = documentId.replace(/^drafts\./, "");
3142
- const editState = useEditState(publishedId, documentType);
3143
- const slug = getSlugFromEditState(editState);
3144
- const onCloseRef = useRef(onClose);
3145
- onCloseRef.current = onClose;
3146
- useEffect2(() => {
3147
- if (!editState.ready) return;
3148
- const previewUrl = slug ? buildPreviewUrl(slug) : null;
3149
- if (previewUrl) {
3150
- const dedupeKey = `${documentId}::${previewUrl}`;
3151
- const now = Date.now();
3152
- const last = lastOpenByKey.get(dedupeKey) ?? 0;
3153
- if (now - last >= OPEN_DEDUPE_MS) {
3154
- lastOpenByKey.set(dedupeKey, now);
3155
- window.open(previewUrl, "_blank", "noopener,noreferrer");
3156
- }
3157
- }
3158
- queueMicrotask(() => onCloseRef.current());
3159
- }, [editState.ready, slug, documentId]);
3160
- return null;
3161
- };
3162
- var previewInspector_default = PreviewInspector;
3163
-
3164
- // src/client/sanity/config.ts
3165
- var projectId = "l12d16xw";
3166
- var dataset = "main";
3167
- var schema = { types: schemaTypes_default };
3168
- var schemaTypeNames = schema.types.map((i) => i.name).filter(Boolean);
3169
- var config = defineConfig({
3170
- name: "website",
3171
- basePath: "/sanity",
3172
- projectId,
3173
- dataset,
3174
- schema,
3175
- document: {
3176
- newDocumentOptions: (prev) => prev.filter(
3177
- (templateItem) => !schemaTypeNames.includes(templateItem.templateId)
3178
- ),
3179
- inspectors: (prev, context) => {
3180
- const typesWithSlug = schema.types.filter(
3181
- (t) => "fields" in t && t.fields?.some((f) => f.name === "slug")
3182
- ).map((t) => t.name);
3183
- if (!typesWithSlug.includes(context.documentType)) return prev;
3184
- return [
3185
- ...prev,
3186
- {
3187
- name: "preview-staging",
3188
- component: previewInspector_default,
3189
- useMenuItem: usePreviewMenuItem
3190
- }
3191
- ];
3192
- }
3193
- },
3194
- plugins: [
3195
- structureTool({
3196
- structure,
3197
- defaultDocumentNode: (S) => S.document().views([S.view.form(), referencesView(S)])
3198
- }),
3199
- media(),
3200
- markdownSchema(),
3201
- references(),
3202
- documentCountsPlugin(),
3203
- documentInternationalization({
3204
- supportedLanguages: [
3205
- { id: "en", title: "English [en]" },
3206
- { id: "de", title: "German [de]" },
3207
- { id: "es", title: "Spanish [es]" },
3208
- { id: "fr", title: "French [fr]" },
3209
- { id: "it", title: "Italian [it]" },
3210
- { id: "pt-br", title: "Portuguese (Brazil) [pt-br]" },
3211
- { id: "ru", title: "Russian [ru]" },
3212
- { id: "ja", title: "Japanese [ja]" },
3213
- { id: "ko", title: "Korean [ko]" },
3214
- { id: "zh-hans", title: "Chinese (Simplified) [zh-hans]" },
3215
- { id: "zh-hant", title: "Chinese (Traditional) [zh-hant]" }
3216
- ],
3217
- schemaTypes: schemaTypeNames,
3218
- languageField: "locale"
3219
- })
3220
- ]
3221
- });
3222
- var config_default = config;
3223
-
3224
- // src/client/sanity/studio.tsx
3225
- import { jsx as jsx2 } from "react/jsx-runtime";
3226
- var Studio = dynamic(() => import("sanity").then((mod) => mod.Studio), {
3227
- ssr: false,
3228
- loading: () => /* @__PURE__ */ jsx2("div", { style: { height: "100vh", background: "#101112" } })
3229
- });
3230
- var StudioPage = ({ config: overrides } = {}) => {
3231
- const config2 = overrides ? { ...config_default, ...overrides } : config_default;
3232
- return /* @__PURE__ */ jsx2(
3233
- "div",
3234
- {
3235
- style: {
3236
- height: "100vh",
3237
- maxHeight: "100dvh",
3238
- overscrollBehavior: "none",
3239
- WebkitFontSmoothing: "antialiased",
3240
- overflow: "hidden"
3241
- },
3242
- children: /* @__PURE__ */ jsx2(Studio, { config: config2 })
3243
- }
3244
- );
3245
- };
3246
- var studio_default = StudioPage;
3247
2932
  export {
3248
- studio_default as StudioPage,
3249
2933
  audioPhrase_default as audioPhrase,
3250
2934
  banner_default as banner,
3251
2935
  blogGetAppBanner_default as blogGetAppBanner,
@@ -3275,7 +2959,6 @@ export {
3275
2959
  profile_default as profile,
3276
2960
  profilesCarousel_default as profilesCarousel,
3277
2961
  refsList_default as refsList,
3278
- config_default as sanityConfig,
3279
2962
  scheduledParty_default as scheduledParty,
3280
2963
  sliderSection_default as sliderSection,
3281
2964
  statsBlock_default as statsBlock