From fb37793b060710ec88856632ddf13f5695c6b53e Mon Sep 17 00:00:00 2001 From: yunusabdul Date: Sun, 4 May 2025 21:41:29 +0100 Subject: [PATCH 1/4] feat: starknet wallet connector --- package-lock.json | 55 ++++ package.json | 16 +- src/app/components/navbar.tsx | 252 ++++++++++++++++++ src/app/components/provider.tsx | 36 +++ src/app/components/wallet-connect-modal.tsx | 183 +++++++++++++ .../components/wallet-disconnect-modal.tsx | 121 +++++++++ src/app/components/walletProvider.tsx | 79 ++++++ src/app/motion/animation-wrapper.tsx | 92 +++++++ src/app/page.tsx | 100 +------ 9 files changed, 831 insertions(+), 103 deletions(-) create mode 100644 src/app/components/navbar.tsx create mode 100644 src/app/components/provider.tsx create mode 100644 src/app/components/wallet-connect-modal.tsx create mode 100644 src/app/components/wallet-disconnect-modal.tsx create mode 100644 src/app/components/walletProvider.tsx create mode 100644 src/app/motion/animation-wrapper.tsx diff --git a/package-lock.json b/package-lock.json index 53fed30..d072f9e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,9 @@ "name": "blockopoly", "version": "0.1.0", "dependencies": { + "@starknet-react/chains": "^3.1.3", + "framer-motion": "^12.9.4", + "lucide-react": "^0.507.0", "next": "15.3.1", "react": "^19.0.0", "react-dom": "^19.0.0" @@ -870,6 +873,11 @@ "dev": true, "license": "MIT" }, + "node_modules/@starknet-react/chains": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@starknet-react/chains/-/chains-3.1.3.tgz", + "integrity": "sha512-b16VQyxqZXfiVmlKEkjfg+Oj8fdSnGWh1KU87O/unn6NpmaD9h511az1Cs6aW/j3qCIF1o5CrqfEnU1NWV7MVA==" + }, "node_modules/@swc/counter": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", @@ -3116,6 +3124,32 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/framer-motion": { + "version": "12.9.4", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.9.4.tgz", + "integrity": "sha512-yaeGDmGQ3eCQEwZ95/pRQMaSh/Q4E2CK6JYOclG/PdjyQad0MULJ+JFVV8911Fl5a6tF6o0wgW8Dpl5Qx4Adjg==", + "dependencies": { + "motion-dom": "^12.9.4", + "motion-utils": "^12.9.4", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -4269,6 +4303,14 @@ "loose-envify": "cli.js" } }, + "node_modules/lucide-react": { + "version": "0.507.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.507.0.tgz", + "integrity": "sha512-XfgE6gvAHwAtnbUvWiTTHx4S3VGR+cUJHEc0vrh9Ogu672I1Tue2+Cp/8JJqpytgcBHAB1FVI297W4XGNwc2dQ==", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -4326,6 +4368,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/motion-dom": { + "version": "12.9.4", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.9.4.tgz", + "integrity": "sha512-25TWkQPj5I18m+qVjXGtCsxboY11DaRC5HMjd29tHKExazW4Zf4XtAagBdLpyKsVuAxEQ6cx5/E4AB21PFpLnQ==", + "dependencies": { + "motion-utils": "^12.9.4" + } + }, + "node_modules/motion-utils": { + "version": "12.9.4", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.9.4.tgz", + "integrity": "sha512-BW3I65zeM76CMsfh3kHid9ansEJk9Qvl+K5cu4DVHKGsI52n76OJ4z2CUJUV+Mn3uEP9k1JJA3tClG0ggSrRcg==" + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", diff --git a/package.json b/package.json index 8b35a0c..e8cb270 100644 --- a/package.json +++ b/package.json @@ -9,19 +9,23 @@ "lint": "next lint" }, "dependencies": { + "@starknet-react/chains": "^3.1.3", + "@starknet-react/core": "^3.7.4", + "framer-motion": "^12.9.4", + "lucide-react": "^0.507.0", + "next": "15.3.1", "react": "^19.0.0", - "react-dom": "^19.0.0", - "next": "15.3.1" + "react-dom": "^19.0.0" }, "devDependencies": { - "typescript": "^5", + "@eslint/eslintrc": "^3", + "@tailwindcss/postcss": "^4", "@types/node": "^20", "@types/react": "^19", "@types/react-dom": "^19", - "@tailwindcss/postcss": "^4", - "tailwindcss": "^4", "eslint": "^9", "eslint-config-next": "15.3.1", - "@eslint/eslintrc": "^3" + "tailwindcss": "^4", + "typescript": "^5" } } diff --git a/src/app/components/navbar.tsx b/src/app/components/navbar.tsx new file mode 100644 index 0000000..fe3e73c --- /dev/null +++ b/src/app/components/navbar.tsx @@ -0,0 +1,252 @@ +"use client"; + +import { useState, useRef, useEffect } from "react"; +import Link from "next/link"; +import Image from "next/image"; +import { Menu, X, MoreVertical } from "lucide-react"; +import { motion, AnimatePresence } from "framer-motion"; +import { useWalletContext } from "./walletProvider"; +import AnimationWrapper from "../motion/animation-wrapper"; +import WalletConnectModal from "./wallet-connect-modal"; +import WalletDisconnectModal from "./wallet-disconnect-modal"; + +export default function Navbar() { + const [isMenuOpen, setIsMenuOpen] = useState(false); + const [isConnectModalOpen, setIsConnectModalOpen] = useState(false); + const [isDisconnectModalOpen, setIsDisconnectModalOpen] = useState(false); + const [isDropdownOpen, setIsDropdownOpen] = useState(false); + const dropdownRef = useRef(null); + const { account, connectWallet, disconnectWallet, connectors } = + useWalletContext(); + // Close dropdown when clicking outside + useEffect(() => { + function handleClickOutside(event: MouseEvent) { + if ( + dropdownRef.current && + !dropdownRef.current.contains(event.target as Node) + ) { + setIsDropdownOpen(false); + } + } + + document.addEventListener("mousedown", handleClickOutside); + return () => { + document.removeEventListener("mousedown", handleClickOutside); + }; + }, []); + const toggleMenu = () => setIsMenuOpen(!isMenuOpen); + const toggleDropdown = () => setIsDropdownOpen(!isDropdownOpen); + const handleWalletSelect = (walletId: string) => { + const connector = connectors.find((c) => c.id === walletId); + if (connector) { + connectWallet(connector); // invoke Starknet-React’s useConnect() :contentReference[oaicite:3]{index=3} + } + setIsConnectModalOpen(false); + }; + const handleConnectWallet = () => { + setIsConnectModalOpen(true); + }; + const handleWalletClick = () => { + setIsDisconnectModalOpen(true); + }; + const handleDisconnect = () => { + disconnectWallet(); // real Starknet-React disconnect :contentReference[oaicite:4]{index=4} + setIsDisconnectModalOpen(false); + }; + const navLinks = [ + { name: "Features", href: "/#features" }, + { name: "How It Works", href: "/#how-it-works" }, + { name: "Benefits", href: "/#benefits" }, + { name: "FAQs", href: "/#faqs" }, + ]; + + return ( + <> +
+
+ + + blockopoly + + + + {/* Desktop Navigation */} + + + + {/* Wallet Connection Button or Connected Wallet */} + +
+ + {!account ? ( + + ) : ( +
+
+
+ Wallet Avatar +
+ + + {account.slice(0, 6)}…{account.slice(-4)} + + + +
+ + {/* Custom Dropdown Menu */} + + {isDropdownOpen && ( +
+
+ + + + View Profile + + + +
+
+ )} +
+ )} +
+
+ + {/* Mobile Menu Button */} + +
+ + {!account ? ( + + ) : ( +
+
+ Wallet Avatar +
+ + + {account.slice(0, 6)}…{account.slice(-4)} + +
+ )} +
+ + +
+
+ + {/* Mobile Navigation */} + + + {isMenuOpen && ( + +
+ {navLinks.map((link, index) => ( + + setIsMenuOpen(false)} + > + {link.name} + + + ))} +
+
+ )} +
+
+ + setIsConnectModalOpen(false)} + onSelect={handleWalletSelect} + /> + + setIsDisconnectModalOpen(false)} + onDisconnect={handleDisconnect} + /> + + ); +} diff --git a/src/app/components/provider.tsx b/src/app/components/provider.tsx new file mode 100644 index 0000000..1f3e070 --- /dev/null +++ b/src/app/components/provider.tsx @@ -0,0 +1,36 @@ +"use client"; + +import React from "react"; + +import { sepolia, mainnet } from "@starknet-react/chains"; + +import { + StarknetConfig, + publicProvider, + argent, + braavos, + useInjectedConnectors, + voyager, +} from "@starknet-react/core"; + +export function StarknetProvider({ children }: { children: React.ReactNode }) { + const { connectors } = useInjectedConnectors({ + // Show these connectors if the user has no connector installed. + recommended: [argent(), braavos()], + // Hide recommended connectors if the user has any connector installed. + includeRecommended: "onlyIfNoConnectors", + // Randomize the order of the connectors. + order: "random", + }); + + return ( + + {children} + + ); +} diff --git a/src/app/components/wallet-connect-modal.tsx b/src/app/components/wallet-connect-modal.tsx new file mode 100644 index 0000000..1695a95 --- /dev/null +++ b/src/app/components/wallet-connect-modal.tsx @@ -0,0 +1,183 @@ +"use client"; + +import { useState } from "react"; +import { motion, AnimatePresence } from "framer-motion"; +import { X } from "lucide-react"; +import Image from "next/image"; +import { useRouter } from "next/navigation"; +import { useWalletContext } from "./walletProvider"; +import AnimationWrapper from "../motion/animation-wrapper"; + +interface WalletOption { + id: string; + name: string; + icon: string; +} + +interface WalletConnectModalProps { + isOpen: boolean; + onClose: () => void; + onSelect: (wallet: string) => void; +} + +export default function WalletConnectModal({ + isOpen, + onClose, +}: WalletConnectModalProps) { + const [selectedWallet, setSelectedWallet] = useState(null); + const { connectors, connectAsync, account } = useWalletContext(); + const router = useRouter(); + const handleSelect = (walletId: string) => { + setSelectedWallet(walletId); + }; + // ② On confirm, look up the connector object and call connectWallet + const handleConfirm = async () => { + if (!selectedWallet) return; + const connector = connectors.find((c) => c.id === selectedWallet); + if (!connector) { + console.error("Connector not found:", selectedWallet); + return; + } + + try { + await connectAsync({ connector }); // ■ await the wallet prompt + //router.push("/dashboard"); // ■ now safe to navigate + onClose(); + } catch (err) { + console.error("Wallet connection failed:", err); // ■ handle rejections + } + }; + + const modalVariants = { + hidden: { opacity: 0, scale: 0.9 }, + visible: { + opacity: 1, + scale: 1, + transition: { + duration: 0.2, + ease: "easeOut", + }, + }, + + exit: { + opacity: 0, + scale: 0.9, + transition: { + duration: 0.2, + ease: "easeIn", + }, + }, + }; + + const backdropVariants = { + hidden: { opacity: 0 }, + visible: { opacity: 1 }, + exit: { opacity: 0 }, + }; + + // helper to get icon source + function getIconSource( + icon: string | { dark: string; light: string } + ): string { + if (typeof icon === "string") { + // If it's a string, use it directly + return icon; + } else { + // If it's an object, use the dark variant (or light, as needed) + return icon.dark; // Or icon.light, depending on your theme + } + } + + return ( + + {isOpen && ( +
+ + + +
+

+ Connect Wallet +

+ + +
+ +

+ Choose a wallet you want to connect to SkillNet +

+ +
+ {connectors.map((wallet, index) => ( + + + + ))} +
+ + {/* ③ Confirmation button */} + + + + +
+
+ )} +
+ ); +} diff --git a/src/app/components/wallet-disconnect-modal.tsx b/src/app/components/wallet-disconnect-modal.tsx new file mode 100644 index 0000000..9dbb0a0 --- /dev/null +++ b/src/app/components/wallet-disconnect-modal.tsx @@ -0,0 +1,121 @@ +"use client"; + +import { motion, AnimatePresence } from "framer-motion"; +import { useRouter } from "next/navigation"; +import { usePathname } from "next/navigation"; +import { X } from "lucide-react"; +import AnimationWrapper from "../motion/animation-wrapper"; + +interface WalletDisconnectModalProps { + isOpen: boolean; + onClose: () => void; + onDisconnect: () => void; +} + +export default function WalletDisconnectModal({ + isOpen, + onClose, + onDisconnect, +}: WalletDisconnectModalProps) { + //pathname check + const pathName = usePathname(); + const userDashboardPath = "/dashboard/user"; + const institutionDashboardPath = "/dashboard/institution"; + //router + const router = useRouter(); + const handleDisconnect = () => { + if ( + userDashboardPath === pathName || + institutionDashboardPath === pathName + ) { + router.push("/"); // ■ now safe to navigate + } + onDisconnect(); + }; + + const modalVariants = { + hidden: { opacity: 0, scale: 0.9 }, + visible: { + opacity: 1, + scale: 1, + transition: { + duration: 0.2, + ease: "easeOut", + }, + }, + + exit: { + opacity: 0, + scale: 0.9, + transition: { + duration: 0.2, + ease: "easeIn", + }, + }, + }; + + const backdropVariants = { + hidden: { opacity: 0 }, + visible: { opacity: 1 }, + exit: { opacity: 0 }, + }; + + return ( + + {isOpen && ( +
+ + + +
+

+ Disconnect Wallet +

+ +
+ + +

+ Are you sure you want to disconnect your wallet? +

+
+ +
+ + + +
+
+
+ )} +
+ ); +} diff --git a/src/app/components/walletProvider.tsx b/src/app/components/walletProvider.tsx new file mode 100644 index 0000000..976d146 --- /dev/null +++ b/src/app/components/walletProvider.tsx @@ -0,0 +1,79 @@ +"use client"; + +import React, { + createContext, + useContext, + ReactNode, + useCallback, + useEffect, +} from "react"; + +import { + useConnect, + useAccount, + useDisconnect, + Connector, + ConnectVariables, +} from "@starknet-react/core"; + +interface WalletContextProps { + account: string | null; + connectors: Connector[]; // ← Exposed connectors + connectWallet: (connector: Connector) => void; // ← Takes connector arg + disconnectWallet: () => void; + connectAsync: (args?: ConnectVariables) => Promise; +} + +const WalletContext = createContext({ + account: null, + connectors: [], // ← Default empty + connectWallet: () => {}, + disconnectWallet: () => {}, + connectAsync: () => Promise.resolve(), +}); + +export const WalletProvider: React.FC<{ children: ReactNode }> = ({ + children, +}) => { + const { connect, connectors, connectAsync } = useConnect(); + const { address } = useAccount(); + const { disconnect } = useDisconnect(); + // Accept a specific connector when connecting + const connectWallet = useCallback( + (connector: Connector) => { + connect({ connector }); + }, + [connect] + ); + + // Save wallet address to localStorage when connected + useEffect(() => { + if (address) { + localStorage.setItem("walletAddress", address); + } else { + localStorage.removeItem("walletAddress"); + } + }, [address]); + + return ( + + {children} + + ); +}; + +export const useWalletContext = () => { + const ctx = useContext(WalletContext); + if (!ctx) { + throw new Error("useWalletContext must be inside WalletProvider"); + } + return ctx; +}; diff --git a/src/app/motion/animation-wrapper.tsx b/src/app/motion/animation-wrapper.tsx new file mode 100644 index 0000000..52c6adb --- /dev/null +++ b/src/app/motion/animation-wrapper.tsx @@ -0,0 +1,92 @@ +"use client"; + +import type { ReactNode } from "react"; + +import { motion, type MotionProps } from "framer-motion"; + +type AnimationVariant = + | "fadeIn" + | "slideUp" + | "slideDown" + | "slideLeft" + | "slideRight" + | "scale" + | "bounce"; + +interface AnimationWrapperProps extends Omit { + children: ReactNode; + variant?: AnimationVariant; + delay?: number; + duration?: number; + className?: string; + once?: boolean; +} + +const variants = { + fadeIn: { + hidden: { opacity: 0 }, + visible: { opacity: 1 }, + }, + + slideUp: { + hidden: { y: 50, opacity: 0 }, + visible: { y: 0, opacity: 1 }, + }, + + slideDown: { + hidden: { y: -50, opacity: 0 }, + visible: { y: 0, opacity: 1 }, + }, + + slideLeft: { + hidden: { x: 50, opacity: 0 }, + visible: { x: 0, opacity: 1 }, + }, + + slideRight: { + hidden: { x: -50, opacity: 0 }, + visible: { x: 0, opacity: 1 }, + }, + + scale: { + hidden: { scale: 0.8, opacity: 0 }, + visible: { scale: 1, opacity: 1 }, + }, + + bounce: { + hidden: { y: 50, opacity: 0 }, + visible: { + y: 0, + opacity: 1, + transition: { + type: "spring", + stiffness: 300, + damping: 15, + }, + }, + }, +}; + +export default function AnimationWrapper({ + children, + variant = "fadeIn", + delay = 0, + duration = 0.5, + className = "", + once = true, + ...props +}: AnimationWrapperProps) { + return ( + + {children} + + ); +} diff --git a/src/app/page.tsx b/src/app/page.tsx index e68abe6..821a588 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,103 +1,9 @@ -import Image from "next/image"; +import Navbar from "./components/navbar"; export default function Home() { return ( -
-
- Next.js logo -
    -
  1. - Get started by editing{" "} - - src/app/page.tsx - - . -
  2. -
  3. - Save and see your changes instantly. -
  4. -
- - -
- +
+
); } From 96b865b59e2e2c951240873d80708d8c5cc6a357 Mon Sep 17 00:00:00 2001 From: yunusabdul Date: Tue, 6 May 2025 15:28:20 +0100 Subject: [PATCH 2/4] fix: wallet connector --- src/app/components/icons/logo.tsx | 16 +++ src/app/components/navbar.tsx | 99 ++++--------------- src/app/components/provider.tsx | 2 +- src/app/components/wallet-connect-modal.tsx | 19 ++-- .../components/wallet-disconnect-modal.tsx | 6 +- src/app/components/walletProvider.tsx | 10 +- src/app/globals.css | 3 +- src/app/layout.tsx | 18 +++- 8 files changed, 61 insertions(+), 112 deletions(-) create mode 100644 src/app/components/icons/logo.tsx diff --git a/src/app/components/icons/logo.tsx b/src/app/components/icons/logo.tsx new file mode 100644 index 0000000..a2c12dd --- /dev/null +++ b/src/app/components/icons/logo.tsx @@ -0,0 +1,16 @@ +export default function Logo() { + return ( + + + + ); +} diff --git a/src/app/components/navbar.tsx b/src/app/components/navbar.tsx index fe3e73c..632a532 100644 --- a/src/app/components/navbar.tsx +++ b/src/app/components/navbar.tsx @@ -3,22 +3,20 @@ import { useState, useRef, useEffect } from "react"; import Link from "next/link"; import Image from "next/image"; -import { Menu, X, MoreVertical } from "lucide-react"; -import { motion, AnimatePresence } from "framer-motion"; +import { MoreVertical, House, Volume2 } from "lucide-react"; import { useWalletContext } from "./walletProvider"; import AnimationWrapper from "../motion/animation-wrapper"; import WalletConnectModal from "./wallet-connect-modal"; import WalletDisconnectModal from "./wallet-disconnect-modal"; +import Logo from "./icons/logo"; export default function Navbar() { - const [isMenuOpen, setIsMenuOpen] = useState(false); const [isConnectModalOpen, setIsConnectModalOpen] = useState(false); const [isDisconnectModalOpen, setIsDisconnectModalOpen] = useState(false); const [isDropdownOpen, setIsDropdownOpen] = useState(false); const dropdownRef = useRef(null); const { account, connectWallet, disconnectWallet, connectors } = useWalletContext(); - // Close dropdown when clicking outside useEffect(() => { function handleClickOutside(event: MouseEvent) { if ( @@ -34,7 +32,6 @@ export default function Navbar() { document.removeEventListener("mousedown", handleClickOutside); }; }, []); - const toggleMenu = () => setIsMenuOpen(!isMenuOpen); const toggleDropdown = () => setIsDropdownOpen(!isDropdownOpen); const handleWalletSelect = (walletId: string) => { const connector = connectors.find((c) => c.id === walletId); @@ -53,53 +50,31 @@ export default function Navbar() { disconnectWallet(); // real Starknet-React disconnect :contentReference[oaicite:4]{index=4} setIsDisconnectModalOpen(false); }; - const navLinks = [ - { name: "Features", href: "/#features" }, - { name: "How It Works", href: "/#how-it-works" }, - { name: "Benefits", href: "/#benefits" }, - { name: "FAQs", href: "/#faqs" }, - ]; return ( <> -
-
+
+
- blockopoly + - {/* Desktop Navigation */} - - - {/* Wallet Connection Button or Connected Wallet */} -
+
+
+ +
+
+ +
{!account ? ( @@ -107,7 +82,7 @@ export default function Navbar() {
+
) : (
)} - -
- - {/* Mobile Navigation */} - - - {isMenuOpen && ( - -
- {navLinks.map((link, index) => ( - - setIsMenuOpen(false)} - > - {link.name} - - - ))} -
-
- )} -
(null); - const { connectors, connectAsync, account } = useWalletContext(); - const router = useRouter(); + const { connectors, connectAsync} = useWalletContext(); const handleSelect = (walletId: string) => { setSelectedWallet(walletId); }; @@ -102,14 +95,14 @@ export default function WalletConnectModal({ />
-

+

Connect Wallet

@@ -122,7 +115,7 @@ export default function WalletConnectModal({

- Choose a wallet you want to connect to SkillNet + Choose your preferred wallet

@@ -133,9 +126,9 @@ export default function WalletConnectModal({ delay={index * 0.1} > diff --git a/src/app/components/walletProvider.tsx b/src/app/components/walletProvider.tsx index 976d146..07db231 100644 --- a/src/app/components/walletProvider.tsx +++ b/src/app/components/walletProvider.tsx @@ -5,7 +5,6 @@ import React, { useContext, ReactNode, useCallback, - useEffect, } from "react"; import { @@ -38,6 +37,7 @@ export const WalletProvider: React.FC<{ children: ReactNode }> = ({ const { connect, connectors, connectAsync } = useConnect(); const { address } = useAccount(); const { disconnect } = useDisconnect(); + // Accept a specific connector when connecting const connectWallet = useCallback( (connector: Connector) => { @@ -46,14 +46,6 @@ export const WalletProvider: React.FC<{ children: ReactNode }> = ({ [connect] ); - // Save wallet address to localStorage when connected - useEffect(() => { - if (address) { - localStorage.setItem("walletAddress", address); - } else { - localStorage.removeItem("walletAddress"); - } - }, [address]); return ( - {children} + + < WalletProvider> + {children} + + ); From 1fee1c78bdd00083ac4b84c9906dcd6851c7e052 Mon Sep 17 00:00:00 2001 From: yunusabdul Date: Tue, 6 May 2025 15:39:19 +0100 Subject: [PATCH 3/4] fix ci --- .github/workflows/ci.yml | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d10448c..569b026 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,22 +1,14 @@ - -name: Run Frontend Tests +name: Build Project on: [push, pull_request] - jobs: test: runs-on: ubuntu-latest + container: + image: node:20 steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Set up Node.js - uses: actions/setup-node@v3 + - uses: actions/checkout@v3 with: - node-version: "20" - - - name: Install dependencies - run: npm install --legacy-peer-deps - - - name: Run build - run: npm run build \ No newline at end of file + node-version: 20 + - run: npm ci + - run: npm run build \ No newline at end of file From 6f44a58166953655b38ad18fe3bab9fdffe4bc5b Mon Sep 17 00:00:00 2001 From: yunusabdul Date: Tue, 6 May 2025 15:41:27 +0100 Subject: [PATCH 4/4] fix ci --- .github/workflows/ci.yml | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 569b026..0187a55 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,14 +1,22 @@ -name: Build Project + +name: Run Frontend Tests on: [push, pull_request] + jobs: test: runs-on: ubuntu-latest - container: - image: node:20 steps: - - uses: actions/checkout@v3 + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set up Node.js + uses: actions/setup-node@v3 with: - node-version: 20 - - run: npm ci - - run: npm run build \ No newline at end of file + node-version: "20" + + - name: Install dependencies + run: npm install --force + + - name: Run build + run: npm run build \ No newline at end of file