diff --git a/app/page.tsx b/app/page.tsx index 63955de3..b1ee4404 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -5,6 +5,7 @@ import Intro from "@/components/intro"; import Projects from "@/components/projects"; import SectionDivider from "@/components/section-divider"; import Skills from "@/components/skills"; +import Selection from "@/components/selection"; export default function Home() { return ( @@ -16,6 +17,7 @@ export default function Home() { + ); } diff --git a/components/dropdown.tsx b/components/dropdown.tsx new file mode 100644 index 00000000..f745f400 --- /dev/null +++ b/components/dropdown.tsx @@ -0,0 +1,41 @@ +"use client"; + +import { useState } from 'react'; + +interface DropdownProps { + items: { name: string, message: string, created_at: string | number }[]; + onSelect: (item: any) => void; +} + +function Dropdown({ items, onSelect }: DropdownProps) { + const [isOpen, setIsOpen] = useState(false); + const maxHeight = Math.min(items.length, 5)*3; + + return ( +
+ +
+ {isOpen && ( +
    + {items.map((item, idx) => { + const date = String(new Date(item.created_at)).split('(')[0]; + const parse = `${item.name} "${item.message}" ${date}`; + return ( +
  • { onSelect(parse); setIsOpen(false) }} className="bg-white borderBlack rounded-xl px-5 py-3 dark:bg-white/10 dark:text-white/80 cursor-pointer"> + {parse} +
  • + ) + })} +
+ )} +
+ ); +} + +export default Dropdown; diff --git a/components/header.tsx b/components/header.tsx index a1e53f21..f210b310 100644 --- a/components/header.tsx +++ b/components/header.tsx @@ -14,7 +14,7 @@ export default function Header() { return (
diff --git a/components/selection.tsx b/components/selection.tsx new file mode 100644 index 00000000..29355ea2 --- /dev/null +++ b/components/selection.tsx @@ -0,0 +1,56 @@ +"use client"; + +import { useState } from 'react'; +import useSWR from 'swr'; +import Dropdown from './dropdown'; +import { motion } from "framer-motion"; +import { useSectionInView } from "@/lib/hooks"; +import SectionHeading from './section-heading'; + + +interface Item { + name: string; + message: string; + created_at: string | number; +} + +interface Response { + rows: Item[]; +} + +const fetcher = (url: string) => fetch(url).then((res) => res.json()); + +const Selection = () => { + const { data } = useSWR('https://generic-web-app-be.azurewebsites.net/api/generic_data/messages/?collection_name=monolith&skip=0&limit=32', fetcher); + + const items: Item[] = data?.rows || []; + const [selectedItem, setSelectedItem] = useState(null); + const { ref } = useSectionInView("Selection"); + + return ( + + Dropdown Selection + {selectedItem &&
Selected: {selectedItem}
} +
+ +
+ ); +} + +export default Selection; diff --git a/lib/data.ts b/lib/data.ts index 2558095d..5af0eaf1 100644 --- a/lib/data.ts +++ b/lib/data.ts @@ -31,6 +31,10 @@ export const links = [ name: "Contact", hash: "#contact", }, + { + name: "Selection", + hash: "#selection", + }, ] as const; export const experiencesData = [ diff --git a/package-lock.json b/package-lock.json index 82f90853..eb3fe160 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,8 +10,6 @@ "dependencies": { "@react-email/components": "^0.0.7", "@react-email/tailwind": "^0.0.8", - "@types/node": "20.3.2", - "@types/react": "18.2.14", "@types/react-dom": "18.2.6", "autoprefixer": "10.4.14", "clsx": "^1.2.1", @@ -27,11 +25,14 @@ "react-intersection-observer": "^9.5.2", "react-vertical-timeline-component": "^3.6.0", "resend": "^0.16.0", - "tailwindcss": "3.3.2", - "typescript": "5.1.5" + "swr": "^2.2.4", + "tailwindcss": "3.3.2" }, "devDependencies": { - "@types/react-vertical-timeline-component": "^3.3.3" + "@types/node": "20.8.6", + "@types/react": "18.2.28", + "@types/react-vertical-timeline-component": "^3.3.3", + "typescript": "5.2.2" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -672,9 +673,13 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, "node_modules/@types/node": { - "version": "20.3.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.2.tgz", - "integrity": "sha512-vOBLVQeCQfIcF/2Y7eKFTqrMnizK5lRNQ7ykML/5RuwVXVWxYkgwS7xbt4B6fKCUPgbSL5FSsjHQpaGQP/dQmw==" + "version": "20.8.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.6.tgz", + "integrity": "sha512-eWO4K2Ji70QzKUqRy6oyJWUeB7+g2cRagT3T/nxYibYcT4y2BDL8lqolRXjTHmkZCdJfIPaY73KbJAZmcryxTQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.25.1" + } }, "node_modules/@types/prop-types": { "version": "15.7.5", @@ -682,9 +687,9 @@ "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" }, "node_modules/@types/react": { - "version": "18.2.14", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.14.tgz", - "integrity": "sha512-A0zjq+QN/O0Kpe30hA1GidzyFjatVvrpIvWLxD+xv67Vt91TWWgco9IvrJBkeyHm1trGaFS/FSGqPlhyeZRm0g==", + "version": "18.2.28", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.28.tgz", + "integrity": "sha512-ad4aa/RaaJS3hyGz0BGegdnSRXQBkd1CCYDCdNjBPg90UUpLgo+WlJqb9fMYUxtehmzF3PJaTWqRZjko6BRzBg==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -4790,6 +4795,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/swr": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/swr/-/swr-2.2.4.tgz", + "integrity": "sha512-njiZ/4RiIhoOlAaLYDqwz5qH/KZXVilRLvomrx83HjzCWTfa+InyfAjv05PSFxnmLzZkNO9ZfvgoqzAaEI4sGQ==", + "dependencies": { + "client-only": "^0.0.1", + "use-sync-external-store": "^1.2.0" + }, + "peerDependencies": { + "react": "^16.11.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/synckit": { "version": "0.8.5", "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz", @@ -5118,9 +5135,9 @@ } }, "node_modules/typescript": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.5.tgz", - "integrity": "sha512-FOH+WN/DQjUvN6WgW+c4Ml3yi0PH+a/8q+kNIfRehv1wLhWONedw85iu+vQ39Wp49IzTJEsZ2lyLXpBF7mkF1g==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -5143,6 +5160,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici-types": { + "version": "5.25.3", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz", + "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==", + "dev": true + }, "node_modules/untildify": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", @@ -5188,6 +5211,14 @@ "punycode": "^2.1.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/package.json b/package.json index a2602249..75de88b8 100644 --- a/package.json +++ b/package.json @@ -11,8 +11,6 @@ "dependencies": { "@react-email/components": "^0.0.7", "@react-email/tailwind": "^0.0.8", - "@types/node": "20.3.2", - "@types/react": "18.2.14", "@types/react-dom": "18.2.6", "autoprefixer": "10.4.14", "clsx": "^1.2.1", @@ -28,10 +26,13 @@ "react-intersection-observer": "^9.5.2", "react-vertical-timeline-component": "^3.6.0", "resend": "^0.16.0", - "tailwindcss": "3.3.2", - "typescript": "5.1.5" + "swr": "^2.2.4", + "tailwindcss": "3.3.2" }, "devDependencies": { - "@types/react-vertical-timeline-component": "^3.3.3" + "@types/node": "20.8.6", + "@types/react": "18.2.28", + "@types/react-vertical-timeline-component": "^3.3.3", + "typescript": "5.2.2" } }