diff --git a/package-lock.json b/package-lock.json
index 2fe1a7e..272029e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,7 +20,7 @@
"sublinks-js-client": "^0.0.3"
},
"devDependencies": {
- "@stylistic/eslint-plugin-js": "^1.5.1",
+ "@stylistic/eslint-plugin-js": "^1.5.3",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
@@ -569,12 +569,12 @@
"dev": true
},
"node_modules/@stylistic/eslint-plugin-js": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-1.5.1.tgz",
- "integrity": "sha512-iZF0rF+uOhAmOJYOJx1Yvmm3CZ1uz9n0SRd9dpBYHA3QAvfABUORh9LADWwZCigjHJkp2QbCZelGFJGwGz7Siw==",
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-1.5.3.tgz",
+ "integrity": "sha512-XlKnm82fD7Sw9kQ6FFigE0tobvptNBXZWsdfoKmUyK7bNxHsAHOFT8zJGY3j3MjZ0Fe7rLTu86hX/vOl0bRRdQ==",
"dev": true,
"dependencies": {
- "acorn": "^8.11.2",
+ "acorn": "^8.11.3",
"escape-string-regexp": "^4.0.0",
"eslint-visitor-keys": "^3.4.3",
"espree": "^9.6.1"
@@ -1199,9 +1199,9 @@
"integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ=="
},
"node_modules/acorn": {
- "version": "8.11.2",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz",
- "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==",
+ "version": "8.11.3",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
+ "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
"dev": true,
"bin": {
"acorn": "bin/acorn"
@@ -5508,9 +5508,9 @@
}
},
"node_modules/postcss": {
- "version": "8.4.32",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz",
- "integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==",
+ "version": "8.4.33",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz",
+ "integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==",
"dev": true,
"funding": [
{
diff --git a/package.json b/package.json
index b89acc7..f47b451 100644
--- a/package.json
+++ b/package.json
@@ -27,7 +27,7 @@
"sublinks-js-client": "^0.0.3"
},
"devDependencies": {
- "@stylistic/eslint-plugin-js": "^1.5.1",
+ "@stylistic/eslint-plugin-js": "^1.5.3",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
diff --git a/src/app/page.tsx b/src/app/page.tsx
index 5b9c156..219b5e6 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -1,24 +1,21 @@
import React from 'react';
-import PostFeed from '@/components/post-feed';
import sublinksClient from '@/utils/client';
-import { PostView } from 'sublinks-js-client';
+import { GetPostsResponse } from 'sublinks-js-client';
+import Feed from '@/components/front-page-feed';
import * as testData from '../../test-data.json';
-const Feed = async () => {
+const page = async () => {
// @todo: Allow test data when in non-docker dev env
// as Sublinks Core doesn't yet handle all post features
- const postsRes = process.env.SUBLINKS_API_BASE_URL ? await sublinksClient().getPosts({
- type_: 'All',
- sort: 'Active'
- }) : testData as unknown as { posts: PostView[] };
-
+ const posts = process.env.SUBLINKS_API_BASE_URL ? await sublinksClient().getPosts()
+ : JSON.stringify(testData) as unknown as GetPostsResponse;
return (
);
};
-export default Feed;
+export default page;
diff --git a/src/components/TailwindMaterial.ts b/src/components/TailwindMaterial.ts
index 55fd636..0e686b8 100644
--- a/src/components/TailwindMaterial.ts
+++ b/src/components/TailwindMaterial.ts
@@ -8,11 +8,17 @@ import {
TabsBody,
Tab,
TabPanel,
- Switch
+ Switch,
+ ButtonGroup,
+ Select,
+ Option
} from '@material-tailwind/react';
export {
ThemeProvider,
+ ButtonGroup,
+ Select,
+ Option,
Button,
Tabs,
TabsHeader,
diff --git a/src/components/button/index.tsx b/src/components/button/index.tsx
index 0a2250e..61da04d 100644
--- a/src/components/button/index.tsx
+++ b/src/components/button/index.tsx
@@ -6,16 +6,28 @@ interface ButtonProps {
type: 'button' | 'submit' | 'reset';
id?: string;
ariaLabel?: string;
+ active?: boolean;
className?: string;
onClick?: (e: React.MouseEvent) => void;
}
const Button = ({
- ariaLabel, children, className, id, type, onClick
+ ariaLabel, children, className, id, type, active, onClick
}: ButtonProps) => (
// Rule doesn't like type being a variable even though types force it to be a valid option
- // eslint-disable-next-line react/button-has-type
-
+
);
export default Button;
diff --git a/src/components/front-page-feed/index.tsx b/src/components/front-page-feed/index.tsx
new file mode 100644
index 0000000..c2c98d0
--- /dev/null
+++ b/src/components/front-page-feed/index.tsx
@@ -0,0 +1,52 @@
+'use client';
+
+import React, { useEffect, useState } from 'react';
+
+import PostFeed from '@/components/post-feed';
+import sublinksClient from '@/utils/client';
+
+import {
+ GetPostsResponse, ListingType, SortType
+} from 'sublinks-js-client';
+import PostFeedOptions from '@/components/post-feed-sort';
+import * as testData from '../../../test-data.json';
+
+interface FeedProps {
+ posts: GetPostsResponse
+}
+
+const Feed = ({ posts }: FeedProps) => {
+ const [postFeed, setPostFeed] = useState(posts);
+
+ // @todo: Set this to the users default feed type
+ const [postFeedType, setPostFeedType] = useState();
+ const [postFeedSort, setPostFeedSort] = useState();
+
+ // @todo: Allow test data when in non-docker dev env
+ // as Sublinks Core doesn't yet handle all post features
+ useEffect(() => {
+ async function getPosts() {
+ setPostFeed(process.env.SUBLINKS_API_BASE_URL ? await sublinksClient().getPosts({
+ type_: postFeedType,
+ sort: postFeedSort
+ }) : testData as unknown as GetPostsResponse);
+ }
+ getPosts();
+ }, [postFeedSort, postFeedType]);
+
+ return (
+
+ );
+};
+
+export default Feed;
diff --git a/src/components/post-feed-sort/index.tsx b/src/components/post-feed-sort/index.tsx
new file mode 100644
index 0000000..79e021a
--- /dev/null
+++ b/src/components/post-feed-sort/index.tsx
@@ -0,0 +1,136 @@
+'use client';
+
+import { ListingType, SortType } from 'sublinks-js-client';
+import React from 'react';
+import { ButtonGroup } from '../TailwindMaterial';
+import Button from '../button';
+import Select, { Option } from '../select';
+
+interface PostFeedTypeProps {
+ currentType?: ListingType
+ onTypeChange: (type: ListingType) => void
+}
+
+const buttonGroupClass = 'px-12 py-4';
+
+const PostFeedType = ({ currentType, onTypeChange }: PostFeedTypeProps) => (
+
+
+
+
+
+
+);
+
+const sortOptions: { label: string, value: string }[] = [
+ {
+ label: 'Active',
+ value: 'Active'
+ },
+ {
+ label: 'Hot',
+ value: 'Hot'
+ },
+ {
+ label: 'New',
+ value: 'New'
+ },
+ {
+ label: 'Old',
+ value: 'Old'
+ },
+ {
+ label: 'Top Hour',
+ value: 'TopHour'
+ },
+ {
+ label: 'Top Six Hour',
+ value: 'TopSixHour'
+ },
+ {
+ label: 'Top Twelve Hour',
+ value: 'TopTwelveHour'
+ },
+ {
+ label: 'Top Day',
+ value: 'TopDay'
+ },
+ {
+ label: 'Top Week',
+ value: 'TopWeek'
+ },
+ {
+ label: 'Top Month',
+ value: 'TopMonth'
+ },
+ {
+ label: 'Top Three Months',
+ value: 'TopThreeMonths'
+ },
+ {
+ label: 'Top Six Months',
+ value: 'TopSixMonths'
+ },
+ {
+ label: 'Top Nine Months',
+ value: 'TopNineMonths'
+ },
+ {
+ label: 'Top Year',
+ value: 'TopYear'
+ },
+ {
+ label: 'Top All',
+ value: 'TopAll'
+ },
+ {
+ label: 'Most Comments',
+ value: 'MostComments'
+ },
+ {
+ label: 'New Comments',
+ value: 'NewComments'
+ },
+ {
+ label: 'Controversial',
+ value: 'Controversial'
+ },
+ {
+ label: 'Scaled',
+ value: 'Scaled'
+ }
+];
+
+interface PostFeedSortProps {
+ currentSort?: SortType
+ onSortChange: (type: SortType) => void
+}
+
+const PostFeedSort = ({ currentSort, onSortChange: onTypeChange }: PostFeedSortProps) => (
+
+);
+
+interface PostFeedOptionProps {
+ currentType?: ListingType
+ onTypeChange: (type: ListingType) => void
+ currentSort?: SortType
+ onSortChange: (type: SortType) => void
+}
+
+const PostFeedOptions = ({
+ currentType, onTypeChange, currentSort, onSortChange
+}: PostFeedOptionProps) => (
+
+);
+
+export default PostFeedOptions;
+export { PostFeedType, PostFeedSort };
diff --git a/src/components/select/index.tsx b/src/components/select/index.tsx
new file mode 100644
index 0000000..7502d65
--- /dev/null
+++ b/src/components/select/index.tsx
@@ -0,0 +1,33 @@
+'use client';
+
+import React from 'react';
+import cx from 'classnames';
+
+interface SortProps {
+ className?: string;
+ value?: string;
+ onChange?: (e: React.ChangeEvent) => void;
+ children: React.ReactNode;
+}
+
+const Select = ({
+ className, value, onChange, children
+}: SortProps) => (
+
+);
+
+interface OptionProps {
+ value?: string;
+ children: React.ReactNode;
+}
+
+const Option = ({ children, value }: OptionProps) => (
+
+);
+
+export default Select;
+export { Option };