diff --git a/solidjs-tailwind/README.md b/solidjs-tailwind/README.md
index 145cefafe..7e93aeda0 100644
--- a/solidjs-tailwind/README.md
+++ b/solidjs-tailwind/README.md
@@ -56,6 +56,10 @@ Signals can live outside of components. Each relevant component subscribes to it
Demonstrates how to retrieve data from a third-party API by using `createResource`.
+#### Other Resources
+
+- [Solidjs Icons](https://www.npmjs.com/package/solid-icons)
+
## Installation
### CLI (Recommended)
diff --git a/solidjs-tailwind/package.json b/solidjs-tailwind/package.json
index f7c3bf633..48fd5ec1c 100644
--- a/solidjs-tailwind/package.json
+++ b/solidjs-tailwind/package.json
@@ -32,12 +32,14 @@
"@testing-library/jest-dom": "5.16.5",
"@typescript-eslint/parser": "5.41.0",
"autoprefixer": "10.4.12",
+ "dayjs": "^1.11.6",
"eslint": "8.26.0",
"eslint-plugin-solid": "0.7.4",
"eslint-plugin-unused-imports": "2.0.0",
"jsdom": "20.0.1",
"postcss": "8.4.18",
"prettier": "2.7.1",
+ "solid-icons": "^1.0.2",
"solid-testing-library": "0.3.0",
"storybook-addon-mock": "3.2.0",
"tailwindcss": "3.2.1",
diff --git a/solidjs-tailwind/pnpm-lock.yaml b/solidjs-tailwind/pnpm-lock.yaml
index efb730d6a..a680ae44c 100644
--- a/solidjs-tailwind/pnpm-lock.yaml
+++ b/solidjs-tailwind/pnpm-lock.yaml
@@ -17,12 +17,14 @@ specifiers:
'@testing-library/jest-dom': 5.16.5
'@typescript-eslint/parser': 5.41.0
autoprefixer: 10.4.12
+ dayjs: ^1.11.6
eslint: 8.26.0
eslint-plugin-solid: 0.7.4
eslint-plugin-unused-imports: 2.0.0
jsdom: 20.0.1
postcss: 8.4.18
prettier: 2.7.1
+ solid-icons: ^1.0.2
solid-js: 1.6.0
solid-testing-library: 0.3.0
storybook-addon-mock: 3.2.0
@@ -52,12 +54,14 @@ devDependencies:
'@testing-library/jest-dom': 5.16.5
'@typescript-eslint/parser': 5.41.0_wyqvi574yv7oiwfeinomdzmc3m
autoprefixer: 10.4.12_postcss@8.4.18
+ dayjs: 1.11.6
eslint: 8.26.0
eslint-plugin-solid: 0.7.4_wyqvi574yv7oiwfeinomdzmc3m
eslint-plugin-unused-imports: 2.0.0_eslint@8.26.0
jsdom: 20.0.1
postcss: 8.4.18
prettier: 2.7.1
+ solid-icons: 1.0.2_solid-js@1.6.0
solid-testing-library: 0.3.0_solid-js@1.6.0
storybook-addon-mock: 3.2.0
tailwindcss: 3.2.1_postcss@8.4.18
@@ -6998,6 +7002,10 @@ packages:
whatwg-url: 11.0.0
dev: true
+ /dayjs/1.11.6:
+ resolution: {integrity: sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ==}
+ dev: true
+
/debug/2.6.9:
resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
peerDependencies:
@@ -12329,6 +12337,15 @@ packages:
- supports-color
dev: true
+ /solid-icons/1.0.2_solid-js@1.6.0:
+ resolution: {integrity: sha512-Pockp4vkCFFW+uubuRpb50pqKZNzjLhUUDm5VPpcZJWSgDw7fOxnMLcO1fC2bK8l+kYbJOr52y+pB5fnoZXg3Q==}
+ engines: {node: '>= 16'}
+ peerDependencies:
+ solid-js: '*'
+ dependencies:
+ solid-js: 1.6.0
+ dev: true
+
/solid-js/1.6.0:
resolution: {integrity: sha512-db5s65ErgZnBhapPx77qauzul8akHlMCvirS+Y86U4abMa3uizMVNW9ql3UxbO0yMzMGNpFJwUiOlXmJCbwVpA==}
dependencies:
diff --git a/solidjs-tailwind/src/components/PrivacyBadge/PrivacyBadge.jsx b/solidjs-tailwind/src/components/PrivacyBadge/PrivacyBadge.jsx
new file mode 100644
index 000000000..0e101b706
--- /dev/null
+++ b/solidjs-tailwind/src/components/PrivacyBadge/PrivacyBadge.jsx
@@ -0,0 +1,12 @@
+import { splitProps } from 'solid-js';
+
+const PrivacyBadge = (props) => {
+ const [local] = splitProps(props, ['visibility']);
+ return (
+
+ {local.visibility}
+
+ );
+};
+
+export default PrivacyBadge;
diff --git a/solidjs-tailwind/src/components/PrivacyBadge/PrivacyBadge.stories.jsx b/solidjs-tailwind/src/components/PrivacyBadge/PrivacyBadge.stories.jsx
new file mode 100644
index 000000000..d689f1d65
--- /dev/null
+++ b/solidjs-tailwind/src/components/PrivacyBadge/PrivacyBadge.stories.jsx
@@ -0,0 +1,15 @@
+import PrivacyBadge from './PrivacyBadge';
+
+export default {
+ title: 'Components/PrivacyBadge',
+ argTypes: {
+ visibility: {},
+ },
+};
+
+const Template = (args) => ;
+
+export const Default = Template.bind({});
+Default.args = {
+ visibility: 'Public',
+};
diff --git a/solidjs-tailwind/src/components/PrivacyBadge/index.js b/solidjs-tailwind/src/components/PrivacyBadge/index.js
new file mode 100644
index 000000000..b351cd746
--- /dev/null
+++ b/solidjs-tailwind/src/components/PrivacyBadge/index.js
@@ -0,0 +1 @@
+export { default as PrivacyBadge } from './PrivacyBadge';
diff --git a/solidjs-tailwind/src/components/RepoCard/RepoCard.jsx b/solidjs-tailwind/src/components/RepoCard/RepoCard.jsx
new file mode 100644
index 000000000..001d7d053
--- /dev/null
+++ b/solidjs-tailwind/src/components/RepoCard/RepoCard.jsx
@@ -0,0 +1,60 @@
+import { Link } from '@solidjs/router';
+import { Show, splitProps } from 'solid-js';
+import RepoMeta from '../RepoMeta/RepoMeta';
+import { OcStar2 } from 'solid-icons/oc';
+import PrivacyBadge from '../PrivacyBadge/PrivacyBadge';
+
+const RepoCard = (props) => {
+ const [local] = splitProps(props, [
+ 'name',
+ 'description',
+ 'primaryLanguage',
+ 'stargazerCount',
+ 'owner',
+ 'isProfilePage',
+ 'updatedAt',
+ 'visibility',
+ ]);
+ const repoNameWithOwnerLink = () =>
+ `${local.owner?.login || ''}/${local.name || ''}`;
+ const repoNameWithOwner = () =>
+ `${!local.isProfilePage ? `${local.owner?.login || ''}/` : ''}${
+ local.name || ''
+ }`;
+
+ return (
+
+
+
+
+
+ {repoNameWithOwner()}
+
+
+
+
+
+
+ {local.description}
+
+
+
+
+
+
+
+
+ );
+};
+
+
+export default RepoCard;
diff --git a/solidjs-tailwind/src/components/RepoCard/RepoCard.spec.jsx b/solidjs-tailwind/src/components/RepoCard/RepoCard.spec.jsx
new file mode 100644
index 000000000..73c862d58
--- /dev/null
+++ b/solidjs-tailwind/src/components/RepoCard/RepoCard.spec.jsx
@@ -0,0 +1,51 @@
+import { Router } from '@solidjs/router';
+import { render } from 'solid-testing-library';
+import { beforeEach, describe, expect, it } from 'vitest';
+import RepoCard from './RepoCard';
+import { repoCardProps } from './data';
+
+describe('RepoCard for profilepage', () => {
+ let wrapper;
+ beforeEach(async () => {
+ wrapper = await render(() => (
+
+
+
+ ));
+ });
+
+ it('should mount', () => {
+ expect(wrapper).toBeTruthy();
+ });
+
+ it('a tag text should contain only name', async () => {
+ const repoName = await wrapper.getByText(repoCardProps.name);
+ expect(repoName).toBeVisible();
+ });
+});
+describe('RepoCard for non profile page', () => {
+ let wrapper;
+ const notProfileData = {
+ ...repoCardProps,
+ isProfilePage: false,
+ };
+
+ beforeEach(async () => {
+ wrapper = await render(() => (
+
+
+
+ ));
+ });
+
+ it('should mount', () => {
+ expect(wrapper).toBeTruthy();
+ });
+
+ it('a tag text should contain owner/name', async () => {
+ const repowithOwner = await wrapper.getByText(
+ `${notProfileData.owner.login}/${notProfileData.name}`
+ );
+ expect(repowithOwner).toBeVisible();
+ });
+});
diff --git a/solidjs-tailwind/src/components/RepoCard/RepoCard.stories.jsx b/solidjs-tailwind/src/components/RepoCard/RepoCard.stories.jsx
new file mode 100644
index 000000000..d621d0f98
--- /dev/null
+++ b/solidjs-tailwind/src/components/RepoCard/RepoCard.stories.jsx
@@ -0,0 +1,28 @@
+import { Router } from '@solidjs/router';
+import RepoCard from './RepoCard';
+import { repoCardProps } from './data';
+
+export default {
+ title: 'Components/Repo Card',
+ component: RepoCard,
+ argTypes: {
+ name: {},
+ description: {},
+ primaryLanguage: {},
+ owner: {},
+ isProfilePage: {},
+ stargazerCount: {},
+ },
+};
+
+const Template = (args) => (
+
+
+
+);
+
+export const Default = Template.bind({});
+
+Default.args = {
+ ...repoCardProps,
+};
diff --git a/solidjs-tailwind/src/components/RepoCard/data.js b/solidjs-tailwind/src/components/RepoCard/data.js
new file mode 100644
index 000000000..c85599066
--- /dev/null
+++ b/solidjs-tailwind/src/components/RepoCard/data.js
@@ -0,0 +1,16 @@
+export const repoCardProps = {
+ name: 'cowrywise-unsplashed',
+ owner: {
+ login: 'hdjerry',
+ },
+ isProfilePage: true,
+ stargazerCount: 2,
+ visibility: 'Private',
+ primaryLanguage: {
+ color: 'yellow',
+ name: 'Javascript',
+ },
+ description:
+ 'Using basic pull requests to add your name and github link to BE A MEMBER of ZTM-ng',
+ updatedAt: '23 Sep 2020',
+};
diff --git a/solidjs-tailwind/src/components/RepoCard/index.js b/solidjs-tailwind/src/components/RepoCard/index.js
new file mode 100644
index 000000000..dda4f06a3
--- /dev/null
+++ b/solidjs-tailwind/src/components/RepoCard/index.js
@@ -0,0 +1 @@
+export { default as RepoCard } from './RepoCard';
diff --git a/solidjs-tailwind/src/components/RepoMeta/RepoMeta.jsx b/solidjs-tailwind/src/components/RepoMeta/RepoMeta.jsx
new file mode 100644
index 000000000..d46cea575
--- /dev/null
+++ b/solidjs-tailwind/src/components/RepoMeta/RepoMeta.jsx
@@ -0,0 +1,40 @@
+import { Show, splitProps } from 'solid-js';
+import { OcStar2 } from 'solid-icons/oc';
+import getFriendlyDate from '../../helper/getFriendlyDate';
+
+const RepoMeta = (props) => {
+ const [local] = splitProps(props, [
+ 'primaryLanguage',
+ 'stargazerCount',
+ 'updatedAt',
+ ]);
+
+ const friendlyUpdatedAt = () => getFriendlyDate(local.updatedAt);
+
+ return (
+
+
+
+
+ {local.primaryLanguage.name}
+
+
+
+
+
+
+
+ {local.stargazerCount}
+
+
+
Updated {friendlyUpdatedAt()}
+
+ );
+};
+
+export default RepoMeta;
diff --git a/solidjs-tailwind/src/components/RepoMeta/index.js b/solidjs-tailwind/src/components/RepoMeta/index.js
new file mode 100644
index 000000000..12b089b8a
--- /dev/null
+++ b/solidjs-tailwind/src/components/RepoMeta/index.js
@@ -0,0 +1 @@
+export { default as RepoMeta } from './RepoMeta';
diff --git a/solidjs-tailwind/src/components/index.js b/solidjs-tailwind/src/components/index.js
index 7a9d23386..567fe096c 100644
--- a/solidjs-tailwind/src/components/index.js
+++ b/solidjs-tailwind/src/components/index.js
@@ -1,5 +1,8 @@
export * from './CounterExample';
export * from './FetchExample';
+export * from './RepoMeta';
+export * from './RepoCard';
+export * from './PrivacyBadge';
export * from './Header';
export * from './UserDropdown';
export { default as PageHeader } from './PageHeader';
diff --git a/solidjs-tailwind/src/helper/getFriendlyDate.js b/solidjs-tailwind/src/helper/getFriendlyDate.js
new file mode 100644
index 000000000..51a0a8936
--- /dev/null
+++ b/solidjs-tailwind/src/helper/getFriendlyDate.js
@@ -0,0 +1,12 @@
+import dayjs from 'dayjs';
+import relativeTime from 'dayjs/plugin/relativeTime';
+
+const getFriendlyDate = (dateStr) => {
+ dayjs.extend(relativeTime);
+
+ const formatted = dayjs(dateStr).fromNow();
+
+ return formatted;
+};
+
+export default getFriendlyDate;