@ossy/connected-components 0.1.4 → 0.1.6

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.
Files changed (69) hide show
  1. package/build/index.js +638 -0
  2. package/package.json +7 -3
  3. package/.storybook/main.js +0 -19
  4. package/.storybook/preview.js +0 -13
  5. package/CHANGELOG.md +0 -166
  6. package/rollup.config.js +0 -31
  7. package/src/app/App.jsx +0 -29
  8. package/src/app/App.stories.jsx +0 -36
  9. package/src/app/AppSettings.jsx +0 -22
  10. package/src/app/index.js +0 -3
  11. package/src/app/useAnalytics.jsx +0 -18
  12. package/src/index.js +0 -11
  13. package/src/layout/Layout.jsx +0 -25
  14. package/src/layout/Layout.stories.jsx +0 -16
  15. package/src/layout/index.js +0 -1
  16. package/src/ossybot/Ossybot.jsx +0 -67
  17. package/src/ossybot/Ossybot.stories.jsx +0 -26
  18. package/src/ossybot/index.js +0 -1
  19. package/src/page/Page.jsx +0 -33
  20. package/src/page/Page.stories.jsx +0 -17
  21. package/src/page/index.js +0 -1
  22. package/src/page-data-loader/PageDataLoader.jsx +0 -90
  23. package/src/page-data-loader/PageDataLoader.stories.jsx +0 -16
  24. package/src/page-data-loader/index.js +0 -1
  25. package/src/pages-module/PagesModule.jsx +0 -8
  26. package/src/pages-module/PagesModule.stories.jsx +0 -17
  27. package/src/pages-module/index.js +0 -1
  28. package/src/resume/Resume.jsx +0 -13
  29. package/src/resume/Resume.stories.jsx +0 -23
  30. package/src/resume/Resume.template.js +0 -80
  31. package/src/resume/index.js +0 -3
  32. package/src/resume/useResume.js +0 -112
  33. package/src/section/Section.jsx +0 -93
  34. package/src/section/Section.stories.jsx +0 -17
  35. package/src/section/index.js +0 -1
  36. package/src/stories/Button.jsx +0 -39
  37. package/src/stories/Button.stories.js +0 -49
  38. package/src/stories/Configure.mdx +0 -364
  39. package/src/stories/Header.jsx +0 -56
  40. package/src/stories/Header.stories.js +0 -29
  41. package/src/stories/Page.jsx +0 -69
  42. package/src/stories/Page.stories.js +0 -28
  43. package/src/stories/assets/accessibility.png +0 -0
  44. package/src/stories/assets/accessibility.svg +0 -1
  45. package/src/stories/assets/addon-library.png +0 -0
  46. package/src/stories/assets/assets.png +0 -0
  47. package/src/stories/assets/avif-test-image.avif +0 -0
  48. package/src/stories/assets/context.png +0 -0
  49. package/src/stories/assets/discord.svg +0 -1
  50. package/src/stories/assets/docs.png +0 -0
  51. package/src/stories/assets/figma-plugin.png +0 -0
  52. package/src/stories/assets/github.svg +0 -1
  53. package/src/stories/assets/share.png +0 -0
  54. package/src/stories/assets/styling.png +0 -0
  55. package/src/stories/assets/testing.png +0 -0
  56. package/src/stories/assets/theming.png +0 -0
  57. package/src/stories/assets/tutorials.svg +0 -1
  58. package/src/stories/assets/youtube.svg +0 -1
  59. package/src/stories/button.css +0 -30
  60. package/src/stories/header.css +0 -32
  61. package/src/stories/page.css +0 -68
  62. package/src/theme-editor/ThemeEditor.jsx +0 -132
  63. package/src/theme-editor/ThemeEditor.stories.jsx +0 -16
  64. package/src/theme-editor/index.js +0 -1
  65. package/src/theme-provider/ThemeProvider.jsx +0 -9
  66. package/src/theme-provider/ThemeProvider.stories.jsx +0 -16
  67. package/src/theme-provider/index.js +0 -1
  68. package/src/use-active-page-location/index.js +0 -1
  69. package/src/use-active-page-location/useActivePageLocation.js +0 -54
package/build/index.js ADDED
@@ -0,0 +1,638 @@
1
+ import React$1, { useState, useMemo, useCallback, useEffect, useContext, createContext } from 'react';
2
+ import { SDK } from '@ossy/sdk';
3
+ import { useResource, WorkspaceProvider, AsyncStatus, useQuery, useResources } from '@ossy/sdk-react';
4
+ import { Overlay, View, Button, Text, useTheme, Theme, useDocumentTitle, Switch } from '@ossy/design-system';
5
+ import { Router } from '@ossy/router-react';
6
+ import { Resume as Resume$1 } from '@ossy/design-system-extras';
7
+
8
+ const overlayStyles = {
9
+ background: 'transparent',
10
+ display: 'content',
11
+ pointerEvents: 'none'
12
+ };
13
+ const blobStyles = {
14
+ boxShadow: '2px 2px 5px hsla(0, 0%, 0%, .2)',
15
+ borderRadius: '999px',
16
+ position: 'absolute',
17
+ right: 'var(--space-m)',
18
+ bottom: 'var(--space-m)',
19
+ cursor: 'pointer',
20
+ transition: 'transform .5s',
21
+ pointerEvents: 'auto',
22
+ padding: 'var(--space-m)'
23
+ };
24
+ const editorContainerStyles = {
25
+ position: 'absolute',
26
+ right: '0',
27
+ top: '0',
28
+ height: '100%',
29
+ width: '100%',
30
+ display: 'flex',
31
+ justifyContent: 'flex-end',
32
+ alignItems: 'stretch',
33
+ padding: '8px 32px'
34
+ };
35
+ const editorStyles = {
36
+ width: '100%',
37
+ maxWidth: '350px',
38
+ height: '100%',
39
+ boxShadow: '2px 2px 5px hsla(0, 0%, 0%, .2)',
40
+ padding: '16px 16px 76px 16px',
41
+ overflowX: 'none',
42
+ overflowY: 'auto',
43
+ pointerEvents: 'auto'
44
+ };
45
+ const ThemeSwitcher = () => {
46
+ const {
47
+ activeTheme,
48
+ setTheme,
49
+ themes
50
+ } = useTheme();
51
+ return /*#__PURE__*/React.createElement(View, {
52
+ gap: "s"
53
+ }, /*#__PURE__*/React.createElement(Text, null, "Theme"), /*#__PURE__*/React.createElement(View, {
54
+ layout: "row-wrap",
55
+ gap: "s"
56
+ }, themes.map(themeName => /*#__PURE__*/React.createElement(Button, {
57
+ variant: themeName === activeTheme ? 'tag-active' : 'tag',
58
+ onClick: () => setTheme(themeName)
59
+ }, themeName))));
60
+ };
61
+ const ThemeEditor = () => {
62
+ const {
63
+ updateResourceContent
64
+ } = useResource('PCX53TaGviq4_8KvK-VOp');
65
+ const [isEditorOpen, setIsEditorOpen] = useState(false);
66
+ const [viewCount, setViewCount] = useState(0);
67
+ // const [theme, temporarilyUpdateTheme] = useTheme()
68
+ const theme = {};
69
+ const toggleStyles = useMemo(() => !isEditorOpen ? blobStyles : {
70
+ ...blobStyles,
71
+ transform: 'rotate(-45deg)'
72
+ }, [isEditorOpen]);
73
+ const onToggle = useCallback(() => {
74
+ setIsEditorOpen(!isEditorOpen);
75
+ }, [isEditorOpen, setIsEditorOpen]);
76
+ const onThemeChange = event => {
77
+ const name = event.target.dataset.name;
78
+ const updatedValue = event.target.value;
79
+ if (!name) return;
80
+ if (!updatedValue) return;
81
+ };
82
+ const onSaveTheme = event => {
83
+ event.preventDefault();
84
+ updateResourceContent(theme);
85
+ };
86
+ useEffect(() => {
87
+ if (!isEditorOpen) return;
88
+ const views = document.querySelectorAll('[data-view]');
89
+ views.forEach(view => view.style.border = '1px solid red');
90
+ setViewCount(views.length);
91
+ }, [isEditorOpen]);
92
+ return /*#__PURE__*/React.createElement(Overlay, {
93
+ isVisible: true,
94
+ style: overlayStyles
95
+ }, isEditorOpen && /*#__PURE__*/React.createElement("div", {
96
+ style: editorContainerStyles
97
+ }, /*#__PURE__*/React.createElement(View, {
98
+ surface: "primary",
99
+ roundness: "m",
100
+ gap: "m",
101
+ style: editorStyles
102
+ }, /*#__PURE__*/React.createElement(View, {
103
+ as: "form",
104
+ gap: "s",
105
+ onSubmit: onSaveTheme,
106
+ onChange: onThemeChange
107
+ }, Object.entries(theme).map(([name, value]) => /*#__PURE__*/React.createElement("div", {
108
+ style: {
109
+ marginBottom: '16px'
110
+ }
111
+ }, /*#__PURE__*/React.createElement("label", {
112
+ style: {
113
+ display: 'block',
114
+ fontFamily: 'sans-serif',
115
+ marginBottom: '4px',
116
+ fontWeight: 'bold'
117
+ }
118
+ }, name), /*#__PURE__*/React.createElement("input", {
119
+ value: value,
120
+ "data-name": name,
121
+ style: {
122
+ width: '100%',
123
+ padding: '4px'
124
+ }
125
+ }))), /*#__PURE__*/React.createElement(Button, {
126
+ type: "submit",
127
+ variant: "cta"
128
+ }, "Save")), /*#__PURE__*/React.createElement(ThemeSwitcher, null), /*#__PURE__*/React.createElement(Text, null, "Views: ", viewCount))), /*#__PURE__*/React.createElement(Button, {
129
+ variant: "cta",
130
+ prefix: "math-plus",
131
+ style: toggleStyles,
132
+ onClick: onToggle
133
+ }));
134
+ };
135
+
136
+ const useAppSettings = () => useContext(AppContext);
137
+ function defaultAppSettings() {
138
+ return {
139
+ workspaceId: undefined,
140
+ defaultLanguage: undefined,
141
+ supportedLanguages: [],
142
+ theme: undefined,
143
+ themes: undefined,
144
+ routes: [],
145
+ initialEntries: [],
146
+ initialIndex: 0,
147
+ router: 'browser',
148
+ gaId: undefined,
149
+ apiUrl: undefined,
150
+ devMode: false
151
+ };
152
+ }
153
+
154
+ const AppContext = /*#__PURE__*/createContext(defaultAppSettings());
155
+ const App = _appSettings => {
156
+ const appSettings = {
157
+ ...defaultAppSettings(),
158
+ ..._appSettings
159
+ };
160
+ const sdk = SDK.of({
161
+ apiUrl: appSettings.apiUrl,
162
+ workspaceId: appSettings.workspaceId
163
+ });
164
+ return /*#__PURE__*/React$1.createElement(AppContext.Provider, {
165
+ value: appSettings
166
+ }, /*#__PURE__*/React$1.createElement(Theme, {
167
+ theme: appSettings.theme,
168
+ themes: appSettings.themes
169
+ }, /*#__PURE__*/React$1.createElement(WorkspaceProvider, {
170
+ sdk: sdk
171
+ }, /*#__PURE__*/React$1.createElement(Router, _appSettings), appSettings.devMode && /*#__PURE__*/React$1.createElement(ThemeEditor, null))));
172
+ };
173
+
174
+ function _extends() {
175
+ return _extends = Object.assign ? Object.assign.bind() : function (n) {
176
+ for (var e = 1; e < arguments.length; e++) {
177
+ var t = arguments[e];
178
+ for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
179
+ }
180
+ return n;
181
+ }, _extends.apply(null, arguments);
182
+ }
183
+
184
+ const Layout = ({
185
+ layoutId,
186
+ ...props
187
+ }) => {
188
+ const {
189
+ status,
190
+ resource
191
+ } = useResource(layoutId);
192
+ const layoutStyles = useMemo(() => !resource.data ? {} : {
193
+ display: 'grid',
194
+ gridTemplateRows: resource.data.rows,
195
+ gridTemplateColumns: resource.data.columns,
196
+ gridTemplateAreas: resource.data.areas
197
+ }, [resource]);
198
+ return status === AsyncStatus.Success ? /*#__PURE__*/React.createElement("div", _extends({}, props, {
199
+ style: layoutStyles
200
+ })) : /*#__PURE__*/React.createElement(React.Fragment, null);
201
+ };
202
+
203
+ // https://twitter.com/jh3yy/status/1762979019446698310
204
+ // button:hover span:after {
205
+ // animation: flip 0.2s calc(var(--i) * 0.05s);
206
+ // }
207
+ // @​keyframes flip {
208
+ // 20% { content: '_'; }
209
+ // 40% { content: var(--c1); }
210
+ // 60% { content: var(--c2); }
211
+ // }
212
+
213
+ // <button>
214
+ // <span style="--i: 0; --c1: 'x'; --c2: '$'; --c3: '≈';">C</span>
215
+ // <span style="--i: 1; --c1: 'ç'; --c2: '&'; --c3: 'π';">l</span>
216
+ // <!-- Other characters -->
217
+ // <span class="sr-only">Click Me</span>
218
+ // </button>
219
+
220
+ const Ossybot = ({
221
+ style = {},
222
+ surface = "cta",
223
+ icon,
224
+ ...props
225
+ }) => {
226
+ return /*#__PURE__*/React$1.createElement(React$1.Fragment, null, /*#__PURE__*/React$1.createElement("style", {
227
+ href: "@ossy/design-system/ossybot",
228
+ precedence: "high"
229
+ }, `
230
+ @keyframes flip {
231
+ 0% {
232
+ content: '_';
233
+ }
234
+ 60% {
235
+ content: var(--c1);
236
+ }
237
+ 100% {
238
+ content: var(--c2);
239
+ }
240
+ }
241
+
242
+ /* Define the animation */
243
+ [data-animation="flip"] {
244
+ animation: flip 0.2s calc(var(--i) * 0.05s) infinite;
245
+ }
246
+ `), /*#__PURE__*/React$1.createElement(Button, _extends({
247
+ "data-animation": "flip",
248
+ prefix: {
249
+ name: icon,
250
+ size: 'm'
251
+ },
252
+ variant: surface
253
+ }, props, {
254
+ style: {
255
+ '--size': '64px',
256
+ width: 'var(--size)',
257
+ height: 'var(--size)',
258
+ padding: 'var(--space-m)',
259
+ borderRadius: '999px',
260
+ ...style
261
+ }
262
+ })));
263
+ };
264
+
265
+ const appendSlash = string => string[string.length - 1] === '/' ? string : `${string}/`;
266
+ const prependSlash = string => string[0] === '/' ? string : `/${string}`;
267
+ const padWithSlash = string => appendSlash(prependSlash(string));
268
+ const Predicates = {
269
+ byLength: desiredLength => route => {
270
+ const routeParts = route.split('/').filter(x => !!x);
271
+ return routeParts.length === desiredLength;
272
+ },
273
+ byParamPlaceHolders: activePathname => route => {
274
+ const routeParts = route.split('/').filter(x => !!x).reduce((parts, part) => part.startsWith(':') ? [...parts, '.+?'] : [...parts, part], []).join('/');
275
+ const regex = new RegExp(`^${padWithSlash(routeParts)}$`);
276
+ const passes = regex.test(activePathname);
277
+ return passes;
278
+ }
279
+ };
280
+ const useActivePageLocation = path => {
281
+ console.log('useActivePageLocation path', path);
282
+ const {
283
+ routes: pages
284
+ } = useAppSettings();
285
+ if (!path) return;
286
+
287
+ // TODO: this needs tests because I don't think it works right
288
+ const activePathname = path === '' ? '/' : padWithSlash(path);
289
+ const registeredPageRoutes = pages.map(page => padWithSlash(page.path));
290
+ const exactRouteMatch = registeredPageRoutes.find(route => route === activePathname);
291
+ let activePageLocation;
292
+ if (!!exactRouteMatch) {
293
+ activePageLocation = exactRouteMatch;
294
+ } else {
295
+ const activePathnameParts = activePathname.split('/').filter(x => !!x);
296
+ const dynamicRouteMatch = registeredPageRoutes.find(route => Predicates.byLength(activePathnameParts.length)(route) && Predicates.byParamPlaceHolders(activePathname)(route));
297
+ activePageLocation = dynamicRouteMatch;
298
+ }
299
+ console.log('useActivePageLocation exactRouteMatch', exactRouteMatch);
300
+ console.log('useActivePageLocation activePageLocation', activePageLocation);
301
+ return activePageLocation;
302
+ };
303
+
304
+ // import { useParams } from '../use-params'
305
+ // import { AppHeader } from './AppHeader'
306
+ // import { AppFooter } from './AppFooter'
307
+ // import { AccentBorder } from './AccentBorder'
308
+ // import { ContactUsContent } from './ContactUsContent'
309
+ // import { ResourcesContent } from './ResourcesContent'
310
+ // import { ResourceContent } from './ResourceContent'
311
+ // import { HomeHero } from './HomeHero'
312
+ // import { HomeContent } from './HomeContent'
313
+ // import { ConsultantsContent } from './ConsultantsContent'
314
+ // import { CommandBar } from './CommandBar'
315
+ // import { ConsultantPage } from './ConsultantPage'
316
+
317
+ const components = {
318
+ // AppHeader: AppHeader,
319
+ // AppFooter: AppFooter,
320
+ // CommandBar: CommandBar,
321
+ // AccentBorder: AccentBorder,
322
+ // HomeHero: HomeHero,
323
+ // HomeContent: HomeContent,
324
+ // ContactUsContent: ContactUsContent,
325
+ // ConsultantsContent: ConsultantsContent,
326
+ // ResourcesContent: ResourcesContent,
327
+ // ResourceContent: ResourceContent,
328
+ // ConsultantContent: ConsultantPage
329
+ };
330
+ const Section = ({
331
+ slotName,
332
+ componentId,
333
+ componentProps: pageSpecificProps = ''
334
+ }) => {
335
+ const params = useParams();
336
+ const Component = components[componentId] || (() => /*#__PURE__*/React.createElement(React.Fragment, null, "No component found"));
337
+ const [componentProps, setComponentProps] = useState({});
338
+ const {
339
+ status: defaultPropsStatus,
340
+ resources: defaultPropsQuery
341
+ } = useQuery({
342
+ location: `/design-system/${componentId}/`,
343
+ name: 'default',
344
+ type: '7Bb2zDh2EK65rV_0XHo_W'
345
+ });
346
+ const {
347
+ status: languageSpecificPropsStatus,
348
+ resources: languageSpecificPropsQuery
349
+ } = useQuery({
350
+ location: `/design-system/${componentId}/`,
351
+ name: params.marketCode,
352
+ type: '7Bb2zDh2EK65rV_0XHo_W'
353
+ });
354
+ const loaded = useMemo(() => [defaultPropsStatus, languageSpecificPropsStatus].every(status => status === AsyncStatus.Success), [defaultPropsStatus, languageSpecificPropsStatus]);
355
+ const slotStyles = useMemo(() => ({
356
+ gridArea: slotName
357
+ }), [slotName]);
358
+ useEffect(() => {
359
+ let props = {};
360
+ if (!!defaultPropsQuery.length && !!defaultPropsQuery[0].data.props) {
361
+ const parsedProps = JSON.parse(defaultPropsQuery[0].data.props);
362
+ props = {
363
+ ...props,
364
+ ...parsedProps
365
+ };
366
+ }
367
+ if (!!languageSpecificPropsQuery.length && !!languageSpecificPropsQuery[0].data.props) {
368
+ const parsedProps = JSON.parse(languageSpecificPropsQuery[0].data.props);
369
+ props = {
370
+ ...props,
371
+ ...parsedProps
372
+ };
373
+ }
374
+ if (!!pageSpecificProps) {
375
+ const parsedProps = JSON.parse(pageSpecificProps);
376
+ props = {
377
+ ...props,
378
+ ...parsedProps
379
+ };
380
+ }
381
+ setComponentProps(props);
382
+ }, [pageSpecificProps, defaultPropsQuery, languageSpecificPropsQuery]);
383
+ return /*#__PURE__*/React.createElement("div", {
384
+ style: slotStyles
385
+ }, loaded && /*#__PURE__*/React.createElement(Component, componentProps));
386
+ };
387
+
388
+ const Page = () => {
389
+ const activePageLocation = useActivePageLocation();
390
+ const {
391
+ resources: folder
392
+ } = useResources(`/pages${activePageLocation}`);
393
+ const pageSettings = folder.find(entry => entry.name === 'Page settings');
394
+ const sections = folder.filter(entry => entry.name.endsWith('Section'));
395
+ pageSettings?.data?.title;
396
+ pageSettings?.data?.layout;
397
+ if (!pageSettings) return;
398
+ setSections(sections);
399
+ return !!pageSettings && /*#__PURE__*/React.createElement(Layout, {
400
+ layoutId: pageSettings.layout
401
+ }, sections.map(section => /*#__PURE__*/React.createElement(Section, {
402
+ key: section.data.slotName,
403
+ slotName: section.data.slotName,
404
+ componentId: section.data.componentId,
405
+ componentProps: section.data.componentProps
406
+ })));
407
+ };
408
+
409
+ const getLoadingPageSettings = () => ({
410
+ title: 'Loading...'
411
+ });
412
+ const getErrorPageSettings = () => ({
413
+ title: 'Error'
414
+ });
415
+ const getNotFoundPageSettings = () => ({
416
+ title: 'Not found'
417
+ });
418
+ const getDefaultPageSettings = () => ({
419
+ title: undefined
420
+ });
421
+ const PageStatus = {
422
+ Loading: 'Loading',
423
+ Error: 'Error',
424
+ Success: 'Success',
425
+ NotFound: 'NotFound'
426
+ };
427
+ const PageDataLoader = ({
428
+ children
429
+ }) => {
430
+ const activePageLocation = useActivePageLocation();
431
+ const {
432
+ status,
433
+ resources: folder
434
+ } = useResources(`/pages${activePageLocation}`);
435
+ const [pageStatus, setPageStatus] = useState(PageStatus.Loading);
436
+ const [pageSettings, setPageSettings] = useState(getLoadingPageSettings());
437
+ useDocumentTitle(pageSettings.title);
438
+ useEffect(() => {
439
+ if ([AsyncStatus.NotInitialized, AsyncStatus.Loading].includes(status)) {
440
+ setPageSettings(getLoadingPageSettings());
441
+ return setPageStatus(PageStatus.Loading);
442
+ } else if ([AsyncStatus.Error].includes(status)) {
443
+ setPageSettings(getErrorPageSettings());
444
+ return setPageStatus(PageStatus.Error);
445
+ } else if ([AsyncStatus.Success].includes(status)) {
446
+ const pageSettings = folder.find(entry => entry.name === 'Page settings');
447
+ if (!pageSettings) {
448
+ setPageSettings(getNotFoundPageSettings());
449
+ return setPageStatus(PageStatus.NotFound);
450
+ }
451
+ setPageSettings({
452
+ title: pageSettings.data.title,
453
+ layout: pageSettings.data.layout,
454
+ slots: pageSettings.data.slots
455
+ });
456
+ setPageStatus(PageStatus.Success);
457
+ }
458
+ return () => {
459
+ setPageSettings(getDefaultPageSettings());
460
+ };
461
+ }, [status, folder]);
462
+ return /*#__PURE__*/React.createElement(Switch, {
463
+ on: pageStatus
464
+ }, /*#__PURE__*/React.createElement(Switch.Case, {
465
+ match: [PageStatus.NotFound]
466
+ }, "Page not found"), /*#__PURE__*/React.createElement(Switch.Case, {
467
+ match: [PageStatus.Error]
468
+ }, "Couldn't load the page"), /*#__PURE__*/React.createElement(Switch.Case, {
469
+ match: [PageStatus.Loading]
470
+ }, "Page Loading"), /*#__PURE__*/React.createElement(Switch.Case, {
471
+ match: [PageStatus.Success]
472
+ }, children));
473
+ };
474
+
475
+ const PagesModule = () => /*#__PURE__*/React.createElement(PageDataLoader, null, /*#__PURE__*/React.createElement(Page, null));
476
+
477
+ const translations = {
478
+ en: {
479
+ tags: 'Experience with',
480
+ work: 'Work',
481
+ projects: 'Projects',
482
+ education: 'Education',
483
+ other: 'Other',
484
+ download: 'Download',
485
+ all: 'All'
486
+ }
487
+ };
488
+ const getProfile = resources => {
489
+ const image = resources?.find(x => x.type.startsWith('image/'));
490
+ const {
491
+ id,
492
+ content
493
+ } = resources?.find(x => x.type === 'resume-summary') || {
494
+ content: {}
495
+ };
496
+ const profile = {
497
+ id: id,
498
+ name: content.Name || content['Consultant Name'],
499
+ role: content.Role,
500
+ image: image?.content?.src,
501
+ summary: content.Summary,
502
+ tags: content?.Tags?.split(','),
503
+ links: []
504
+ };
505
+ content.Mobile && profile.links.push({
506
+ icon: 'phone',
507
+ label: content.Mobile,
508
+ href: `tel:${content.Mobile}`,
509
+ target: '_blank'
510
+ });
511
+ content.Email && profile.links.push({
512
+ icon: 'mail',
513
+ label: content.Email,
514
+ href: `mailto:${content.Email}`
515
+ });
516
+ content.Website && profile.links.push({
517
+ icon: 'globe-alt',
518
+ label: content.Website.replace('https://', '').replace('http://', ''),
519
+ href: content.Website,
520
+ target: '_blank'
521
+ });
522
+ return profile;
523
+ };
524
+ const getExperiences = resources => resources.filter(x => x.type === 'resume-experience').map(resource => ({
525
+ id: resource.id,
526
+ title: resource.content.Title,
527
+ subTitle: resource.content['Sub Title'],
528
+ date: resource.content.Date,
529
+ description: resource.content.Description,
530
+ website: resource.content.Website,
531
+ github: resource.content.GitHub,
532
+ tags: resource.content?.Tags?.split(',')?.map(x => x.trim()).filter(x => !!x),
533
+ typeOfExperience: resource.content['Type of experience']
534
+ }));
535
+ const useMergeAsyncStatus = (...statuses) => {
536
+ return statuses.reduce((acc, status) => {
537
+ if (acc === 'Loading' || status === 'Loading' || status === 'NotInitialized') {
538
+ return 'Loading';
539
+ }
540
+ if (acc === 'Error' || status === 'Error') {
541
+ return 'Error';
542
+ }
543
+ if (acc === 'AuthenticationError' || status === 'AuthenticationError') {
544
+ return 'AuthenticationError';
545
+ }
546
+ return 'Success';
547
+ }, 'NotInitialized');
548
+ };
549
+ const location = '/@ossy/resumes/';
550
+ const useResume = resumeId => {
551
+ const resumeDirectory = useResource(resumeId);
552
+ const resumeResources = useResources(resumeDirectory?.resource?.name ? location + resumeDirectory?.resource?.name + '/' : undefined);
553
+ const status = useMergeAsyncStatus(resumeDirectory.status, resumeResources.status);
554
+ return {
555
+ status,
556
+ translations: translations.en,
557
+ profile: getProfile(resumeResources.resources),
558
+ experiences: getExperiences(resumeResources.resources)
559
+ };
560
+ };
561
+
562
+ const Resume = ({
563
+ resumeId,
564
+ ...props
565
+ }) => {
566
+ const resumeProps = useResume(resumeId);
567
+ return resumeProps.status === 'Success' ? /*#__PURE__*/React$1.createElement(Resume$1, _extends({}, resumeProps, {
568
+ profileCardVariant: "resume"
569
+ }, props)) : /*#__PURE__*/React$1.createElement(React$1.Fragment, null);
570
+ };
571
+
572
+ const ResumeTemplates = [{
573
+ name: 'Resume Experience',
574
+ id: 'resume-experience',
575
+ fields: [{
576
+ name: 'Title',
577
+ type: 'text'
578
+ }, {
579
+ name: 'Sub Title',
580
+ type: 'text'
581
+ }, {
582
+ name: 'Date',
583
+ type: 'text'
584
+ }, {
585
+ name: 'Description',
586
+ type: 'textarea'
587
+ }, {
588
+ name: 'Type of experience',
589
+ type: 'select',
590
+ options: ['Work', 'Education', 'Other', 'Project']
591
+ }, {
592
+ name: 'Website',
593
+ type: 'text'
594
+ }, {
595
+ name: 'Tags',
596
+ type: 'text'
597
+ }, {
598
+ name: 'GitHub',
599
+ type: 'text'
600
+ }]
601
+ }, {
602
+ name: 'Resume Summary',
603
+ id: 'resume-summary',
604
+ fields: [{
605
+ name: 'Name',
606
+ type: 'text'
607
+ }, {
608
+ name: 'Role',
609
+ type: 'text'
610
+ }, {
611
+ name: 'Summary',
612
+ type: 'textarea'
613
+ }, {
614
+ name: 'Mobile',
615
+ type: 'text'
616
+ }, {
617
+ name: 'Email',
618
+ type: 'text'
619
+ }, {
620
+ name: 'Website',
621
+ type: 'text'
622
+ }, {
623
+ name: 'Tags',
624
+ type: 'textarea'
625
+ }]
626
+ }];
627
+
628
+ const ThemeProvider = props => {
629
+ const {
630
+ status,
631
+ resource: theme
632
+ } = useResource('PCX53TaGviq4_8KvK-VOp');
633
+ return status === AsyncStatus.Success ? /*#__PURE__*/React.createElement(Theme, _extends({
634
+ theme: theme.data
635
+ }, props)) : /*#__PURE__*/React.createElement(React.Fragment, null);
636
+ };
637
+
638
+ export { App, AppContext, Layout, Ossybot, Page, PageDataLoader, PagesModule, Resume, ResumeTemplates, ThemeEditor, ThemeProvider, defaultAppSettings, location, useActivePageLocation, useAppSettings, useMergeAsyncStatus, useResume };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ossy/connected-components",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/ossy-se/packages.git"
@@ -38,7 +38,7 @@
38
38
  "prop-types": "^15.8.1"
39
39
  },
40
40
  "dependencies": {
41
- "@ossy/themes": "^0.1.4",
41
+ "@ossy/themes": "^0.1.6",
42
42
  "moment": "^2.29.4"
43
43
  },
44
44
  "peerDependencies": {
@@ -54,5 +54,9 @@
54
54
  "access": "public",
55
55
  "registry": "https://registry.npmjs.org"
56
56
  },
57
- "gitHead": "d5cd2ad89b32cdc9cd31a27ff53b71a9c3226799"
57
+ "files": [
58
+ "/build",
59
+ "README.md"
60
+ ],
61
+ "gitHead": "b13ae79ee733d5934fc4fefa3b50e30a7b566ac9"
58
62
  }
@@ -1,19 +0,0 @@
1
-
2
-
3
- /** @type { import('@storybook/react-vite').StorybookConfig } */
4
- const config = {
5
- "stories": [
6
- "../src/**/*.mdx",
7
- "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"
8
- ],
9
- "addons": [
10
- "@storybook/addon-essentials",
11
- "@storybook/addon-onboarding",
12
- "@storybook/addon-interactions"
13
- ],
14
- "framework": {
15
- "name": "@storybook/react-vite",
16
- "options": {}
17
- }
18
- };
19
- export default config;
@@ -1,13 +0,0 @@
1
- /** @type { import('@storybook/react').Preview } */
2
- const preview = {
3
- parameters: {
4
- controls: {
5
- matchers: {
6
- color: /(background|color)$/i,
7
- date: /Date$/i,
8
- },
9
- },
10
- },
11
- };
12
-
13
- export default preview;