From 805a9f40b0d473307c2b2a1ad3567f749a262aba Mon Sep 17 00:00:00 2001 From: Joseph Omotade Date: Wed, 3 May 2023 22:44:55 +0100 Subject: [PATCH 1/2] =?UTF-8?q?commit=20finished=20project=E2=9C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .hintrc | 13 ++ README.md | 3 + package-lock.json | 35 +++- package.json | 1 + src/components/Dashboard.tsx | 79 ++++----- src/components/modal/Setup.tsx | 72 +++++--- .../modal/component/Availability.tsx | 142 ++++++++++------ src/components/modal/component/Learn.tsx | 122 ++++++++----- src/components/modal/component/Speak.tsx | 140 +++++++++------ src/constant/index.ts | 2 +- src/context/index.tsx | 160 ++++++++++++++++++ src/pages/_app.tsx | 7 +- src/pages/dashboard.tsx | 5 +- src/pages/loabby.tsx | 4 +- 14 files changed, 568 insertions(+), 217 deletions(-) create mode 100644 .hintrc diff --git a/.hintrc b/.hintrc new file mode 100644 index 0000000..2fa1a2e --- /dev/null +++ b/.hintrc @@ -0,0 +1,13 @@ +{ + "extends": [ + "development" + ], + "hints": { + "axe/forms": [ + "default", + { + "select-name": "off" + } + ] + } +} \ No newline at end of file diff --git a/README.md b/README.md index 965a122..91561d6 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). +Figma file +[https://www.figma.com/file/4AnazUQXHdoJK1zEt4JQSx/Fluently?type=design&node-id=236-850&t=pKDK4WK3kfPbA3zZ-0](https://www.figma.com/file/4AnazUQXHdoJK1zEt4JQSx/Fluently?type=design&node-id=236-850&t=pKDK4WK3kfPbA3zZ-0) ## Getting Started First, run the development server: @@ -10,6 +12,7 @@ npm run dev yarn dev # or pnpm dev + ``` Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. diff --git a/package-lock.json b/package-lock.json index f0626c1..319cf4d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "@types/node": "18.15.11", "@types/react": "18.0.37", "@types/react-dom": "18.0.11", + "axios": "^1.4.0", "eslint": "8.38.0", "eslint-config-next": "13.3.0", "ethers": "^5.7.2", @@ -2315,6 +2316,15 @@ "zustand": "^4.0.0-rc.1" } }, + "node_modules/@huddle01/huddle01-client/node_modules/axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "dependencies": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, "node_modules/@huddle01/huddle01-iframe": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/@huddle01/huddle01-iframe/-/huddle01-iframe-0.0.9.tgz", @@ -3556,6 +3566,15 @@ "@ethersproject/properties": "^5.7.0" } }, + "node_modules/@safe-global/safe-ethers-adapters/node_modules/axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "dependencies": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, "node_modules/@safe-global/safe-ethers-lib": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/@safe-global/safe-ethers-lib/-/safe-ethers-lib-1.9.3.tgz", @@ -5088,12 +5107,13 @@ } }, "node_modules/axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", + "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", "dependencies": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" } }, "node_modules/axobject-query": { @@ -9861,6 +9881,11 @@ "resolved": "https://registry.npmjs.org/proxy-compare/-/proxy-compare-2.5.0.tgz", "integrity": "sha512-f1us0OsVAJ3tdIMXGQx2lmseYS4YXe4W+sKF5g5ww/jV+5ogMadPt+sIZ+88Ga9kvMJsrRNWzCrKPpr6pMWYbA==" }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", diff --git a/package.json b/package.json index 3634d70..5a6e2e2 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@types/node": "18.15.11", "@types/react": "18.0.37", "@types/react-dom": "18.0.11", + "axios": "^1.4.0", "eslint": "8.38.0", "eslint-config-next": "13.3.0", "ethers": "^5.7.2", diff --git a/src/components/Dashboard.tsx b/src/components/Dashboard.tsx index d239139..5380abc 100644 --- a/src/components/Dashboard.tsx +++ b/src/components/Dashboard.tsx @@ -12,21 +12,30 @@ import { Text, Flex, useDisclosure, + Link, } from "@chakra-ui/react"; import { useAddress } from "@thirdweb-dev/react"; import Setup from "./modal/Setup"; import truncateEthAddress from "truncate-eth-address"; -const Dashboard = () => { +type Props = { + item: any[]; // I assumed this prop is an array of objects with the structure that the `getAllMeeting` function returns +}; + +const Dashboard = ({ item }: Props) => { + console.log(item); const address = useAddress(); const { isOpen, onOpen, onClose } = useDisclosure(); + + const userMeetings = item.filter((meeting) => meeting.user === address && meeting.matched === true); return ( <> + - Hey {address && `${truncateEthAddress(address)}`} + Hey {address ? truncateEthAddress(address) : ""} Your language partner is waiting for you. @@ -59,46 +68,30 @@ const Dashboard = () => { - - Thurs, 27th April, 4:00 PM - Irish - Pakistan - - - - - - - - - Thurs, 27th April, 4:00 PM - Irish - Pakistan - - - - - - - + {userMeetings.map((detail, i) => ( + + Thurs, 27th April, 4:00 PM {/* TODO: Use `detail.time` to render the actual date */} + {detail.language} + {detail.native} + + + + + + + + + + ))} @@ -108,4 +101,4 @@ const Dashboard = () => { ); }; -export default Dashboard; +export default Dashboard; \ No newline at end of file diff --git a/src/components/modal/Setup.tsx b/src/components/modal/Setup.tsx index 389b6cd..4c35098 100644 --- a/src/components/modal/Setup.tsx +++ b/src/components/modal/Setup.tsx @@ -1,4 +1,20 @@ -import { Box, Button, Flex, FormControl, FormLabel, Image, Modal, ModalBody, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalOverlay, Select, Text } from "@chakra-ui/react" +import { + Box, + Button, + Flex, + FormControl, + FormLabel, + Image, + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + ModalFooter, + ModalHeader, + ModalOverlay, + Select, + Text, +} from "@chakra-ui/react"; import { useState } from "react"; import Availability from "./component/Availability"; import Learn from "./component/Learn"; @@ -6,28 +22,40 @@ import Speak from "./component/Speak"; import Complete from "./component/Complete"; interface Props { - isOpen: boolean; - onClose: () => void; + isOpen: boolean; + onClose: () => void; } -const Setup : React.FC = ({ isOpen, onClose }) => { - const [activeComponent, setActiveComponent] = useState('learn') +const Setup: React.FC = ({ isOpen, onClose }) => { + const [activeComponent, setActiveComponent] = useState("learn"); - return ( - - - - - - {/* logo */} - - {activeComponent === 'learn' && } - {activeComponent === 'speak' && } - {activeComponent === 'available' && } - {activeComponent === 'complete' && } - - - ) -} + return ( + + + + + + {/* logo */} + + {activeComponent === "learn" && ( + + )} + {activeComponent === "speak" && ( + + )} + {activeComponent === "available" && ( + + )} + {activeComponent === "complete" && } + + + ); +}; -export default Setup \ No newline at end of file +export default Setup; diff --git a/src/components/modal/component/Availability.tsx b/src/components/modal/component/Availability.tsx index e603785..d8a5eae 100644 --- a/src/components/modal/component/Availability.tsx +++ b/src/components/modal/component/Availability.tsx @@ -1,57 +1,101 @@ -import { Box, Button, Center, Flex, FormControl, FormLabel, Image, Modal, ModalBody, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalOverlay, Select, Text, Wrap, WrapItem } from "@chakra-ui/react" +import { useFluentContext } from "@/context"; +import { + Box, + Button, + Center, + Flex, + FormControl, + FormLabel, + Image, + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + ModalFooter, + ModalHeader, + ModalOverlay, + Select, + Text, + Wrap, + WrapItem, +} from "@chakra-ui/react"; import { FiArrowRight } from "react-icons/fi"; -import { MdKeyboardArrowLeft, MdKeyboardArrowRight } from "react-icons/md" +import { MdKeyboardArrowLeft, MdKeyboardArrowRight } from "react-icons/md"; +import { useState } from "react"; type Props = { - setActiveComponent: React.Dispatch>; + setActiveComponent: React.Dispatch>; }; const Availability: React.FC = ({ setActiveComponent }) => { + const { time, setTime,createMeeting, getRoomId } = useFluentContext(); + const [complete, setComplete] = useState(""); + console.log(time); - return ( - <> - - Select availabilty - Please select from the available time slots to increase the chances of finding a suitable language exchange partner. - - - - - - Thurs - April 27 - - - - -
- - - 04:00 PM - - -
-
-
- - - - - - ) -} + const meeting = async () => { + try { + const meetings = await getRoomId() + const meeting = createMeeting(meetings); + setActiveComponent("complete"); + console.log(meetings); + } catch (error) { + console.log(error); + } + }; + return ( + <> + + + Select availabilty + + + Please select from the available time slots to increase the chances of + finding a suitable language exchange partner. + + + + + + + Thurs + April 27 + + + + +
+ + setTime(440)} + > + 04:00 PM + + +
+
+
+ + + + + + ); +}; -export default Availability; \ No newline at end of file +export default Availability; diff --git a/src/components/modal/component/Learn.tsx b/src/components/modal/component/Learn.tsx index a9c19b5..26d9c5d 100644 --- a/src/components/modal/component/Learn.tsx +++ b/src/components/modal/component/Learn.tsx @@ -1,50 +1,88 @@ -import { Box, Button, Flex, FormControl, FormLabel, Image, Modal, ModalBody, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalOverlay, Select, Text } from "@chakra-ui/react" -import { BsQuestionCircleFill, BsSearch, BsSearchHeartFill, BsStar } from "react-icons/bs"; +import { useFluentContext } from "@/context"; +import { + Box, + Button, + Flex, + FormControl, + FormLabel, + Image, + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + ModalFooter, + ModalHeader, + ModalOverlay, + Select, + Text, + +} from "@chakra-ui/react"; +import { + BsQuestionCircleFill, + BsSearch, + BsSearchHeartFill, + BsStar, +} from "react-icons/bs"; import { FiArrowRight } from "react-icons/fi"; type Props = { - setActiveComponent: React.Dispatch>; + setActiveComponent: React.Dispatch>; }; const Learn: React.FC = ({ setActiveComponent }) => { + const { language, setLanguage } = useFluentContext(); + console.log(language) - return ( - <> - - Set up languagues preferences - Please select the language you want to learn and your proficiency level in that language. - - - Select language - - - - Select your proficiency level - - - - - - - - - - - - - - - - ) -} + return ( + <> + + + Set up languagues preferences + + + Please select the language you want to learn and your proficiency + level in that language. + + + + + Select language + + + + + + Select your proficiency level + + + + + + + + + + + + + + + + + ); +}; -export default Learn; \ No newline at end of file +export default Learn; diff --git a/src/components/modal/component/Speak.tsx b/src/components/modal/component/Speak.tsx index bd524cd..82677de 100644 --- a/src/components/modal/component/Speak.tsx +++ b/src/components/modal/component/Speak.tsx @@ -1,57 +1,97 @@ -import { Box, Button, Flex, FormControl, FormLabel, Image, Modal, ModalBody, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalOverlay, Select, Text } from "@chakra-ui/react" -import { BsQuestionCircleFill, BsSearch, BsSearchHeartFill, BsStar } from "react-icons/bs"; +import { useFluentContext } from "@/context"; +import { + Box, + Button, + Flex, + FormControl, + FormLabel, + Image, + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + ModalFooter, + ModalHeader, + ModalOverlay, + Select, + Text, +} from "@chakra-ui/react"; +import { + BsQuestionCircleFill, + BsSearch, + BsSearchHeartFill, + BsStar, +} from "react-icons/bs"; import { FiArrowRight } from "react-icons/fi"; type Props = { - setActiveComponent: React.Dispatch>; + setActiveComponent: React.Dispatch>; }; const Speak: React.FC = ({ setActiveComponent }) => { + const { native, setNative } = useFluentContext(); + console.log(native) + return ( + <> + + + Choose spoken language + + + Please select the language you can speak to help us find the best + language exchange partner for you. + + + + + Select language + + + + + + Select your proficiency level + + + + + + + + + + + + + + + + + + ); +}; - return ( - <> - - Choose spoken language - Please select the language you can speak to help us find the best language exchange partner for you. - - - Select language - - - - Select your proficiency level - - - - - - - - - - - - - - - - - ) -} - -export default Speak; \ No newline at end of file +export default Speak; diff --git a/src/constant/index.ts b/src/constant/index.ts index 514e3f4..00e6cb9 100644 --- a/src/constant/index.ts +++ b/src/constant/index.ts @@ -3,7 +3,7 @@ import FluentTokenAbi from "./FLUENTOKEN.json"; import { ethers } from "ethers"; export const tokenAddress = "0x7cc168Ed905f1160C6AfcFf64FA691f5462a13CA"; -export const tokenAccount = "0xE4c84a30D8c6D8f6f86D916Dc62387A5Fc12193D"; +export const tokenAccount = "0x86Ae062a625e1950009D6f3863199282C196F528"; export const accountAbi = FlentAccountAbi.abi; export const tokenAbi = FluentTokenAbi.abi; diff --git a/src/context/index.tsx b/src/context/index.tsx index e69de29..94a80c5 100644 --- a/src/context/index.tsx +++ b/src/context/index.tsx @@ -0,0 +1,160 @@ +import connectWithContract from "@/constant"; +import React, { useContext, createContext, useState, useEffect } from "react"; +import { ethers } from "ethers"; +import { useHuddleStore } from "@huddle01/huddle01-client/store"; +import { getHuddleClient } from "@huddle01/huddle01-client"; +import { useAddress } from "@thirdweb-dev/react"; +import { useRouter } from "next/router"; +import axios from "axios"; + +type FluentProviderProps = { + children: React.ReactNode; +}; + +interface PodcastContextProps { + language: string; + native: string; + allMeeting: any[]; + setLanguage: React.Dispatch>; + setNative: React.Dispatch>; + setAllMeeting: React.Dispatch>; + setTime: React.Dispatch>; + time: number | undefined; + createMeeting: (meetingLink: string) => Promise; + getAllMeeting: () => Promise; + getUserMeeting: () => void; + getRoomId: () => Promise; +} + +const FluentContext = createContext({ + language: "", + native: "", + allMeeting: [], + setAllMeeting: () => {}, + setLanguage: () => {}, + setNative: () => {}, + setTime: () => {}, + time: undefined, + createMeeting: async (meetingLink: string) => {}, + getAllMeeting: async () => [], + getUserMeeting: () => {}, + getRoomId: async () => "", +}); + +export const FluentProvider = ({ children }: FluentProviderProps) => { + const roomId = useHuddleStore((state) => state.roomState.roomId); + // const huddleClient = getHuddleClient("VwTZ4AGTxme9snANex9tep3NwvVMGfYd"); + // console.log(huddleClient) + + const API_KEY = "VwTZ4AGTxme9snANex9tep3NwvVMGfYd"; + + const [meetingLink, setMeetingLink] = useState(""); + // console.log(meetingLink); + const router = useRouter(); + + const getRoomId = async () => { + try { + const { data } = await axios.post( + "https://iriko.testing.huddle01.com/api/v1/create-iframe-room", + { + title: "Huddle01-Test", + roomLocked: false, + }, + { + headers: { + "Content-Type": "application/json", + "x-api-key": API_KEY, + }, + } + ); + setMeetingLink(data.data.meetingLink); + console.log(data); + return data.data.meetingLink; + } catch (error) { + console.log(error); + return ""; + } + }; + + useEffect(() => { + if (address) { + router.push("/welcome"); + } + }, []); + + const address = useAddress(); + const [language, setLanguage] = useState(""); + const [native, setNative] = useState(""); + const [time, setTime] = useState(); + const [allMeeting, setAllMeeting] = useState([]); + // const meetingLink = `https://iframe.huddle01.com/${roomId}`; + + const createMeeting = async (meetingLink: string) => { + const meetingContract = await connectWithContract(); + const meeting = meetingContract.createMeeting( + language, + native, + meetingLink, + time + ); + console.log(meeting); + }; + + const getAllMeeting = async () => { + try { + const meeetingContract = await connectWithContract(); + const meeting = await meeetingContract._allMeetings(); + //console.log(meeting) + const parsedAccount = meeting.map((user: any, i: any) => ({ + user: user.user, + language: user.language, + native: user.nativeLanguage, + status: user.matchStatus, + pid: user.matchId.toNumber(), + time: user.time.toNumber(), + meeting: user.meetingLink, + matched: user.userMatched, + })); + setAllMeeting(parsedAccount); + return parsedAccount; + } catch (error) { + console.log(error); + } + }; + + const getUserMeeting = async () => { + const meeting = await getAllMeeting(); + console.log(meeting); + const filterUserMeeting = meeting.filter( + (account: any) => account.user === address + ); + console.log(filterUserMeeting); + }; + + useEffect(() => { + getAllMeeting(); + getUserMeeting(); + }, []); + + const value = { + language, + setLanguage, + setNative, + native, + time, + setTime, + createMeeting, + getAllMeeting, + allMeeting, + setAllMeeting, + getRoomId, + getUserMeeting, + }; + + return ( + {children} + ); +}; + +export const useFluentContext = (): PodcastContextProps => + useContext(FluentContext); diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 7f31eb7..86ebdd9 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -21,6 +21,7 @@ import { useAddress, } from "@thirdweb-dev/react"; import { useRouter } from "next/router"; +import { FluentProvider } from "@/context"; export const theme = extendTheme({ colors }); @@ -33,7 +34,7 @@ export default function App({ Component, pageProps }: AppProps) { useEffect(() => { if (address) { - Router.push("/dasboard"); + Router.push("/welcome"); } }, [address]); @@ -44,7 +45,9 @@ export default function App({ Component, pageProps }: AppProps) { supportedWallets={[metamaskWallet(), coinbaseWallet(), walletConnect()]} > - + + + diff --git a/src/pages/dashboard.tsx b/src/pages/dashboard.tsx index 145bdae..e72c090 100644 --- a/src/pages/dashboard.tsx +++ b/src/pages/dashboard.tsx @@ -23,10 +23,13 @@ import { ConnectWallet as ConnectWeb3Wallet, } from "@thirdweb-dev/react"; import truncateEthAddress from "truncate-eth-address"; +import { useFluentContext } from "@/context"; const Dashboard = () => { const address = useAddress(); const connect = useMetamask(); + const { allMeeting } = useFluentContext() + //console.log(allMeeting) return ( @@ -67,7 +70,7 @@ const Dashboard = () => { /> - + diff --git a/src/pages/loabby.tsx b/src/pages/loabby.tsx index 7d60c18..a1f372a 100644 --- a/src/pages/loabby.tsx +++ b/src/pages/loabby.tsx @@ -7,8 +7,8 @@ import { } from "@huddle01/huddle01-iframe"; import { useAddress } from "@thirdweb-dev/react"; import { useEffect, useLayoutEffect, useState } from "react"; -import MeVideoElem from "@/components/MeVideoElem"; -import { Button } from "@chakra-ui/react"; +//import MeVideoElem from "@/components/MeVideoElem"; +//import { Button } from "@chakra-ui/react"; const Loabby = () => { const huddleClient = getHuddleClient("gfhhf"); From 5d0a38eb4bae351b14424f095617ff968a738abd Mon Sep 17 00:00:00 2001 From: Joseph Omotade Date: Thu, 4 May 2023 00:37:05 +0100 Subject: [PATCH 2/2] Merge branch 'main' of --- src/components/Header.tsx | 2 +- src/pages/loabby.tsx | 2 +- src/pages/video.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 878f106..e05cc6a 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -62,7 +62,7 @@ const Header = () => { bgRepeat="no-repeat" bgSize="cover" > - group + group diff --git a/src/pages/loabby.tsx b/src/pages/loabby.tsx index a1f372a..8d7c4cc 100644 --- a/src/pages/loabby.tsx +++ b/src/pages/loabby.tsx @@ -42,7 +42,7 @@ const Loabby = () => { noBorder: false, // false by default }; return ( -
+
diff --git a/src/pages/video.tsx b/src/pages/video.tsx index 3dfcd99..cc2dde6 100644 --- a/src/pages/video.tsx +++ b/src/pages/video.tsx @@ -2,7 +2,7 @@ import React from "react"; const Video = () => { return ( -
+
josep
);