+
+ {title}
+
+
{`${project} / ${repository}`}
{language}
diff --git a/components/contributions-table/table.tsx b/components/contributions-table/table.tsx
index bf19642..973253b 100644
--- a/components/contributions-table/table.tsx
+++ b/components/contributions-table/table.tsx
@@ -1,5 +1,6 @@
"use client";
import React from "react";
+import { useMediaQuery } from "react-responsive";
import {
Table as NuiTable,
TableHeader,
@@ -14,6 +15,7 @@ import { Contribution, PaginatedContributions } from "@/types/contribution";
import { ExternalLink, Content, Labels, Time, Project } from "./row";
import { useContributions } from "@/hooks/useContributions";
import { KudosQueryParameters } from "@/lib/notion/types";
+import { isNotNull } from "@/utils/type-guard";
interface ITableProps {
items: PaginatedContributions;
@@ -34,6 +36,16 @@ export const Table = ({ items, queries = {} }: ITableProps) => {
return results?.pages.flatMap((page) => page.data) || [];
}, [results]);
+ const isMobile = useMediaQuery({ maxWidth: 639 }); // tailwind lg default: 640px
+ const isLaptop = useMediaQuery({ minWidth: 1024 }); // tailwind lg default: 1024px
+ const COLUMNS = [
+ { name: "PROJECT", uid: "project" },
+ { name: "CONTENT", uid: "content" },
+ isLaptop ? { name: "LABELS", uid: "labels" } : null,
+ { name: "DATE", uid: "date" },
+ isMobile ? null : { name: "ACTIONS", uid: "actions" },
+ ].filter(isNotNull);
+
const renderCell = React.useCallback(
(item: Contribution, columnKey: React.Key) => {
const cellValue = item[columnKey as keyof Contribution];
@@ -48,11 +60,25 @@ export const Table = ({ items, queries = {} }: ITableProps) => {
/>
);
case "content":
- return
;
+ return (
+
+ );
case "labels":
return
;
case "date":
- return
;
+ return (
+
+ );
case "actions":
return
;
default:
@@ -83,6 +109,7 @@ export const Table = ({ items, queries = {} }: ITableProps) => {
wrapper:
"bg-background overflow-visible p-0 rounded-none border-small border-y-0",
tr: "relative bg-gradient-to-r from-background to-background-200 to-80% border-y-small border-y-overlay before:content-[''] before:absolute before:bg-hover-overlay before:opacity-0 before:w-full before:h-full before:transition-opacity before:duration-300 before:ease-in-out hover:before:opacity-100",
+ td: "px-2 sm:px-inherit",
}}
>
@@ -113,11 +140,3 @@ export const Table = ({ items, queries = {} }: ITableProps) => {
};
export default Table;
-
-const COLUMNS = [
- { name: "PROJECT", uid: "project" },
- { name: "CONTENT", uid: "content" },
- { name: "LABELS", uid: "labels" },
- { name: "DATE", uid: "date" },
- { name: "ACTIONS", uid: "actions" },
-];
diff --git a/package.json b/package.json
index 3dddd72..969bfca 100644
--- a/package.json
+++ b/package.json
@@ -52,6 +52,7 @@
"react": "18.2.0",
"react-dom": "18.2.0",
"react-intersection-observer": "^9.5.3",
+ "react-responsive": "^9.0.2",
"tailwind-variants": "^0.1.19",
"tailwindcss": "3.4.0",
"typescript": "5.3.3"
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 4407998..2bebb78 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -131,6 +131,9 @@ dependencies:
react-intersection-observer:
specifier: ^9.5.3
version: 9.5.3(react@18.2.0)
+ react-responsive:
+ specifier: ^9.0.2
+ version: 9.0.2(react@18.2.0)
tailwind-variants:
specifier: ^0.1.19
version: 0.1.19(tailwindcss@3.4.0)
@@ -2720,6 +2723,10 @@ packages:
shebang-command: 2.0.0
which: 2.0.2
+ /css-mediaquery@0.1.2:
+ resolution: {integrity: sha512-COtn4EROW5dBGlE/4PiKnh6rZpAPxDeFLaEEwt4i10jpDMFt2EhQGS79QmmrO+iKCHv0PU/HrOWEhijFd1x99Q==}
+ dev: false
+
/cssesc@3.0.0:
resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
engines: {node: '>=4'}
@@ -3527,6 +3534,10 @@ packages:
function-bind: 1.1.2
dev: false
+ /hyphenate-style-name@1.0.4:
+ resolution: {integrity: sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==}
+ dev: false
+
/ignore@5.3.0:
resolution: {integrity: sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==}
engines: {node: '>= 4'}
@@ -3896,6 +3907,12 @@ packages:
dependencies:
yallist: 4.0.0
+ /matchmediaquery@0.3.1:
+ resolution: {integrity: sha512-Hlk20WQHRIm9EE9luN1kjRjYXAQToHOIAHPJn9buxBwuhfTHoKUcX+lXBbxc85DVQfXYbEQ4HcwQdd128E3qHQ==}
+ dependencies:
+ css-mediaquery: 0.1.2
+ dev: false
+
/merge2@1.4.1:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'}
@@ -4355,6 +4372,19 @@ packages:
use-sidecar: 1.1.2(@types/react@18.2.45)(react@18.2.0)
dev: false
+ /react-responsive@9.0.2(react@18.2.0):
+ resolution: {integrity: sha512-+4CCab7z8G8glgJoRjAwocsgsv6VA2w7JPxFWHRc7kvz8mec1/K5LutNC2MG28Mn8mu6+bu04XZxHv5gyfT7xQ==}
+ engines: {node: '>=0.10'}
+ peerDependencies:
+ react: '>=16.8.0'
+ dependencies:
+ hyphenate-style-name: 1.0.4
+ matchmediaquery: 0.3.1
+ prop-types: 15.8.1
+ react: 18.2.0
+ shallow-equal: 1.2.1
+ dev: false
+
/react-style-singleton@2.2.1(@types/react@18.2.45)(react@18.2.0):
resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==}
engines: {node: '>=10'}
@@ -4527,6 +4557,10 @@ packages:
has-property-descriptors: 1.0.1
dev: false
+ /shallow-equal@1.2.1:
+ resolution: {integrity: sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==}
+ dev: false
+
/shebang-command@2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'}
diff --git a/utils/type-guard.ts b/utils/type-guard.ts
new file mode 100644
index 0000000..4294e83
--- /dev/null
+++ b/utils/type-guard.ts
@@ -0,0 +1,3 @@
+export function isNotNull(value: T | null): value is T {
+ return value !== null;
+}