@c-rex/components 0.0.9 → 0.0.11
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 +29 -44
- package/src/autocomplete.tsx +113 -0
- package/src/blog-card.tsx +87 -0
- package/src/blur-image.tsx +23 -0
- package/src/breadcrumb.tsx +81 -0
- package/src/empty.tsx +13 -0
- package/src/navbar/navbar.tsx +69 -0
- package/src/navbar/sing-in-out-btns.tsx +29 -0
- package/src/providers/search-state-wrapper.tsx +21 -0
- package/src/result-list.tsx +16 -0
- package/src/result-view/blog-view.stories.tsx +58 -0
- package/src/result-view/blog.tsx +38 -0
- package/src/result-view/table-view.stories.tsx +55 -0
- package/src/result-view/table.tsx +65 -0
- package/src/sidebar.tsx +76 -0
- package/src/stories/blog-card.stories.tsx +46 -0
- package/src/stories/blur-image.stories.tsx +51 -0
- package/src/stories/breadcrumb.stories.tsx +52 -0
- package/src/stories/empty.stories.tsx +14 -0
- package/src/stories/navbar.stories.tsx +16 -0
- package/src/stories/sidebar.stories.tsx +94 -0
- package/dist/autocomplete.cjs.js +0 -215
- package/dist/autocomplete.cjs.js.map +0 -1
- package/dist/autocomplete.d.cts +0 -10
- package/dist/autocomplete.d.ts +0 -10
- package/dist/autocomplete.esm.js +0 -154
- package/dist/autocomplete.esm.js.map +0 -1
- package/dist/blog-card.cjs.js +0 -265
- package/dist/blog-card.cjs.js.map +0 -1
- package/dist/blog-card.d.cts +0 -19
- package/dist/blog-card.d.ts +0 -19
- package/dist/blog-card.esm.js +0 -192
- package/dist/blog-card.esm.js.map +0 -1
- package/dist/blur-image.cjs.js +0 -198
- package/dist/blur-image.cjs.js.map +0 -1
- package/dist/blur-image.d.cts +0 -7
- package/dist/blur-image.d.ts +0 -7
- package/dist/blur-image.esm.js +0 -125
- package/dist/blur-image.esm.js.map +0 -1
- package/dist/breadcrumb.cjs.js +0 -159
- package/dist/breadcrumb.cjs.js.map +0 -1
- package/dist/breadcrumb.d.cts +0 -10
- package/dist/breadcrumb.d.ts +0 -10
- package/dist/breadcrumb.esm.js +0 -98
- package/dist/breadcrumb.esm.js.map +0 -1
- package/dist/empty.cjs.js +0 -79
- package/dist/empty.cjs.js.map +0 -1
- package/dist/empty.d.cts +0 -5
- package/dist/empty.d.ts +0 -5
- package/dist/empty.esm.js +0 -18
- package/dist/empty.esm.js.map +0 -1
- package/dist/navbar.cjs.js +0 -134
- package/dist/navbar.cjs.js.map +0 -1
- package/dist/navbar.d.cts +0 -9
- package/dist/navbar.d.ts +0 -9
- package/dist/navbar.esm.js +0 -61
- package/dist/navbar.esm.js.map +0 -1
- package/dist/providers/search-state-wrapper.cjs.js +0 -113
- package/dist/providers/search-state-wrapper.cjs.js.map +0 -1
- package/dist/providers/search-state-wrapper.d.cts +0 -14
- package/dist/providers/search-state-wrapper.d.ts +0 -14
- package/dist/providers/search-state-wrapper.esm.js +0 -51
- package/dist/providers/search-state-wrapper.esm.js.map +0 -1
- package/dist/result-list.cjs.js +0 -321
- package/dist/result-list.cjs.js.map +0 -1
- package/dist/result-list.d.cts +0 -9
- package/dist/result-list.d.ts +0 -9
- package/dist/result-list.esm.js +0 -247
- package/dist/result-list.esm.js.map +0 -1
- package/dist/result-view/blog-view.stories.cjs.js +0 -372
- package/dist/result-view/blog-view.stories.cjs.js.map +0 -1
- package/dist/result-view/blog-view.stories.d.cts +0 -11
- package/dist/result-view/blog-view.stories.d.ts +0 -11
- package/dist/result-view/blog-view.stories.esm.js +0 -295
- package/dist/result-view/blog-view.stories.esm.js.map +0 -1
- package/dist/result-view/blog.cjs.js +0 -290
- package/dist/result-view/blog.cjs.js.map +0 -1
- package/dist/result-view/blog.d.cts +0 -9
- package/dist/result-view/blog.d.ts +0 -9
- package/dist/result-view/blog.esm.js +0 -220
- package/dist/result-view/blog.esm.js.map +0 -1
- package/dist/result-view/table-view.stories.cjs.js +0 -196
- package/dist/result-view/table-view.stories.cjs.js.map +0 -1
- package/dist/result-view/table-view.stories.d.cts +0 -11
- package/dist/result-view/table-view.stories.d.ts +0 -11
- package/dist/result-view/table-view.stories.esm.js +0 -131
- package/dist/result-view/table-view.stories.esm.js.map +0 -1
- package/dist/result-view/table.cjs.js +0 -116
- package/dist/result-view/table.cjs.js.map +0 -1
- package/dist/result-view/table.d.cts +0 -9
- package/dist/result-view/table.d.ts +0 -9
- package/dist/result-view/table.esm.js +0 -59
- package/dist/result-view/table.esm.js.map +0 -1
- package/dist/sidebar.cjs.js +0 -225
- package/dist/sidebar.cjs.js.map +0 -1
- package/dist/sidebar.d.cts +0 -12
- package/dist/sidebar.d.ts +0 -12
- package/dist/sidebar.esm.js +0 -164
- package/dist/sidebar.esm.js.map +0 -1
- package/dist/stories/blog-card.stories.cjs.js +0 -323
- package/dist/stories/blog-card.stories.cjs.js.map +0 -1
- package/dist/stories/blog-card.stories.d.cts +0 -9
- package/dist/stories/blog-card.stories.d.ts +0 -9
- package/dist/stories/blog-card.stories.esm.js +0 -242
- package/dist/stories/blog-card.stories.esm.js.map +0 -1
- package/dist/stories/blur-image.stories.cjs.js +0 -265
- package/dist/stories/blur-image.stories.cjs.js.map +0 -1
- package/dist/stories/blur-image.stories.d.cts +0 -37
- package/dist/stories/blur-image.stories.d.ts +0 -37
- package/dist/stories/blur-image.stories.esm.js +0 -180
- package/dist/stories/blur-image.stories.esm.js.map +0 -1
- package/dist/stories/breadcrumb.stories.cjs.js +0 -214
- package/dist/stories/breadcrumb.stories.cjs.js.map +0 -1
- package/dist/stories/breadcrumb.stories.d.cts +0 -9
- package/dist/stories/breadcrumb.stories.d.ts +0 -9
- package/dist/stories/breadcrumb.stories.esm.js +0 -145
- package/dist/stories/breadcrumb.stories.esm.js.map +0 -1
- package/dist/stories/empty.stories.cjs.js +0 -93
- package/dist/stories/empty.stories.cjs.js.map +0 -1
- package/dist/stories/empty.stories.d.cts +0 -13
- package/dist/stories/empty.stories.d.ts +0 -13
- package/dist/stories/empty.stories.esm.js +0 -28
- package/dist/stories/empty.stories.esm.js.map +0 -1
- package/dist/stories/navbar.stories.cjs.js +0 -151
- package/dist/stories/navbar.stories.cjs.js.map +0 -1
- package/dist/stories/navbar.stories.d.cts +0 -8
- package/dist/stories/navbar.stories.d.ts +0 -8
- package/dist/stories/navbar.stories.esm.js +0 -74
- package/dist/stories/navbar.stories.esm.js.map +0 -1
- package/dist/stories/sidebar.stories.cjs.js +0 -327
- package/dist/stories/sidebar.stories.cjs.js.map +0 -1
- package/dist/stories/sidebar.stories.d.cts +0 -30
- package/dist/stories/sidebar.stories.d.ts +0 -30
- package/dist/stories/sidebar.stories.esm.js +0 -258
- package/dist/stories/sidebar.stories.esm.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,74 +1,60 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@c-rex/components",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"type": "module",
|
|
3
|
+
"version": "0.0.11",
|
|
5
4
|
"files": [
|
|
6
|
-
"
|
|
5
|
+
"src"
|
|
7
6
|
],
|
|
8
7
|
"publishConfig": {
|
|
9
8
|
"access": "public"
|
|
10
|
-
|
|
9
|
+
},
|
|
10
|
+
"sideEffects": false,
|
|
11
11
|
"exports": {
|
|
12
12
|
"./autocomplete": {
|
|
13
|
-
"types": "./
|
|
14
|
-
"import": "./
|
|
15
|
-
"require": "./dist/autocomplete.cjs.js"
|
|
13
|
+
"types": "./src/autocomplete.tsx",
|
|
14
|
+
"import": "./src/autocomplete.tsx"
|
|
16
15
|
},
|
|
17
16
|
"./blog-card": {
|
|
18
|
-
"types": "./
|
|
19
|
-
"import": "./
|
|
20
|
-
"require": "./dist/blog-card.cjs.js"
|
|
17
|
+
"types": "./src/blog-card.tsx",
|
|
18
|
+
"import": "./src/blog-card.tsx"
|
|
21
19
|
},
|
|
22
20
|
"./blur-image": {
|
|
23
|
-
"types": "./
|
|
24
|
-
"import": "./
|
|
25
|
-
"require": "./dist/blur-image.cjs.js"
|
|
21
|
+
"types": "./src/blur-image.tsx",
|
|
22
|
+
"import": "./src/blur-image.tsx"
|
|
26
23
|
},
|
|
27
24
|
"./breadcrumb": {
|
|
28
|
-
"types": "./
|
|
29
|
-
"import": "./
|
|
30
|
-
"require": "./dist/breadcrumb.cjs.js"
|
|
25
|
+
"types": "./src/breadcrumb.tsx",
|
|
26
|
+
"import": "./src/breadcrumb.tsx"
|
|
31
27
|
},
|
|
32
28
|
"./empty": {
|
|
33
|
-
"types": "./
|
|
34
|
-
"import": "./
|
|
35
|
-
"require": "./dist/empty.cjs.js"
|
|
29
|
+
"types": "./src/empty.tsx",
|
|
30
|
+
"import": "./src/empty.tsx"
|
|
36
31
|
},
|
|
37
32
|
"./navbar": {
|
|
38
|
-
"types": "./
|
|
39
|
-
"import": "./
|
|
40
|
-
"require": "./dist/navbar.cjs.js"
|
|
33
|
+
"types": "./src/navbar/navbar.tsx",
|
|
34
|
+
"import": "./src/navbar/navbar.tsx"
|
|
41
35
|
},
|
|
42
|
-
"./search-wrapper": {
|
|
43
|
-
"types": "./
|
|
44
|
-
"import": "./
|
|
45
|
-
"require": "./dist/providers/search-state-wrapper.cjs.js"
|
|
36
|
+
"./providers/search-state-wrapper": {
|
|
37
|
+
"types": "./src/providers/search-state-wrapper.tsx",
|
|
38
|
+
"import": "./src/providers/search-state-wrapper.tsx"
|
|
46
39
|
},
|
|
47
40
|
"./result-list": {
|
|
48
|
-
"types": "./
|
|
49
|
-
"import": "./
|
|
50
|
-
"require": "./dist/result-list.cjs.js"
|
|
41
|
+
"types": "./src/result-list.tsx",
|
|
42
|
+
"import": "./src/result-list.tsx"
|
|
51
43
|
},
|
|
52
44
|
"./result-view/blog": {
|
|
53
|
-
"types": "./
|
|
54
|
-
"import": "./
|
|
55
|
-
"require": "./dist/result-view/blog.cjs.js"
|
|
45
|
+
"types": "./src/result-view/blog.tsx",
|
|
46
|
+
"import": "./src/result-view/blog.tsx"
|
|
56
47
|
},
|
|
57
48
|
"./result-view/table": {
|
|
58
|
-
"types": "./
|
|
59
|
-
"import": "./
|
|
60
|
-
"require": "./dist/result-view/table.cjs.js"
|
|
49
|
+
"types": "./src/result-view/table.tsx",
|
|
50
|
+
"import": "./src/result-view/table.tsx"
|
|
61
51
|
},
|
|
62
52
|
"./sidebar": {
|
|
63
|
-
"types": "./
|
|
64
|
-
"import": "./
|
|
65
|
-
|
|
66
|
-
},
|
|
67
|
-
"./package.json": "./package.json"
|
|
53
|
+
"types": "./src/sidebar.tsx",
|
|
54
|
+
"import": "./src/sidebar.tsx"
|
|
55
|
+
}
|
|
68
56
|
},
|
|
69
57
|
"scripts": {
|
|
70
|
-
"dev": "tsup --watch",
|
|
71
|
-
"build": "tsup",
|
|
72
58
|
"storybook": "storybook dev -p 6006",
|
|
73
59
|
"build-storybook": "storybook build"
|
|
74
60
|
},
|
|
@@ -82,7 +68,6 @@
|
|
|
82
68
|
"@storybook/nextjs": "^8.6.12",
|
|
83
69
|
"@storybook/react": "^8.6.12",
|
|
84
70
|
"@storybook/test": "^8.6.12",
|
|
85
|
-
"@swc/core": "^1.11.21",
|
|
86
71
|
"@turbo/gen": "^2.4.4",
|
|
87
72
|
"@types/node": "^22.13.10",
|
|
88
73
|
"@types/react": "19.0.10",
|
|
@@ -97,12 +82,12 @@
|
|
|
97
82
|
"typescript": "latest"
|
|
98
83
|
},
|
|
99
84
|
"dependencies": {
|
|
100
|
-
"@c-rex/config": "*",
|
|
101
85
|
"@c-rex/contexts": "*",
|
|
102
86
|
"@c-rex/interfaces": "*",
|
|
103
87
|
"@c-rex/services": "*",
|
|
104
88
|
"@c-rex/ui": "*",
|
|
105
89
|
"@c-rex/utils": "*",
|
|
90
|
+
"@c-rex/config": "*",
|
|
106
91
|
"next": "^14",
|
|
107
92
|
"react": "^18",
|
|
108
93
|
"react-dom": "^18",
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { Command as CommandPrimitive } from "cmdk";
|
|
2
|
+
import { Check } from "lucide-react";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { Input } from "@c-rex/ui/input";
|
|
5
|
+
import {
|
|
6
|
+
Command,
|
|
7
|
+
CommandEmpty,
|
|
8
|
+
CommandGroup,
|
|
9
|
+
CommandItem,
|
|
10
|
+
CommandList
|
|
11
|
+
} from "@c-rex/ui/command";
|
|
12
|
+
import {
|
|
13
|
+
Popover,
|
|
14
|
+
PopoverAnchor,
|
|
15
|
+
PopoverContent
|
|
16
|
+
} from "@c-rex/ui/popover";
|
|
17
|
+
|
|
18
|
+
type Props = {
|
|
19
|
+
initialValue: string;
|
|
20
|
+
onSelect: (value: string) => void;
|
|
21
|
+
onSearch: (value: string) => Promise<string[]>;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const AutoComplete = ({
|
|
25
|
+
initialValue,
|
|
26
|
+
onSearch,
|
|
27
|
+
onSelect,
|
|
28
|
+
}: Props) => {
|
|
29
|
+
const [query, setQuery] = useState(initialValue);
|
|
30
|
+
const [suggestions, setSuggestions] = useState<string[]>([]);
|
|
31
|
+
|
|
32
|
+
const [open, setOpen] = useState(false);
|
|
33
|
+
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
const debounceFetch = setTimeout(() => {
|
|
36
|
+
if (query) {
|
|
37
|
+
onSearch(query).then(setSuggestions);
|
|
38
|
+
} else {
|
|
39
|
+
setSuggestions([]);
|
|
40
|
+
}
|
|
41
|
+
}, 300);
|
|
42
|
+
|
|
43
|
+
return () => clearTimeout(debounceFetch);
|
|
44
|
+
}, [onSearch, query]);
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<div className="flex items-center">
|
|
48
|
+
<Popover open={open} onOpenChange={setOpen}>
|
|
49
|
+
<Command shouldFilter={false}>
|
|
50
|
+
<PopoverAnchor asChild>
|
|
51
|
+
<CommandPrimitive.Input
|
|
52
|
+
asChild
|
|
53
|
+
value={query}
|
|
54
|
+
onValueChange={setQuery}
|
|
55
|
+
onKeyDown={(e) => setOpen(e.key !== "Escape")}
|
|
56
|
+
onMouseDown={() => setOpen(false)}
|
|
57
|
+
onFocus={() => setOpen(true)}
|
|
58
|
+
>
|
|
59
|
+
<Input />
|
|
60
|
+
</CommandPrimitive.Input>
|
|
61
|
+
</PopoverAnchor>
|
|
62
|
+
|
|
63
|
+
{!open && <CommandList aria-hidden="true" className="hidden" />}
|
|
64
|
+
|
|
65
|
+
<PopoverContent
|
|
66
|
+
asChild
|
|
67
|
+
onOpenAutoFocus={(e) => e.preventDefault()}
|
|
68
|
+
onInteractOutside={(e) => {
|
|
69
|
+
if (
|
|
70
|
+
e.target instanceof Element &&
|
|
71
|
+
e.target.hasAttribute("cmdk-input")
|
|
72
|
+
) {
|
|
73
|
+
e.preventDefault();
|
|
74
|
+
}
|
|
75
|
+
}}
|
|
76
|
+
className="w-[--radix-popover-trigger-width] p-0"
|
|
77
|
+
>
|
|
78
|
+
<CommandList>
|
|
79
|
+
{/*isLoading && (
|
|
80
|
+
<CommandPrimitive.Loading>
|
|
81
|
+
<div className="p-1">
|
|
82
|
+
<Skeleton className="h-6 w-full" />
|
|
83
|
+
</div>
|
|
84
|
+
</CommandPrimitive.Loading>
|
|
85
|
+
)*/}
|
|
86
|
+
|
|
87
|
+
{suggestions.length > 0 ? (
|
|
88
|
+
<CommandGroup>
|
|
89
|
+
{suggestions.map((option) => (
|
|
90
|
+
<CommandItem
|
|
91
|
+
key={option}
|
|
92
|
+
value={option}
|
|
93
|
+
onMouseDown={(e) => e.preventDefault()}
|
|
94
|
+
onSelect={(inputValue) => {
|
|
95
|
+
setOpen(false);
|
|
96
|
+
onSelect(inputValue ?? "");
|
|
97
|
+
}}
|
|
98
|
+
>
|
|
99
|
+
<Check className="mr-2 h-4 w-4 opacity-0" />
|
|
100
|
+
{option}
|
|
101
|
+
</CommandItem>
|
|
102
|
+
))}
|
|
103
|
+
</CommandGroup>
|
|
104
|
+
) : (
|
|
105
|
+
<CommandEmpty>No suggestions.</CommandEmpty>
|
|
106
|
+
)}
|
|
107
|
+
</CommandList>
|
|
108
|
+
</PopoverContent>
|
|
109
|
+
</Command>
|
|
110
|
+
</Popover>
|
|
111
|
+
</div>
|
|
112
|
+
);
|
|
113
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import Link from "next/link";
|
|
2
|
+
import { cn } from "@c-rex/utils";
|
|
3
|
+
import { BlurImage } from "./blur-image";
|
|
4
|
+
|
|
5
|
+
//import Author from "./author";
|
|
6
|
+
|
|
7
|
+
interface BlogCardProp {
|
|
8
|
+
data: {
|
|
9
|
+
title: string;
|
|
10
|
+
blurDataURL: string;
|
|
11
|
+
image: string;
|
|
12
|
+
description: string;
|
|
13
|
+
authors: string;
|
|
14
|
+
_id: string;
|
|
15
|
+
date: string;
|
|
16
|
+
slug: string;
|
|
17
|
+
};
|
|
18
|
+
priority?: boolean;
|
|
19
|
+
horizontal?: boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const BlogCard = ({
|
|
23
|
+
data,
|
|
24
|
+
priority,
|
|
25
|
+
horizontal = false,
|
|
26
|
+
}: BlogCardProp) => {
|
|
27
|
+
return (
|
|
28
|
+
<article
|
|
29
|
+
className={cn(
|
|
30
|
+
"group relative",
|
|
31
|
+
horizontal
|
|
32
|
+
? "grid grid-cols-1 gap-3 md:grid-cols-2 md:gap-6"
|
|
33
|
+
: "flex flex-col space-y-2",
|
|
34
|
+
)}
|
|
35
|
+
>
|
|
36
|
+
{data.image && (
|
|
37
|
+
<div className="w-full overflow-hidden rounded-xl border">
|
|
38
|
+
<BlurImage
|
|
39
|
+
alt={data.title}
|
|
40
|
+
blurDataURL={data.blurDataURL}
|
|
41
|
+
className={cn(
|
|
42
|
+
"size-full object-cover object-center",
|
|
43
|
+
horizontal ? "lg:h-72" : null,
|
|
44
|
+
)}
|
|
45
|
+
width={800}
|
|
46
|
+
height={400}
|
|
47
|
+
priority={priority}
|
|
48
|
+
placeholder="blur"
|
|
49
|
+
src={data.image}
|
|
50
|
+
sizes="(max-width: 768px) 750px, 600px"
|
|
51
|
+
/>
|
|
52
|
+
</div>
|
|
53
|
+
)}
|
|
54
|
+
<div
|
|
55
|
+
className={cn(
|
|
56
|
+
"flex flex-1 flex-col",
|
|
57
|
+
horizontal ? "justify-center" : "justify-between",
|
|
58
|
+
)}
|
|
59
|
+
>
|
|
60
|
+
<div className="w-full">
|
|
61
|
+
<h2 className="my-1.5 line-clamp-2 font-heading text-2xl">
|
|
62
|
+
{data.title}
|
|
63
|
+
</h2>
|
|
64
|
+
{data.description && (
|
|
65
|
+
<p className="line-clamp-2 text-muted-foreground">
|
|
66
|
+
{data.description}
|
|
67
|
+
</p>
|
|
68
|
+
)}
|
|
69
|
+
</div>
|
|
70
|
+
<div className="mt-4 flex items-center space-x-3">
|
|
71
|
+
<div className="flex items-center -space-x-2">
|
|
72
|
+
{data.authors && (
|
|
73
|
+
<p className="text-sm text-muted-foreground">{data.authors}</p>
|
|
74
|
+
)}
|
|
75
|
+
</div>
|
|
76
|
+
|
|
77
|
+
{data.date && (
|
|
78
|
+
<p className="text-sm text-muted-foreground">{data.date}</p>
|
|
79
|
+
)}
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
<Link href={data.slug} className="absolute inset-0" target="_blank">
|
|
83
|
+
<span className="sr-only">View Article</span>
|
|
84
|
+
</Link>
|
|
85
|
+
</article>
|
|
86
|
+
);
|
|
87
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import type { ComponentProps } from "react";
|
|
5
|
+
import Image from "next/image";
|
|
6
|
+
import { cn } from "@c-rex/utils";
|
|
7
|
+
|
|
8
|
+
export const BlurImage = (props: ComponentProps<typeof Image>) => {
|
|
9
|
+
const [isLoading, setLoading] = useState(true);
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<Image
|
|
13
|
+
{...props}
|
|
14
|
+
alt={props.alt}
|
|
15
|
+
className={cn(
|
|
16
|
+
props.className,
|
|
17
|
+
"duration-500 ease-in-out",
|
|
18
|
+
isLoading ? "blur-sm" : "blur-0",
|
|
19
|
+
)}
|
|
20
|
+
onLoad={() => setLoading(false)}
|
|
21
|
+
/>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { FC, ReactNode } from "react";
|
|
2
|
+
import {
|
|
3
|
+
Breadcrumb as BreadcrumbComponent,
|
|
4
|
+
BreadcrumbItem,
|
|
5
|
+
BreadcrumbLink,
|
|
6
|
+
BreadcrumbList,
|
|
7
|
+
BreadcrumbPage,
|
|
8
|
+
BreadcrumbSeparator
|
|
9
|
+
} from "@c-rex/ui/breadcrumb";
|
|
10
|
+
import { Skeleton } from "@c-rex/ui/skeleton";
|
|
11
|
+
import { TreeOfContent } from "@c-rex/interfaces";
|
|
12
|
+
|
|
13
|
+
interface BreadcrumbProps {
|
|
14
|
+
items: TreeOfContent[];
|
|
15
|
+
loading?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const Breadcrumb: FC<BreadcrumbProps> = ({ items, loading }) => {
|
|
19
|
+
if (!items) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (loading) {
|
|
24
|
+
return (
|
|
25
|
+
<BreadcrumbComponent>
|
|
26
|
+
<BreadcrumbList>
|
|
27
|
+
<BreadcrumbItem>
|
|
28
|
+
<BreadcrumbPage>Home</BreadcrumbPage>
|
|
29
|
+
</BreadcrumbItem>
|
|
30
|
+
<BreadcrumbSeparator />
|
|
31
|
+
<BreadcrumbItem>
|
|
32
|
+
<Skeleton className="w-40 h-6" />
|
|
33
|
+
</BreadcrumbItem>
|
|
34
|
+
<BreadcrumbSeparator />
|
|
35
|
+
<BreadcrumbItem>
|
|
36
|
+
<Skeleton className="w-40 h-6" />
|
|
37
|
+
</BreadcrumbItem>
|
|
38
|
+
</BreadcrumbList>
|
|
39
|
+
</BreadcrumbComponent>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const homeItem: TreeOfContent = {
|
|
44
|
+
link: "/",
|
|
45
|
+
label: "Home",
|
|
46
|
+
id: "home",
|
|
47
|
+
active: false,
|
|
48
|
+
children: [],
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const newItemList: TreeOfContent[] = [homeItem, ...items];
|
|
52
|
+
|
|
53
|
+
const renderLink = (showLink: boolean, item: TreeOfContent): ReactNode => {
|
|
54
|
+
if (showLink) {
|
|
55
|
+
return <BreadcrumbLink href={item.link}>{item.label}</BreadcrumbLink>;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return <BreadcrumbPage>{item.label}</BreadcrumbPage>;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<BreadcrumbComponent>
|
|
63
|
+
<BreadcrumbList>
|
|
64
|
+
{newItemList.map((item, index) => {
|
|
65
|
+
const isLast = index === newItemList.length - 1;
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<>
|
|
69
|
+
<BreadcrumbItem key={`${item.label}-item`}>
|
|
70
|
+
{renderLink(!isLast, item)}
|
|
71
|
+
</BreadcrumbItem>
|
|
72
|
+
{!isLast && (
|
|
73
|
+
<BreadcrumbSeparator key={`${item.label}-separator`} />
|
|
74
|
+
)}
|
|
75
|
+
</>
|
|
76
|
+
);
|
|
77
|
+
})}
|
|
78
|
+
</BreadcrumbList>
|
|
79
|
+
</BreadcrumbComponent>
|
|
80
|
+
);
|
|
81
|
+
};
|
package/src/empty.tsx
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { FC } from "react";
|
|
2
|
+
import { Alert, AlertDescription, AlertTitle } from "@c-rex/ui/alert";
|
|
3
|
+
|
|
4
|
+
export const Empty: FC = () => {
|
|
5
|
+
return (
|
|
6
|
+
<Alert className="my-2">
|
|
7
|
+
<AlertTitle>No results</AlertTitle>
|
|
8
|
+
<AlertDescription>
|
|
9
|
+
No data available. Please try adjusting your search or filter criteria.
|
|
10
|
+
</AlertDescription>
|
|
11
|
+
</Alert>
|
|
12
|
+
);
|
|
13
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import React, { FC } from "react";
|
|
2
|
+
import Link from "next/link";
|
|
3
|
+
import Image from "next/image";
|
|
4
|
+
import { SingOut, SingInBtn } from "./sing-in-out-btns";
|
|
5
|
+
import { getServerSession } from "next-auth";
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
interface NavBarProps {
|
|
9
|
+
scroll?: boolean;
|
|
10
|
+
large?: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const NavBar: FC<NavBarProps> = async () => {
|
|
14
|
+
const session = await getServerSession()
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<header className="sticky top-0 z-40 flex w-full bg-background/60 backdrop-blur-xl transition-all bg-transparent border-b justify-center py-4">
|
|
18
|
+
<div className="container flex justify-between">
|
|
19
|
+
<div className="flex gap-6 md:gap-10">
|
|
20
|
+
<Link href="/" className="flex items-center space-x-1.5">
|
|
21
|
+
<Image
|
|
22
|
+
src="/img/logo.png"
|
|
23
|
+
alt="C-rex Logo"
|
|
24
|
+
width={88}
|
|
25
|
+
height={50}
|
|
26
|
+
/>
|
|
27
|
+
</Link>
|
|
28
|
+
|
|
29
|
+
<nav className="hidden gap-6 md:flex">
|
|
30
|
+
{/*
|
|
31
|
+
TODO: add map to load links
|
|
32
|
+
TODO: add function to validate active item
|
|
33
|
+
*/}
|
|
34
|
+
<Link
|
|
35
|
+
href={"/blog"}
|
|
36
|
+
prefetch={true}
|
|
37
|
+
className={
|
|
38
|
+
"flex items-center text-lg font-medium transition-colors hover:text-foreground/80 sm:text-sm"
|
|
39
|
+
}
|
|
40
|
+
>
|
|
41
|
+
Blog
|
|
42
|
+
</Link>
|
|
43
|
+
|
|
44
|
+
<Link
|
|
45
|
+
href={"#"}
|
|
46
|
+
prefetch={true}
|
|
47
|
+
className={
|
|
48
|
+
"flex items-center text-lg font-medium transition-colors hover:text-foreground/80 sm:text-sm"
|
|
49
|
+
}
|
|
50
|
+
>
|
|
51
|
+
Documentation
|
|
52
|
+
</Link>
|
|
53
|
+
</nav>
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
<div className="flex items-center space-x-3">
|
|
57
|
+
{session ? (
|
|
58
|
+
<>
|
|
59
|
+
<span>Welcome, {session.user?.name}</span>
|
|
60
|
+
<SingOut />
|
|
61
|
+
</>
|
|
62
|
+
) : (
|
|
63
|
+
<SingInBtn />
|
|
64
|
+
)}
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
</header>
|
|
68
|
+
);
|
|
69
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { signOut, signIn } from "next-auth/react";
|
|
5
|
+
import { Button } from "@c-rex/ui/button";
|
|
6
|
+
|
|
7
|
+
export const SingInBtn = () => (
|
|
8
|
+
<Button
|
|
9
|
+
className="hidden gap-2 px-5 md:flex"
|
|
10
|
+
variant="default"
|
|
11
|
+
size="sm"
|
|
12
|
+
rounded="full"
|
|
13
|
+
onClick={() => signIn("crex", { callbackUrl: "/" })}
|
|
14
|
+
>
|
|
15
|
+
<span>Sign In</span>
|
|
16
|
+
</Button>
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
export const SingOut = () => (
|
|
20
|
+
<Button
|
|
21
|
+
className="hidden gap-2 px-5 md:flex"
|
|
22
|
+
variant="default"
|
|
23
|
+
size="sm"
|
|
24
|
+
rounded="full"
|
|
25
|
+
onClick={() => signOut()}
|
|
26
|
+
>
|
|
27
|
+
<span>Sign out</span>
|
|
28
|
+
</Button>
|
|
29
|
+
);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { SearchProvider } from "@c-rex/contexts";
|
|
4
|
+
import { FC, ReactNode } from "react";
|
|
5
|
+
|
|
6
|
+
interface SearchStateWrapperProps {
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
filters: {
|
|
9
|
+
searchValue: string;
|
|
10
|
+
page: number;
|
|
11
|
+
selectedLanguage: string[];
|
|
12
|
+
availableLanguages: string[];
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const SearchStateWrapper: FC<SearchStateWrapperProps> = ({
|
|
17
|
+
children,
|
|
18
|
+
filters,
|
|
19
|
+
}) => {
|
|
20
|
+
return <SearchProvider value={{ ...filters }}>{children}</SearchProvider>;
|
|
21
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { FC } from "react";
|
|
2
|
+
import { informationUnitsItems } from "@c-rex/interfaces";
|
|
3
|
+
import { Empty } from "./empty";
|
|
4
|
+
//import { CUSTOMER_CONFIG } from '@/config/customerConfig';
|
|
5
|
+
//import { RESULT_VIEW_OPTIONS } from '@/constants/components';
|
|
6
|
+
import BlogView from './result-view/blog';
|
|
7
|
+
|
|
8
|
+
const ViewComponent = BlogView;
|
|
9
|
+
|
|
10
|
+
interface ResultListProps {
|
|
11
|
+
items: informationUnitsItems[];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const ResultList: FC<ResultListProps> = ({ items }) => {
|
|
15
|
+
return <>{items.length == 0 ? <Empty /> : <ViewComponent items={items} />}</>;
|
|
16
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import BlogView from '../result-view/blog';
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof BlogView> = {
|
|
5
|
+
title: 'Components/ResultView/Blog',
|
|
6
|
+
component: BlogView,
|
|
7
|
+
parameters: {
|
|
8
|
+
layout: 'centered',
|
|
9
|
+
},
|
|
10
|
+
tags: ['autodocs'],
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default meta;
|
|
14
|
+
type Story = StoryObj<typeof BlogView>;
|
|
15
|
+
|
|
16
|
+
const mockItems = [
|
|
17
|
+
{
|
|
18
|
+
id: '1',
|
|
19
|
+
shortId: 'doc-1',
|
|
20
|
+
labels: [
|
|
21
|
+
{ value: 'Getting Started with C-Rex', language: 'en-US' },
|
|
22
|
+
{ value: 'Começando com C-Rex', language: 'pt-BR' }
|
|
23
|
+
],
|
|
24
|
+
languages: ['pt-BR'],
|
|
25
|
+
type: 'document',
|
|
26
|
+
renditions: [],
|
|
27
|
+
directoryNodes: []
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: '2',
|
|
31
|
+
shortId: 'doc-2',
|
|
32
|
+
labels: [
|
|
33
|
+
{ value: 'Advanced Configuration Guide', language: 'en-US' }
|
|
34
|
+
],
|
|
35
|
+
languages: ['en-US'],
|
|
36
|
+
type: 'document',
|
|
37
|
+
renditions: [],
|
|
38
|
+
directoryNodes: []
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: '3',
|
|
42
|
+
shortId: 'doc-3',
|
|
43
|
+
labels: [
|
|
44
|
+
{ value: 'API Documentation', language: 'en-US' },
|
|
45
|
+
{ value: 'Documentation API', language: 'fr-FR' }
|
|
46
|
+
],
|
|
47
|
+
languages: ['fr-FR'],
|
|
48
|
+
type: 'document',
|
|
49
|
+
renditions: [],
|
|
50
|
+
directoryNodes: []
|
|
51
|
+
}
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
export const Default: Story = {
|
|
55
|
+
args: {
|
|
56
|
+
items: mockItems as any
|
|
57
|
+
}
|
|
58
|
+
};
|