Skip to content

Commit 96e4c05

Browse files
Help features about ai tools (#716)
* Added the content for each features * Added AI Tools * Clean query params when changing the main tabs * Fixed the render of ai-tools in content.tsx * Updated the pmpm-lock.yaml * Added icon to code block and fixed pnpm installation * Changed to Zod, use server side rendering when possible * Place queryKeys into ui/use-query-keys/help.ts * Added prefix to the help query-keys in ui
1 parent ab8c681 commit 96e4c05

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1383
-246
lines changed

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,13 @@
140140
"react-markdown": "^9.1.0",
141141
"react-pdf": "^9.2.1",
142142
"react-plotly.js": "^2.6.0",
143-
"react-query": "link:@types/@tanstack/react-query",
144143
"react-resizable": "^3.0.5",
145144
"react-select": "^5.7.3",
146145
"react-syntax-highlighter": "^15.6.1",
147146
"rehype-katex": "^7.0.1",
148147
"rehype-raw": "^7.0.0",
148+
"rehype-sanitize": "^6.0.0",
149+
"remark-breaks": "^4.0.0",
149150
"remark-gfm": "^4.0.1",
150151
"remark-math": "^6.0.0",
151152
"sanity": "^3.93.0",
@@ -159,7 +160,7 @@
159160
"use-breakpoint": "^4.0.6",
160161
"wavefront-obj-parser": "^2.0.1",
161162
"whatwg-fetch": "^3.6.19",
162-
"zod": "^3.22.4"
163+
"zod": "^3.25.76"
163164
},
164165
"devDependencies": {
165166
"@playwright/test": "^1.51.1",

pnpm-lock.yaml

Lines changed: 184 additions & 142 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/api/sanity/client.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { env } from '@/env';
66

77
import { ContentForPricing } from '@/components/LandingPage/content/pricing';
88

9-
const client = new SanityClient({
9+
export const client = new SanityClient({
1010
projectId: 'fgi7eh1v',
1111
dataset: env.NEXT_PUBLIC_SANITY_DATASET!,
1212
apiVersion: '2023-03-25',
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { client } from '@/api/sanity/client';
2+
import { logError } from '@/util/logger';
3+
import { assertType } from '@/util/type-guards';
4+
5+
export type AboutContentProps = {
6+
aboutContent: unknown;
7+
aboutTheAppContent: unknown;
8+
termsAndConditionContent: unknown;
9+
};
10+
11+
const queryForAboutContent = `*[_type=="ResourceHelpSection"][0]{
12+
aboutContent,
13+
aboutTheAppContent,
14+
termsAndConditionContent
15+
}`;
16+
17+
function isContentForAbout(data: unknown): data is AboutContentProps {
18+
try {
19+
assertType(
20+
data,
21+
{
22+
aboutContent: 'unknown',
23+
aboutTheAppContent: 'unknown',
24+
termsAndConditionContent: 'unknown',
25+
},
26+
'ContentForAbout'
27+
);
28+
return true;
29+
} catch (ex) {
30+
logError(ex);
31+
return false;
32+
}
33+
}
34+
35+
export async function getAboutContent(): Promise<AboutContentProps> {
36+
try {
37+
const data = await client.fetch<AboutContentProps>({
38+
query: queryForAboutContent,
39+
});
40+
if (isContentForAbout(data)) return data;
41+
} catch (err) {
42+
logError(err);
43+
}
44+
45+
return {
46+
aboutContent: [],
47+
aboutTheAppContent: [],
48+
termsAndConditionContent: [],
49+
};
50+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { client } from '@/api/sanity/client';
2+
import { ContentForTutorialItem } from '@/types/help/type';
3+
import { logError } from '@/util/logger';
4+
import { assertType, TypeDef } from '@/util/type-guards';
5+
6+
const queryForAboutContent = `*[_type == "documentationSettings"][0] {
7+
tutorialOrder[]-> {
8+
title,
9+
description,
10+
"slug": slug.current,
11+
"url": videoUrl,
12+
transcript,
13+
"imageURL": thumbnail.asset->url,
14+
"imageWidth": thumbnail.asset->metadata.dimensions.width,
15+
"imageHeight": thumbnail.asset->metadata.dimensions.height,
16+
steps
17+
}
18+
}`;
19+
20+
function isContentForTutorials(data: unknown): data is ContentForTutorialItem {
21+
const typeStringOrNull: TypeDef = ['|', 'string', 'null'];
22+
try {
23+
assertType(
24+
data,
25+
{
26+
tutorialOrder: [
27+
'array',
28+
{
29+
title: typeStringOrNull,
30+
description: typeStringOrNull,
31+
slug: 'string',
32+
url: typeStringOrNull,
33+
imageURL: 'string',
34+
imageWidth: 'number',
35+
imageHeight: 'number',
36+
},
37+
],
38+
},
39+
'ContentForTutorial'
40+
);
41+
return true;
42+
} catch (ex) {
43+
logError(ex);
44+
return false;
45+
}
46+
}
47+
48+
export async function getTutorialContent(): Promise<ContentForTutorialItem> {
49+
try {
50+
const data = await client.fetch<ContentForTutorialItem>({
51+
query: queryForAboutContent,
52+
});
53+
if (isContentForTutorials(data)) return data;
54+
} catch (err) {
55+
logError(err);
56+
}
57+
58+
return {
59+
tutorialOrder: [],
60+
};
61+
}

src/app/app/v2/[virtualLabId]/[projectId]/help/page.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,17 @@ import { HelpLayout } from '@/ui/layouts/help-layout';
22
import { HelpHeader } from '@/ui/segments/help/header';
33
import Sections from '@/ui/segments/help/sections';
44

5-
export default function Page() {
5+
export const dynamic = 'force-dynamic';
6+
7+
export default function Page({
8+
searchParams,
9+
}: {
10+
searchParams?: Record<string, string | string[] | undefined>;
11+
}) {
612
return (
713
<HelpLayout>
814
<HelpHeader />
9-
<Sections />
15+
<Sections searchParams={searchParams} />
1016
</HelpLayout>
1117
);
1218
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { useSanity } from '@/services/sanity';
2+
import { AboutContentProps } from '@/ui/segments/help/about/content';
3+
import { logError } from '@/util/logger';
4+
import { assertType } from '@/util/type-guards';
5+
6+
const queryForAboutContent = `*[_type=="ResourceHelpSection"][0] {
7+
aboutContent,
8+
aboutTheAppContent,
9+
termsAndConditionContent
10+
}`;
11+
12+
export function useSanityContentForAboutContent(): AboutContentProps {
13+
return (
14+
useSanity(queryForAboutContent, isContentForAbout) ?? {
15+
aboutContent: [],
16+
aboutTheAppContent: [],
17+
termsAndConditionContent: [],
18+
}
19+
);
20+
}
21+
22+
function isContentForAbout(data: unknown): data is AboutContentProps {
23+
try {
24+
assertType(
25+
data,
26+
{
27+
aboutContent: 'unknown',
28+
aboutTheAppContent: 'unknown',
29+
termsAndConditionContent: 'unknown',
30+
},
31+
'ContentForAbout'
32+
);
33+
return true;
34+
} catch (ex) {
35+
logError(ex);
36+
return false;
37+
}
38+
}

src/components/documentation/hooks/use-sanity-content-for-features.ts

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
// import query from '../query/featuresItemHooks.groq';
2-
import query from '@/components/documentation/query/features-item-hooks.groq';
1+
import { z } from 'zod';
32

3+
import query from '@/components/documentation/query/features-item-hooks.groq';
44
import { useSanity } from '@/services/sanity';
55
import { logError } from '@/util/logger';
6-
import { assertType, TypeDef } from '@/util/type-guards';
76

87
export function useSanityContentForFeatureItems() {
98
return useSanity(query, isContentForFeatureItems) ?? [];
@@ -17,23 +16,21 @@ export type ContentForFeatureItem = {
1716
Status: string;
1817
};
1918

19+
// Zod schema for ContentForFeatureItem
20+
const ContentForFeatureItemSchema = z.object({
21+
Feature_title: z.string().nullable(),
22+
Description: z.string().nullable(),
23+
Topic: z.string().nullable(),
24+
Scale: z.string().nullable(),
25+
Status: z.string().nullable(),
26+
});
27+
28+
// Zod schema for array of ContentForFeatureItem
29+
const ContentForFeatureItemsSchema = z.array(ContentForFeatureItemSchema);
30+
2031
function isContentForFeatureItems(data: unknown): data is ContentForFeatureItem[] {
21-
const typeStringOrNull: TypeDef = ['|', 'string', 'null'];
2232
try {
23-
assertType(
24-
data,
25-
[
26-
'array',
27-
{
28-
Feature_title: typeStringOrNull,
29-
Description: typeStringOrNull,
30-
Topic: typeStringOrNull,
31-
Scale: typeStringOrNull,
32-
Status: typeStringOrNull,
33-
},
34-
],
35-
'ContentForGlossary'
36-
);
33+
ContentForFeatureItemsSchema.parse(data);
3734
return true;
3835
} catch (ex) {
3936
logError(ex);

src/services/sanity/sanity.ts

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { createClient } from 'next-sanity';
55

66
import { logError } from '@/util/logger';
77
import { isUndefined } from '@/util/type-guards';
8+
import { log } from '@/utils/logger';
89

910
const client = createClient({
1011
projectId: 'fgi7eh1v',
@@ -14,12 +15,6 @@ const client = createClient({
1415
useCdn: process.env.NODE_ENV === 'production',
1516
});
1617

17-
/**
18-
* @returns The expected object, or:
19-
*
20-
* - `undefined` if the query has not finished yet.
21-
* - `null` if an error occured.
22-
*/
2318
export function useSanity<T>(
2419
query: string,
2520
typeGuard: (data: unknown) => data is T
@@ -48,25 +43,17 @@ export async function fetchSanity<T>(
4843
if (typeGuard(data)) return data;
4944
throw Error('Type guard rejeted this type, but without any explanation!');
5045
} catch (ex) {
51-
console.log('The following Sanity GROQ query returned a data of unexpected type:');
52-
console.log(`%c${query}`, 'font-family: monospace; color: #0f0; bakground: #000');
53-
console.log(data);
46+
log('warn', 'The following Sanity GROQ query returned a data of unexpected type:');
47+
log('log', `%c${query}`, 'font-family: monospace; color: #0f0; background: #000');
48+
log('log', data);
5449
const msg = ex instanceof Error ? ex.message : `${ex}`;
55-
console.log(`%c${msg}`, 'font-weight: bold; color: #fff; background: #b00');
50+
log('log', `%c${msg}`, 'font-weight: bold; color: #fff; background: #b00');
5651
return null;
5752
}
5853
}
5954

60-
// Prevent a query from being fetched twice.
6155
const cache = new Map<string, unknown>();
6256

63-
/**
64-
* Query Sanity without checking the returned format.
65-
* This is an utility function used by more specific ones.
66-
* Please use `useSanityContentTyped()` instead.
67-
*
68-
* @see https://open-brain-institute.sanity.studio
69-
*/
7057
async function fetchSanityContent(query: string): Promise<unknown> {
7158
const fromCache = cache.get(query);
7259
if (fromCache) return fromCache;

src/styles/globals.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@
116116

117117
--shadow-strong-image: 0px 22px 22px -16px rgba(0, 0, 0, 0.36);
118118
--shadow-super-shadow: 0px 24px 60px 0px rgba(0, 0, 0, 0.4);
119+
--shadow-skmp-s:
120+
-16px -16px 20px 0 rgba(255, 255, 255, 0.82), 8px 12px 24px 0 rgba(0, 0, 0, 0.06);
119121

120122
--ease-in-expo: cubic-bezier(0.95, 0.05, 0.795, 0.035);
121123
--ease-out-expo: cubic-bezier(0.19, 1, 0.22, 1);

0 commit comments

Comments
 (0)