diff --git a/package-lock.json b/package-lock.json index bf31450..9e97669 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,17 @@ { "name": "trustvc-website", - "version": "0.0.0", + "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "trustvc-website", - "version": "0.0.0", + "version": "1.0.0", "dependencies": { "@sanity/client": "^7.20.0", "@sanity/image-url": "^2.1.1", "@trustvc/decentralized-renderer-react-components": "^1.0.3", - "@trustvc/trustvc": "^2.8.0", + "@trustvc/trustvc": "^2.12.4", "@types/lodash": "^4.17.24", "clsx": "^2.1.1", "date-fns": "^4.1.0", @@ -5474,9 +5474,9 @@ } }, "node_modules/@tradetrust-tt/dnsprove": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/@tradetrust-tt/dnsprove/-/dnsprove-2.18.0.tgz", - "integrity": "sha512-UgcwV17hZSSBW5oDb+DUtXle5XdBRWXURSASkr207PYjCxZOhZV88KHJi3PB45UgtUCbtvrJK7czSsgDNnpRtg==", + "version": "2.21.0", + "resolved": "https://registry.npmjs.org/@tradetrust-tt/dnsprove/-/dnsprove-2.21.0.tgz", + "integrity": "sha512-acxJGS07WLfLDli1E4uvT5IbPcmh9vzVelgEdhxzi2KE50r3k/vvkwUQl1ctgkw152cIxnqR20cch8x3HLLvcw==", "license": "Apache-2.0", "dependencies": { "axios": "1.7.2", @@ -5487,15 +5487,6 @@ "node": ">=18.x" } }, - "node_modules/@tradetrust-tt/document-store": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@tradetrust-tt/document-store/-/document-store-4.1.1.tgz", - "integrity": "sha512-+gIR+icfbJOHVNXTc6D1Fo4jdwGRboZqUek/YN+ThXIaLaUP1dvD85tnEz63Nu4LfiDcjYld0aVXOfKsnCJ+yw==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.x" - } - }, "node_modules/@tradetrust-tt/ethers-aws-kms-signer": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@tradetrust-tt/ethers-aws-kms-signer/-/ethers-aws-kms-signer-2.1.4.tgz", @@ -5752,9 +5743,9 @@ } }, "node_modules/@tradetrust-tt/tradetrust": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/@tradetrust-tt/tradetrust/-/tradetrust-6.10.2.tgz", - "integrity": "sha512-4zj4zlsrrQiUJQxvl4N8Pa4cLHtFtFIs0lMg6daP/gRJXIn1QWD0Kl4mQ5FsjuopeM7JOBX/xok22SmElEtT5w==", + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/@tradetrust-tt/tradetrust/-/tradetrust-6.10.3.tgz", + "integrity": "sha512-2A/o6GguA31V7GnOfvhG1zANuxKdlBS5+k6jvAMeh/VotZEDvoOOA+mTArt5Fv+BKHhpgh7J8dS0DUohfVAiqg==", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { @@ -5846,6 +5837,7 @@ "version": "10.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -5856,9 +5848,9 @@ } }, "node_modules/@tradetrust-tt/tradetrust/node_modules/ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -5952,15 +5944,15 @@ } }, "node_modules/@tradetrust-tt/tt-verify": { - "version": "9.6.2", - "resolved": "https://registry.npmjs.org/@tradetrust-tt/tt-verify/-/tt-verify-9.6.2.tgz", - "integrity": "sha512-G6XB/fhzIDAc+p07/cDCVCNYgKxx9x5e2HwOORPS8kMkimoB4FXNoWlV8GMXcbzjIjU4frI2KEL54y8TA8+Wpw==", + "version": "9.7.2", + "resolved": "https://registry.npmjs.org/@tradetrust-tt/tt-verify/-/tt-verify-9.7.2.tgz", + "integrity": "sha512-LZvjF/1Lj0a0TwLiyRAhygVxe7jnwlmcDiaFu/rpiHCvwySUh5iehJeha0erpU7xeSyMZPRqeWOKQE3XXbtLRA==", "license": "Apache-2.0", "dependencies": { - "@tradetrust-tt/dnsprove": "^2.18.0", - "@tradetrust-tt/document-store": "^4.1.1", + "@tradetrust-tt/dnsprove": "^2.20.0", "@tradetrust-tt/token-registry": "^5.5.0", - "@tradetrust-tt/tradetrust": "^6.10.1", + "@tradetrust-tt/tradetrust": "^6.10.3", + "@trustvc/document-store": "^1.0.3", "axios": "^1.7.2", "debug": "^4.3.1", "did-resolver": "^3.1.0", @@ -5968,13 +5960,32 @@ "ethr-did-resolver": "^4.3.3", "node-cache": "^5.1.2", "runtypes": "^6.3.0", - "web-did-resolver": "^2.0.4" + "web-did-resolver": "2.0.4" }, "engines": { "node": ">=18.x" }, "peerDependencies": { - "ethers": "^5.7.2" + "ethers": "^5.8.0" + } + }, + "node_modules/@tradetrust-tt/tt-verify/node_modules/cross-fetch": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz", + "integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==", + "license": "MIT", + "dependencies": { + "node-fetch": "^2.7.0" + } + }, + "node_modules/@tradetrust-tt/tt-verify/node_modules/web-did-resolver": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/web-did-resolver/-/web-did-resolver-2.0.4.tgz", + "integrity": "sha512-PORpoA4P0I3m0cLJX2IIDZ0gMKgC1PjS8DuDeg9/JCdIlFiXrZCyTG1hxvw4a4vhDKr0sZKSZL1pQDXTgqLm8w==", + "license": "Apache-2.0", + "dependencies": { + "cross-fetch": "^3.1.2", + "did-resolver": "^3.1.0" } }, "node_modules/@trustvc/decentralized-renderer-react-components": { @@ -6015,17 +6026,17 @@ "license": "Apache-2.0" }, "node_modules/@trustvc/trustvc": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@trustvc/trustvc/-/trustvc-2.8.0.tgz", - "integrity": "sha512-9ALOVQkkNFc7Ngx/Lm/FMP6kqWpWI6wTSSNeDrb81vaRl51uQ8RcUW4ErFHNrfGJkiR0WrjxnGEHNRFSnWlYtw==", + "version": "2.12.4", + "resolved": "https://registry.npmjs.org/@trustvc/trustvc/-/trustvc-2.12.4.tgz", + "integrity": "sha512-9Ff/BuXmT5guZBjBLtEXNynCHnxLeH7awsS8/LMoZSPXcFczk8vAAFtx+4iTEBv2mRXQ3hZpe+T4zoueSe/gxQ==", "license": "Apache-2.0", "dependencies": { "@tradetrust-tt/dnsprove": "^2.18.0", "@tradetrust-tt/ethers-aws-kms-signer": "^2.1.4", "@tradetrust-tt/token-registry-v4": "npm:@tradetrust-tt/token-registry@^4.16.0", "@tradetrust-tt/token-registry-v5": "npm:@tradetrust-tt/token-registry@^5.5.0", - "@tradetrust-tt/tradetrust": "^6.10.2", - "@tradetrust-tt/tt-verify": "^9.6.0", + "@tradetrust-tt/tradetrust": "^6.10.3", + "@tradetrust-tt/tt-verify": "^9.7.2", "@trustvc/document-store": "^1.0.3", "@trustvc/w3c": "^2.0.0", "@trustvc/w3c-context": "^2.0.0", @@ -6036,6 +6047,7 @@ "ethersV6": "npm:ethers@^6.14.4", "js-sha3": "^0.9.3", "node-fetch": "^2.7.0", + "node-forge": "^1.3.3", "ts-chacha20": "^1.2.0" }, "engines": { @@ -6061,6 +6073,15 @@ "linux" ] }, + "node_modules/@trustvc/trustvc/node_modules/node-forge": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz", + "integrity": "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==", + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, "node_modules/@trustvc/w3c": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@trustvc/w3c/-/w3c-2.0.2.tgz", @@ -7163,9 +7184,9 @@ } }, "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -10294,9 +10315,9 @@ "dev": true }, "node_modules/fast-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", + "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", "funding": [ { "type": "github", @@ -17836,6 +17857,7 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -17882,9 +17904,9 @@ } }, "node_modules/validator": { - "version": "13.15.26", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.26.tgz", - "integrity": "sha512-spH26xU080ydGggxRyR1Yhcbgx+j3y5jbNXk/8L+iRvdIEQ4uTRH2Sgf2dokud6Q4oAtsbNvJ1Ft+9xmm6IZcA==", + "version": "13.15.35", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.35.tgz", + "integrity": "sha512-TQ5pAGhd5whStmqWvYF4OjQROlmv9SMFVt37qoCBdqRffuuklWYQlCNnEs2ZaIBD1kZRNnikiZOS1eqgkar0iw==", "license": "MIT", "engines": { "node": ">= 0.10" diff --git a/package.json b/package.json index 3924ab2..6cc9c2e 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "@sanity/client": "^7.20.0", "@sanity/image-url": "^2.1.1", "@trustvc/decentralized-renderer-react-components": "^1.0.3", - "@trustvc/trustvc": "^2.8.0", + "@trustvc/trustvc": "^2.12.4", "@types/lodash": "^4.17.24", "clsx": "^2.1.1", "date-fns": "^4.1.0", diff --git a/public/images/about/center-image.svg b/public/images/about/center-image.svg new file mode 100644 index 0000000..58edcfb --- /dev/null +++ b/public/images/about/center-image.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/about/ecosystem.svg b/public/images/about/ecosystem.svg new file mode 100644 index 0000000..6a597ef --- /dev/null +++ b/public/images/about/ecosystem.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/about/frame-bottom.svg b/public/images/about/frame-bottom.svg new file mode 100644 index 0000000..00d4655 --- /dev/null +++ b/public/images/about/frame-bottom.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/about/frame-top.svg b/public/images/about/frame-top.svg new file mode 100644 index 0000000..4b5dcfe --- /dev/null +++ b/public/images/about/frame-top.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/about/global.svg b/public/images/about/global.svg new file mode 100644 index 0000000..1979173 --- /dev/null +++ b/public/images/about/global.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/about/privacy.svg b/public/images/about/privacy.svg new file mode 100644 index 0000000..abf2e42 --- /dev/null +++ b/public/images/about/privacy.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/about/single-source.svg b/public/images/about/single-source.svg new file mode 100644 index 0000000..ffa86b4 --- /dev/null +++ b/public/images/about/single-source.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/about/tamper.svg b/public/images/about/tamper.svg new file mode 100644 index 0000000..2e027cb --- /dev/null +++ b/public/images/about/tamper.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/about/unified-foundation.svg b/public/images/about/unified-foundation.svg new file mode 100644 index 0000000..372d2ac --- /dev/null +++ b/public/images/about/unified-foundation.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/partners/1X/Banner/AEOTRADE.png b/public/images/partners/1X/Banner/AEOTRADE.png new file mode 100644 index 0000000..2997b1e Binary files /dev/null and b/public/images/partners/1X/Banner/AEOTRADE.png differ diff --git a/public/images/partners/1X/Banner/ASTROn.png b/public/images/partners/1X/Banner/ASTROn.png new file mode 100644 index 0000000..059457c Binary files /dev/null and b/public/images/partners/1X/Banner/ASTROn.png differ diff --git a/public/images/partners/1X/Banner/Angsana Technology.png b/public/images/partners/1X/Banner/Angsana Technology.png new file mode 100644 index 0000000..0394d78 Binary files /dev/null and b/public/images/partners/1X/Banner/Angsana Technology.png differ diff --git a/public/images/partners/1X/Banner/Automaxis.png b/public/images/partners/1X/Banner/Automaxis.png new file mode 100644 index 0000000..41e2daf Binary files /dev/null and b/public/images/partners/1X/Banner/Automaxis.png differ diff --git a/public/images/partners/1X/Banner/Banco.png b/public/images/partners/1X/Banner/Banco.png new file mode 100644 index 0000000..05a2d94 Binary files /dev/null and b/public/images/partners/1X/Banner/Banco.png differ diff --git a/public/images/partners/1X/Banner/Bank of China.png b/public/images/partners/1X/Banner/Bank of China.png new file mode 100644 index 0000000..f173789 Binary files /dev/null and b/public/images/partners/1X/Banner/Bank of China.png differ diff --git a/public/images/partners/1X/Banner/BlockPeer.png b/public/images/partners/1X/Banner/BlockPeer.png new file mode 100644 index 0000000..52e60ca Binary files /dev/null and b/public/images/partners/1X/Banner/BlockPeer.png differ diff --git a/public/images/partners/1X/Banner/BunkerChain.png b/public/images/partners/1X/Banner/BunkerChain.png new file mode 100644 index 0000000..e7df95a Binary files /dev/null and b/public/images/partners/1X/Banner/BunkerChain.png differ diff --git a/public/images/partners/1X/Banner/CALISTA.png b/public/images/partners/1X/Banner/CALISTA.png new file mode 100644 index 0000000..ab570fc Binary files /dev/null and b/public/images/partners/1X/Banner/CALISTA.png differ diff --git a/public/images/partners/1X/Banner/COFCO.png b/public/images/partners/1X/Banner/COFCO.png new file mode 100644 index 0000000..124ed0f Binary files /dev/null and b/public/images/partners/1X/Banner/COFCO.png differ diff --git a/public/images/partners/1X/Banner/CargoX.png b/public/images/partners/1X/Banner/CargoX.png new file mode 100644 index 0000000..636b419 Binary files /dev/null and b/public/images/partners/1X/Banner/CargoX.png differ diff --git a/public/images/partners/1X/Banner/ChainDoX.png b/public/images/partners/1X/Banner/ChainDoX.png new file mode 100644 index 0000000..3155e58 Binary files /dev/null and b/public/images/partners/1X/Banner/ChainDoX.png differ diff --git a/public/images/partners/1X/Banner/Credore.png b/public/images/partners/1X/Banner/Credore.png new file mode 100644 index 0000000..1fabf91 Binary files /dev/null and b/public/images/partners/1X/Banner/Credore.png differ diff --git a/public/images/partners/1X/Banner/DBS Group.png b/public/images/partners/1X/Banner/DBS Group.png new file mode 100644 index 0000000..27c5174 Binary files /dev/null and b/public/images/partners/1X/Banner/DBS Group.png differ diff --git a/public/images/partners/1X/Banner/DIMUTO.png b/public/images/partners/1X/Banner/DIMUTO.png new file mode 100644 index 0000000..b3366b7 Binary files /dev/null and b/public/images/partners/1X/Banner/DIMUTO.png differ diff --git a/public/images/partners/1X/Banner/DLTLedgers.png b/public/images/partners/1X/Banner/DLTLedgers.png new file mode 100644 index 0000000..5697fdd Binary files /dev/null and b/public/images/partners/1X/Banner/DLTLedgers.png differ diff --git a/public/images/partners/1X/Banner/DOCKLAB.png b/public/images/partners/1X/Banner/DOCKLAB.png new file mode 100644 index 0000000..19ce1b1 Binary files /dev/null and b/public/images/partners/1X/Banner/DOCKLAB.png differ diff --git a/public/images/partners/1X/Banner/Docsonblocks.png b/public/images/partners/1X/Banner/Docsonblocks.png new file mode 100644 index 0000000..ac8e730 Binary files /dev/null and b/public/images/partners/1X/Banner/Docsonblocks.png differ diff --git a/public/images/partners/1X/Banner/DocuShield.png b/public/images/partners/1X/Banner/DocuShield.png new file mode 100644 index 0000000..40cbcd9 Binary files /dev/null and b/public/images/partners/1X/Banner/DocuShield.png differ diff --git a/public/images/partners/1X/Banner/DocuTrade.png b/public/images/partners/1X/Banner/DocuTrade.png new file mode 100644 index 0000000..dd733b2 Binary files /dev/null and b/public/images/partners/1X/Banner/DocuTrade.png differ diff --git a/public/images/partners/1X/Banner/FUIX LABS.png b/public/images/partners/1X/Banner/FUIX LABS.png new file mode 100644 index 0000000..c09b50c Binary files /dev/null and b/public/images/partners/1X/Banner/FUIX LABS.png differ diff --git a/public/images/partners/1X/Banner/FilPass.png b/public/images/partners/1X/Banner/FilPass.png new file mode 100644 index 0000000..783bcc8 Binary files /dev/null and b/public/images/partners/1X/Banner/FilPass.png differ diff --git a/public/images/partners/1X/Banner/GUUD.png b/public/images/partners/1X/Banner/GUUD.png new file mode 100644 index 0000000..802636c Binary files /dev/null and b/public/images/partners/1X/Banner/GUUD.png differ diff --git a/public/images/partners/1X/Banner/ICICI Bank.png b/public/images/partners/1X/Banner/ICICI Bank.png new file mode 100644 index 0000000..2b9e1b4 Binary files /dev/null and b/public/images/partners/1X/Banner/ICICI Bank.png differ diff --git a/public/images/partners/1X/Banner/Institute of Technical Education.png b/public/images/partners/1X/Banner/Institute of Technical Education.png new file mode 100644 index 0000000..9b9f838 Binary files /dev/null and b/public/images/partners/1X/Banner/Institute of Technical Education.png differ diff --git a/public/images/partners/1X/Banner/JSLA.png b/public/images/partners/1X/Banner/JSLA.png new file mode 100644 index 0000000..f528619 Binary files /dev/null and b/public/images/partners/1X/Banner/JSLA.png differ diff --git a/public/images/partners/1X/Banner/JUPYTON.png b/public/images/partners/1X/Banner/JUPYTON.png new file mode 100644 index 0000000..2fc965d Binary files /dev/null and b/public/images/partners/1X/Banner/JUPYTON.png differ diff --git a/public/images/partners/1X/Banner/Jed.png b/public/images/partners/1X/Banner/Jed.png new file mode 100644 index 0000000..cd8354b Binary files /dev/null and b/public/images/partners/1X/Banner/Jed.png differ diff --git a/public/images/partners/1X/Banner/LASALLE College of the Arts.png b/public/images/partners/1X/Banner/LASALLE College of the Arts.png new file mode 100644 index 0000000..be4b7c9 Binary files /dev/null and b/public/images/partners/1X/Banner/LASALLE College of the Arts.png differ diff --git a/public/images/partners/1X/Banner/Linklogis.png b/public/images/partners/1X/Banner/Linklogis.png new file mode 100644 index 0000000..e13a48e Binary files /dev/null and b/public/images/partners/1X/Banner/Linklogis.png differ diff --git a/public/images/partners/1X/Banner/MAPTRASCO.png b/public/images/partners/1X/Banner/MAPTRASCO.png new file mode 100644 index 0000000..55ec2fe Binary files /dev/null and b/public/images/partners/1X/Banner/MAPTRASCO.png differ diff --git a/public/images/partners/1X/Banner/Morpheus.Network.png b/public/images/partners/1X/Banner/Morpheus.Network.png new file mode 100644 index 0000000..4d91bee Binary files /dev/null and b/public/images/partners/1X/Banner/Morpheus.Network.png differ diff --git a/public/images/partners/1X/Banner/NAFA.png b/public/images/partners/1X/Banner/NAFA.png new file mode 100644 index 0000000..c7870d8 Binary files /dev/null and b/public/images/partners/1X/Banner/NAFA.png differ diff --git a/public/images/partners/1X/Banner/NIEC.png b/public/images/partners/1X/Banner/NIEC.png new file mode 100644 index 0000000..f087157 Binary files /dev/null and b/public/images/partners/1X/Banner/NIEC.png differ diff --git a/public/images/partners/1X/Banner/Nanyang Polytechnic.png b/public/images/partners/1X/Banner/Nanyang Polytechnic.png new file mode 100644 index 0000000..15ff1de Binary files /dev/null and b/public/images/partners/1X/Banner/Nanyang Polytechnic.png differ diff --git a/public/images/partners/1X/Banner/National University of Singapore.png b/public/images/partners/1X/Banner/National University of Singapore.png new file mode 100644 index 0000000..82aa455 Binary files /dev/null and b/public/images/partners/1X/Banner/National University of Singapore.png differ diff --git a/public/images/partners/1X/Banner/Ngee Ann Polytechnic.png b/public/images/partners/1X/Banner/Ngee Ann Polytechnic.png new file mode 100644 index 0000000..379020f Binary files /dev/null and b/public/images/partners/1X/Banner/Ngee Ann Polytechnic.png differ diff --git a/public/images/partners/1X/Banner/Pacific International Lines.png b/public/images/partners/1X/Banner/Pacific International Lines.png new file mode 100644 index 0000000..13a5297 Binary files /dev/null and b/public/images/partners/1X/Banner/Pacific International Lines.png differ diff --git a/public/images/partners/1X/Banner/Republic Polytechnic.png b/public/images/partners/1X/Banner/Republic Polytechnic.png new file mode 100644 index 0000000..6811f70 Binary files /dev/null and b/public/images/partners/1X/Banner/Republic Polytechnic.png differ diff --git a/public/images/partners/1X/Banner/SECRO.png b/public/images/partners/1X/Banner/SECRO.png new file mode 100644 index 0000000..056780e Binary files /dev/null and b/public/images/partners/1X/Banner/SECRO.png differ diff --git a/public/images/partners/1X/Banner/SGTraDex.png b/public/images/partners/1X/Banner/SGTraDex.png new file mode 100644 index 0000000..ec8d718 Binary files /dev/null and b/public/images/partners/1X/Banner/SGTraDex.png differ diff --git a/public/images/partners/1X/Banner/SMU.png b/public/images/partners/1X/Banner/SMU.png new file mode 100644 index 0000000..c015cfb Binary files /dev/null and b/public/images/partners/1X/Banner/SMU.png differ diff --git a/public/images/partners/1X/Banner/STABILITY.png b/public/images/partners/1X/Banner/STABILITY.png new file mode 100644 index 0000000..e876118 Binary files /dev/null and b/public/images/partners/1X/Banner/STABILITY.png differ diff --git a/public/images/partners/1X/Banner/Singapore Examinations and Assessment Board.png b/public/images/partners/1X/Banner/Singapore Examinations and Assessment Board.png new file mode 100644 index 0000000..347e38e Binary files /dev/null and b/public/images/partners/1X/Banner/Singapore Examinations and Assessment Board.png differ diff --git a/public/images/partners/1X/Banner/Singapore Polytechnic.png b/public/images/partners/1X/Banner/Singapore Polytechnic.png new file mode 100644 index 0000000..0e9bc88 Binary files /dev/null and b/public/images/partners/1X/Banner/Singapore Polytechnic.png differ diff --git a/public/images/partners/1X/Banner/Singapore University of Social Sciences.png b/public/images/partners/1X/Banner/Singapore University of Social Sciences.png new file mode 100644 index 0000000..8ade537 Binary files /dev/null and b/public/images/partners/1X/Banner/Singapore University of Social Sciences.png differ diff --git a/public/images/partners/1X/Banner/SkillsFuture SG.png b/public/images/partners/1X/Banner/SkillsFuture SG.png new file mode 100644 index 0000000..7368308 Binary files /dev/null and b/public/images/partners/1X/Banner/SkillsFuture SG.png differ diff --git a/public/images/partners/1X/Banner/TASConnect.png b/public/images/partners/1X/Banner/TASConnect.png new file mode 100644 index 0000000..8d31bf0 Binary files /dev/null and b/public/images/partners/1X/Banner/TASConnect.png differ diff --git "a/public/images/partners/1X/Banner/TRAM\303\211S.png" "b/public/images/partners/1X/Banner/TRAM\303\211S.png" new file mode 100644 index 0000000..43bbe8e Binary files /dev/null and "b/public/images/partners/1X/Banner/TRAM\303\211S.png" differ diff --git a/public/images/partners/1X/Banner/Temasek Polytechnic.png b/public/images/partners/1X/Banner/Temasek Polytechnic.png new file mode 100644 index 0000000..66fb0bc Binary files /dev/null and b/public/images/partners/1X/Banner/Temasek Polytechnic.png differ diff --git a/public/images/partners/1X/Banner/TradeGo.png b/public/images/partners/1X/Banner/TradeGo.png new file mode 100644 index 0000000..444aab4 Binary files /dev/null and b/public/images/partners/1X/Banner/TradeGo.png differ diff --git a/public/images/partners/1X/Banner/UOB.png b/public/images/partners/1X/Banner/UOB.png new file mode 100644 index 0000000..beb071c Binary files /dev/null and b/public/images/partners/1X/Banner/UOB.png differ diff --git a/public/images/partners/1X/Banner/VAYANA.png b/public/images/partners/1X/Banner/VAYANA.png new file mode 100644 index 0000000..f2e4a81 Binary files /dev/null and b/public/images/partners/1X/Banner/VAYANA.png differ diff --git a/public/images/partners/1X/Banner/XDC Network.png b/public/images/partners/1X/Banner/XDC Network.png new file mode 100644 index 0000000..1701695 Binary files /dev/null and b/public/images/partners/1X/Banner/XDC Network.png differ diff --git a/public/images/partners/1X/Banner/YIT HONG PTE LTD.png b/public/images/partners/1X/Banner/YIT HONG PTE LTD.png new file mode 100644 index 0000000..a2e06ef Binary files /dev/null and b/public/images/partners/1X/Banner/YIT HONG PTE LTD.png differ diff --git a/public/images/partners/1X/Banner/ZenithBlox.png b/public/images/partners/1X/Banner/ZenithBlox.png new file mode 100644 index 0000000..4dd54b3 Binary files /dev/null and b/public/images/partners/1X/Banner/ZenithBlox.png differ diff --git a/public/images/partners/1X/Banner/eTEU.png b/public/images/partners/1X/Banner/eTEU.png new file mode 100644 index 0000000..db34108 Binary files /dev/null and b/public/images/partners/1X/Banner/eTEU.png differ diff --git a/public/images/partners/1X/Banner/veriTAG.png b/public/images/partners/1X/Banner/veriTAG.png new file mode 100644 index 0000000..9c301b1 Binary files /dev/null and b/public/images/partners/1X/Banner/veriTAG.png differ diff --git a/public/images/partners/1X/Card/Infrastructure/TradeTrust/ASTROn.png b/public/images/partners/1X/Card/Infrastructure/TradeTrust/ASTROn.png new file mode 100644 index 0000000..52c77e8 Binary files /dev/null and b/public/images/partners/1X/Card/Infrastructure/TradeTrust/ASTROn.png differ diff --git a/public/images/partners/1X/Card/Infrastructure/TradeTrust/DLTLedgers.png b/public/images/partners/1X/Card/Infrastructure/TradeTrust/DLTLedgers.png new file mode 100644 index 0000000..d56a4d1 Binary files /dev/null and b/public/images/partners/1X/Card/Infrastructure/TradeTrust/DLTLedgers.png differ diff --git a/public/images/partners/1X/Card/Infrastructure/TradeTrust/STABILITY.png b/public/images/partners/1X/Card/Infrastructure/TradeTrust/STABILITY.png new file mode 100644 index 0000000..b7c490c Binary files /dev/null and b/public/images/partners/1X/Card/Infrastructure/TradeTrust/STABILITY.png differ diff --git a/public/images/partners/1X/Card/Infrastructure/TradeTrust/XDC Network.png b/public/images/partners/1X/Card/Infrastructure/TradeTrust/XDC Network.png new file mode 100644 index 0000000..f3e24d1 Binary files /dev/null and b/public/images/partners/1X/Card/Infrastructure/TradeTrust/XDC Network.png differ diff --git a/public/images/partners/1X/Card/Issuance Attestation/OpenCert/Institute of Technical Education.png b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/Institute of Technical Education.png new file mode 100644 index 0000000..1d3cbb6 Binary files /dev/null and b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/Institute of Technical Education.png differ diff --git a/public/images/partners/1X/Card/Issuance Attestation/OpenCert/LASALLE College of the Arts.png b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/LASALLE College of the Arts.png new file mode 100644 index 0000000..cb61591 Binary files /dev/null and b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/LASALLE College of the Arts.png differ diff --git a/public/images/partners/1X/Card/Issuance Attestation/OpenCert/NAFA.png b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/NAFA.png new file mode 100644 index 0000000..d2adf57 Binary files /dev/null and b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/NAFA.png differ diff --git a/public/images/partners/1X/Card/Issuance Attestation/OpenCert/NIEC.png b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/NIEC.png new file mode 100644 index 0000000..4d5a8d2 Binary files /dev/null and b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/NIEC.png differ diff --git a/public/images/partners/1X/Card/Issuance Attestation/OpenCert/Nanyang Polytechnic.png b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/Nanyang Polytechnic.png new file mode 100644 index 0000000..4aa27bc Binary files /dev/null and b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/Nanyang Polytechnic.png differ diff --git a/public/images/partners/1X/Card/Issuance Attestation/OpenCert/National University of Singapore.png b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/National University of Singapore.png new file mode 100644 index 0000000..a582453 Binary files /dev/null and b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/National University of Singapore.png differ diff --git a/public/images/partners/1X/Card/Issuance Attestation/OpenCert/Ngee Ann Polytechnic.png b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/Ngee Ann Polytechnic.png new file mode 100644 index 0000000..eac10b2 Binary files /dev/null and b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/Ngee Ann Polytechnic.png differ diff --git a/public/images/partners/1X/Card/Issuance Attestation/OpenCert/Republic Polytechnic.png b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/Republic Polytechnic.png new file mode 100644 index 0000000..d9486c2 Binary files /dev/null and b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/Republic Polytechnic.png differ diff --git a/public/images/partners/1X/Card/Issuance Attestation/OpenCert/SMU.png b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/SMU.png new file mode 100644 index 0000000..7ec650c Binary files /dev/null and b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/SMU.png differ diff --git a/public/images/partners/1X/Card/Issuance Attestation/OpenCert/Singapore Examinations and Assessment Board.png b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/Singapore Examinations and Assessment Board.png new file mode 100644 index 0000000..7497d3b Binary files /dev/null and b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/Singapore Examinations and Assessment Board.png differ diff --git a/public/images/partners/1X/Card/Issuance Attestation/OpenCert/Singapore Polytechnic.png b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/Singapore Polytechnic.png new file mode 100644 index 0000000..523571b Binary files /dev/null and b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/Singapore Polytechnic.png differ diff --git a/public/images/partners/1X/Card/Issuance Attestation/OpenCert/Singapore University of Social Sciences.png b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/Singapore University of Social Sciences.png new file mode 100644 index 0000000..8cedd2c Binary files /dev/null and b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/Singapore University of Social Sciences.png differ diff --git a/public/images/partners/1X/Card/Issuance Attestation/OpenCert/SkillsFuture SG.png b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/SkillsFuture SG.png new file mode 100644 index 0000000..7dc114b Binary files /dev/null and b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/SkillsFuture SG.png differ diff --git a/public/images/partners/1X/Card/Issuance Attestation/OpenCert/Temasek Polytechnic.png b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/Temasek Polytechnic.png new file mode 100644 index 0000000..812f1a3 Binary files /dev/null and b/public/images/partners/1X/Card/Issuance Attestation/OpenCert/Temasek Polytechnic.png differ diff --git a/public/images/partners/1X/Card/Issuance Attestation/TradeTrust/COFCO.png b/public/images/partners/1X/Card/Issuance Attestation/TradeTrust/COFCO.png new file mode 100644 index 0000000..10b8e47 Binary files /dev/null and b/public/images/partners/1X/Card/Issuance Attestation/TradeTrust/COFCO.png differ diff --git a/public/images/partners/1X/Card/Issuance Attestation/TradeTrust/ICICI Bank.png b/public/images/partners/1X/Card/Issuance Attestation/TradeTrust/ICICI Bank.png new file mode 100644 index 0000000..aeca911 Binary files /dev/null and b/public/images/partners/1X/Card/Issuance Attestation/TradeTrust/ICICI Bank.png differ diff --git a/public/images/partners/1X/Card/Issuance Attestation/TradeTrust/JSLA.png b/public/images/partners/1X/Card/Issuance Attestation/TradeTrust/JSLA.png new file mode 100644 index 0000000..79ced58 Binary files /dev/null and b/public/images/partners/1X/Card/Issuance Attestation/TradeTrust/JSLA.png differ diff --git a/public/images/partners/1X/Card/Issuance Attestation/TradeTrust/MAPTRASCO.png b/public/images/partners/1X/Card/Issuance Attestation/TradeTrust/MAPTRASCO.png new file mode 100644 index 0000000..a17b52c Binary files /dev/null and b/public/images/partners/1X/Card/Issuance Attestation/TradeTrust/MAPTRASCO.png differ diff --git a/public/images/partners/1X/Card/Issuance Attestation/TradeTrust/Pacific International Lines.png b/public/images/partners/1X/Card/Issuance Attestation/TradeTrust/Pacific International Lines.png new file mode 100644 index 0000000..ddde4df Binary files /dev/null and b/public/images/partners/1X/Card/Issuance Attestation/TradeTrust/Pacific International Lines.png differ diff --git a/public/images/partners/1X/Card/Issuance Attestation/TradeTrust/YIT HONG PTE LTD.png b/public/images/partners/1X/Card/Issuance Attestation/TradeTrust/YIT HONG PTE LTD.png new file mode 100644 index 0000000..1656a2c Binary files /dev/null and b/public/images/partners/1X/Card/Issuance Attestation/TradeTrust/YIT HONG PTE LTD.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/AEOTRADE.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/AEOTRADE.png new file mode 100644 index 0000000..5c3ddd8 Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/AEOTRADE.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/Angsana Technology.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/Angsana Technology.png new file mode 100644 index 0000000..2e282c4 Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/Angsana Technology.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/Automaxis.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/Automaxis.png new file mode 100644 index 0000000..2a39daf Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/Automaxis.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/Banco.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/Banco.png new file mode 100644 index 0000000..b5b9dcf Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/Banco.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/BlockPeer.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/BlockPeer.png new file mode 100644 index 0000000..15018d5 Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/BlockPeer.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/BunkerChain.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/BunkerChain.png new file mode 100644 index 0000000..68d0207 Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/BunkerChain.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/CALISTA.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/CALISTA.png new file mode 100644 index 0000000..353c320 Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/CALISTA.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/CargoX.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/CargoX.png new file mode 100644 index 0000000..3f0691c Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/CargoX.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/ChainDoX.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/ChainDoX.png new file mode 100644 index 0000000..b45caa1 Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/ChainDoX.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/Credore.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/Credore.png new file mode 100644 index 0000000..7623088 Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/Credore.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/DIMUTO.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/DIMUTO.png new file mode 100644 index 0000000..efa3e46 Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/DIMUTO.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/DOCKLAB.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/DOCKLAB.png new file mode 100644 index 0000000..d94bff7 Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/DOCKLAB.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/Docsonblocks.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/Docsonblocks.png new file mode 100644 index 0000000..acdb423 Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/Docsonblocks.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/DocuShield.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/DocuShield.png new file mode 100644 index 0000000..8189155 Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/DocuShield.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/DocuTrade.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/DocuTrade.png new file mode 100644 index 0000000..040a9f7 Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/DocuTrade.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/FUIX LABS.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/FUIX LABS.png new file mode 100644 index 0000000..9358027 Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/FUIX LABS.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/FilPass.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/FilPass.png new file mode 100644 index 0000000..5d8533e Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/FilPass.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/GUUD.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/GUUD.png new file mode 100644 index 0000000..438841d Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/GUUD.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/JUPYTON.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/JUPYTON.png new file mode 100644 index 0000000..b5ee969 Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/JUPYTON.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/Jed.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/Jed.png new file mode 100644 index 0000000..6f70bd0 Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/Jed.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/Linklogis.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/Linklogis.png new file mode 100644 index 0000000..2b97501 Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/Linklogis.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/Morpheus.Network.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/Morpheus.Network.png new file mode 100644 index 0000000..c095462 Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/Morpheus.Network.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/SECRO.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/SECRO.png new file mode 100644 index 0000000..4c1caec Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/SECRO.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/SGTraDex.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/SGTraDex.png new file mode 100644 index 0000000..9d67dc1 Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/SGTraDex.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/TASConnect.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/TASConnect.png new file mode 100644 index 0000000..88be89c Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/TASConnect.png differ diff --git "a/public/images/partners/1X/Card/Solution Providers/TradeTrust/TRAM\303\211S.png" "b/public/images/partners/1X/Card/Solution Providers/TradeTrust/TRAM\303\211S.png" new file mode 100644 index 0000000..c99bf01 Binary files /dev/null and "b/public/images/partners/1X/Card/Solution Providers/TradeTrust/TRAM\303\211S.png" differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/TradeGo.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/TradeGo.png new file mode 100644 index 0000000..9c9aebc Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/TradeGo.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/VAYANA.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/VAYANA.png new file mode 100644 index 0000000..5259b90 Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/VAYANA.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/ZenithBlox.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/ZenithBlox.png new file mode 100644 index 0000000..37d0d5c Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/ZenithBlox.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/eTEU.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/eTEU.png new file mode 100644 index 0000000..dfd48f4 Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/eTEU.png differ diff --git a/public/images/partners/1X/Card/Solution Providers/TradeTrust/veriTAG.png b/public/images/partners/1X/Card/Solution Providers/TradeTrust/veriTAG.png new file mode 100644 index 0000000..a369b1d Binary files /dev/null and b/public/images/partners/1X/Card/Solution Providers/TradeTrust/veriTAG.png differ diff --git a/public/images/partners/1X/Card/Verification Validation/TradeTrust/Bank of China.png b/public/images/partners/1X/Card/Verification Validation/TradeTrust/Bank of China.png new file mode 100644 index 0000000..510f811 Binary files /dev/null and b/public/images/partners/1X/Card/Verification Validation/TradeTrust/Bank of China.png differ diff --git a/public/images/partners/1X/Card/Verification Validation/TradeTrust/DBS Group.png b/public/images/partners/1X/Card/Verification Validation/TradeTrust/DBS Group.png new file mode 100644 index 0000000..7875543 Binary files /dev/null and b/public/images/partners/1X/Card/Verification Validation/TradeTrust/DBS Group.png differ diff --git a/public/images/partners/1X/Card/Verification Validation/TradeTrust/UOB.png b/public/images/partners/1X/Card/Verification Validation/TradeTrust/UOB.png new file mode 100644 index 0000000..1987d1a Binary files /dev/null and b/public/images/partners/1X/Card/Verification Validation/TradeTrust/UOB.png differ diff --git a/public/images/partners/2X/Banner/AEOTRADE.png b/public/images/partners/2X/Banner/AEOTRADE.png new file mode 100644 index 0000000..cd289cf Binary files /dev/null and b/public/images/partners/2X/Banner/AEOTRADE.png differ diff --git a/public/images/partners/2X/Banner/ASTROn.png b/public/images/partners/2X/Banner/ASTROn.png new file mode 100644 index 0000000..120e7b6 Binary files /dev/null and b/public/images/partners/2X/Banner/ASTROn.png differ diff --git a/public/images/partners/2X/Banner/Angsana Technology.png b/public/images/partners/2X/Banner/Angsana Technology.png new file mode 100644 index 0000000..ba71b97 Binary files /dev/null and b/public/images/partners/2X/Banner/Angsana Technology.png differ diff --git a/public/images/partners/2X/Banner/Automaxis.png b/public/images/partners/2X/Banner/Automaxis.png new file mode 100644 index 0000000..147e26c Binary files /dev/null and b/public/images/partners/2X/Banner/Automaxis.png differ diff --git a/public/images/partners/2X/Banner/Banco.png b/public/images/partners/2X/Banner/Banco.png new file mode 100644 index 0000000..2996b95 Binary files /dev/null and b/public/images/partners/2X/Banner/Banco.png differ diff --git a/public/images/partners/2X/Banner/Bank of China.png b/public/images/partners/2X/Banner/Bank of China.png new file mode 100644 index 0000000..cc54d9d Binary files /dev/null and b/public/images/partners/2X/Banner/Bank of China.png differ diff --git a/public/images/partners/2X/Banner/BlockPeer.png b/public/images/partners/2X/Banner/BlockPeer.png new file mode 100644 index 0000000..c24ffd8 Binary files /dev/null and b/public/images/partners/2X/Banner/BlockPeer.png differ diff --git a/public/images/partners/2X/Banner/BunkerChain.png b/public/images/partners/2X/Banner/BunkerChain.png new file mode 100644 index 0000000..39ee9a0 Binary files /dev/null and b/public/images/partners/2X/Banner/BunkerChain.png differ diff --git a/public/images/partners/2X/Banner/CALISTA.png b/public/images/partners/2X/Banner/CALISTA.png new file mode 100644 index 0000000..8ef36c5 Binary files /dev/null and b/public/images/partners/2X/Banner/CALISTA.png differ diff --git a/public/images/partners/2X/Banner/COFCO.png b/public/images/partners/2X/Banner/COFCO.png new file mode 100644 index 0000000..f52a42c Binary files /dev/null and b/public/images/partners/2X/Banner/COFCO.png differ diff --git a/public/images/partners/2X/Banner/CargoX.png b/public/images/partners/2X/Banner/CargoX.png new file mode 100644 index 0000000..aa191b0 Binary files /dev/null and b/public/images/partners/2X/Banner/CargoX.png differ diff --git a/public/images/partners/2X/Banner/ChainDoX.png b/public/images/partners/2X/Banner/ChainDoX.png new file mode 100644 index 0000000..2051533 Binary files /dev/null and b/public/images/partners/2X/Banner/ChainDoX.png differ diff --git a/public/images/partners/2X/Banner/Credore.png b/public/images/partners/2X/Banner/Credore.png new file mode 100644 index 0000000..eb250b3 Binary files /dev/null and b/public/images/partners/2X/Banner/Credore.png differ diff --git a/public/images/partners/2X/Banner/DBS Group.png b/public/images/partners/2X/Banner/DBS Group.png new file mode 100644 index 0000000..a8d47d9 Binary files /dev/null and b/public/images/partners/2X/Banner/DBS Group.png differ diff --git a/public/images/partners/2X/Banner/DIMUTO.png b/public/images/partners/2X/Banner/DIMUTO.png new file mode 100644 index 0000000..dc19d77 Binary files /dev/null and b/public/images/partners/2X/Banner/DIMUTO.png differ diff --git a/public/images/partners/2X/Banner/DLTLedgers.png b/public/images/partners/2X/Banner/DLTLedgers.png new file mode 100644 index 0000000..6bf8f91 Binary files /dev/null and b/public/images/partners/2X/Banner/DLTLedgers.png differ diff --git a/public/images/partners/2X/Banner/DOCKLAB.png b/public/images/partners/2X/Banner/DOCKLAB.png new file mode 100644 index 0000000..26bba0e Binary files /dev/null and b/public/images/partners/2X/Banner/DOCKLAB.png differ diff --git a/public/images/partners/2X/Banner/Docsonblocks.png b/public/images/partners/2X/Banner/Docsonblocks.png new file mode 100644 index 0000000..eb63116 Binary files /dev/null and b/public/images/partners/2X/Banner/Docsonblocks.png differ diff --git a/public/images/partners/2X/Banner/DocuShield.png b/public/images/partners/2X/Banner/DocuShield.png new file mode 100644 index 0000000..a2890f1 Binary files /dev/null and b/public/images/partners/2X/Banner/DocuShield.png differ diff --git a/public/images/partners/2X/Banner/DocuTrade.png b/public/images/partners/2X/Banner/DocuTrade.png new file mode 100644 index 0000000..9ac5088 Binary files /dev/null and b/public/images/partners/2X/Banner/DocuTrade.png differ diff --git a/public/images/partners/2X/Banner/FUIX LABS.png b/public/images/partners/2X/Banner/FUIX LABS.png new file mode 100644 index 0000000..37d39bb Binary files /dev/null and b/public/images/partners/2X/Banner/FUIX LABS.png differ diff --git a/public/images/partners/2X/Banner/FilPass.png b/public/images/partners/2X/Banner/FilPass.png new file mode 100644 index 0000000..0faf27a Binary files /dev/null and b/public/images/partners/2X/Banner/FilPass.png differ diff --git a/public/images/partners/2X/Banner/GUUD.png b/public/images/partners/2X/Banner/GUUD.png new file mode 100644 index 0000000..1a5b226 Binary files /dev/null and b/public/images/partners/2X/Banner/GUUD.png differ diff --git a/public/images/partners/2X/Banner/ICICI Bank.png b/public/images/partners/2X/Banner/ICICI Bank.png new file mode 100644 index 0000000..7c94ea8 Binary files /dev/null and b/public/images/partners/2X/Banner/ICICI Bank.png differ diff --git a/public/images/partners/2X/Banner/Institute of Technical Education.png b/public/images/partners/2X/Banner/Institute of Technical Education.png new file mode 100644 index 0000000..6ee4eca Binary files /dev/null and b/public/images/partners/2X/Banner/Institute of Technical Education.png differ diff --git a/public/images/partners/2X/Banner/JSLA.png b/public/images/partners/2X/Banner/JSLA.png new file mode 100644 index 0000000..e030b43 Binary files /dev/null and b/public/images/partners/2X/Banner/JSLA.png differ diff --git a/public/images/partners/2X/Banner/JUPYTON.png b/public/images/partners/2X/Banner/JUPYTON.png new file mode 100644 index 0000000..b1bc58d Binary files /dev/null and b/public/images/partners/2X/Banner/JUPYTON.png differ diff --git a/public/images/partners/2X/Banner/Jed.png b/public/images/partners/2X/Banner/Jed.png new file mode 100644 index 0000000..57157a2 Binary files /dev/null and b/public/images/partners/2X/Banner/Jed.png differ diff --git a/public/images/partners/2X/Banner/LASALLE College of the Arts.png b/public/images/partners/2X/Banner/LASALLE College of the Arts.png new file mode 100644 index 0000000..f8eb287 Binary files /dev/null and b/public/images/partners/2X/Banner/LASALLE College of the Arts.png differ diff --git a/public/images/partners/2X/Banner/Linklogis.png b/public/images/partners/2X/Banner/Linklogis.png new file mode 100644 index 0000000..4cfc5cb Binary files /dev/null and b/public/images/partners/2X/Banner/Linklogis.png differ diff --git a/public/images/partners/2X/Banner/MAPTRASCO.png b/public/images/partners/2X/Banner/MAPTRASCO.png new file mode 100644 index 0000000..85e6d72 Binary files /dev/null and b/public/images/partners/2X/Banner/MAPTRASCO.png differ diff --git a/public/images/partners/2X/Banner/Morpheus.Network.png b/public/images/partners/2X/Banner/Morpheus.Network.png new file mode 100644 index 0000000..e3c58c8 Binary files /dev/null and b/public/images/partners/2X/Banner/Morpheus.Network.png differ diff --git a/public/images/partners/2X/Banner/NAFA.png b/public/images/partners/2X/Banner/NAFA.png new file mode 100644 index 0000000..248bf67 Binary files /dev/null and b/public/images/partners/2X/Banner/NAFA.png differ diff --git a/public/images/partners/2X/Banner/NIEC.png b/public/images/partners/2X/Banner/NIEC.png new file mode 100644 index 0000000..74a4d12 Binary files /dev/null and b/public/images/partners/2X/Banner/NIEC.png differ diff --git a/public/images/partners/2X/Banner/Nanyang Polytechnic.png b/public/images/partners/2X/Banner/Nanyang Polytechnic.png new file mode 100644 index 0000000..b5771d8 Binary files /dev/null and b/public/images/partners/2X/Banner/Nanyang Polytechnic.png differ diff --git a/public/images/partners/2X/Banner/National University of Singapore.png b/public/images/partners/2X/Banner/National University of Singapore.png new file mode 100644 index 0000000..44d8704 Binary files /dev/null and b/public/images/partners/2X/Banner/National University of Singapore.png differ diff --git a/public/images/partners/2X/Banner/Ngee Ann Polytechnic.png b/public/images/partners/2X/Banner/Ngee Ann Polytechnic.png new file mode 100644 index 0000000..5f2908c Binary files /dev/null and b/public/images/partners/2X/Banner/Ngee Ann Polytechnic.png differ diff --git a/public/images/partners/2X/Banner/Pacific International Lines.png b/public/images/partners/2X/Banner/Pacific International Lines.png new file mode 100644 index 0000000..d26247f Binary files /dev/null and b/public/images/partners/2X/Banner/Pacific International Lines.png differ diff --git a/public/images/partners/2X/Banner/Republic Polytechnic.png b/public/images/partners/2X/Banner/Republic Polytechnic.png new file mode 100644 index 0000000..2612756 Binary files /dev/null and b/public/images/partners/2X/Banner/Republic Polytechnic.png differ diff --git a/public/images/partners/2X/Banner/SECRO.png b/public/images/partners/2X/Banner/SECRO.png new file mode 100644 index 0000000..40e2957 Binary files /dev/null and b/public/images/partners/2X/Banner/SECRO.png differ diff --git a/public/images/partners/2X/Banner/SGTraDex.png b/public/images/partners/2X/Banner/SGTraDex.png new file mode 100644 index 0000000..1134f5a Binary files /dev/null and b/public/images/partners/2X/Banner/SGTraDex.png differ diff --git a/public/images/partners/2X/Banner/SMU.png b/public/images/partners/2X/Banner/SMU.png new file mode 100644 index 0000000..dc79c45 Binary files /dev/null and b/public/images/partners/2X/Banner/SMU.png differ diff --git a/public/images/partners/2X/Banner/STABILITY.png b/public/images/partners/2X/Banner/STABILITY.png new file mode 100644 index 0000000..f33febc Binary files /dev/null and b/public/images/partners/2X/Banner/STABILITY.png differ diff --git a/public/images/partners/2X/Banner/Singapore Examinations and Assessment Board.png b/public/images/partners/2X/Banner/Singapore Examinations and Assessment Board.png new file mode 100644 index 0000000..f4d7c51 Binary files /dev/null and b/public/images/partners/2X/Banner/Singapore Examinations and Assessment Board.png differ diff --git a/public/images/partners/2X/Banner/Singapore Polytechnic.png b/public/images/partners/2X/Banner/Singapore Polytechnic.png new file mode 100644 index 0000000..9def663 Binary files /dev/null and b/public/images/partners/2X/Banner/Singapore Polytechnic.png differ diff --git a/public/images/partners/2X/Banner/Singapore University of Social Sciences.png b/public/images/partners/2X/Banner/Singapore University of Social Sciences.png new file mode 100644 index 0000000..f83324e Binary files /dev/null and b/public/images/partners/2X/Banner/Singapore University of Social Sciences.png differ diff --git a/public/images/partners/2X/Banner/SkillsFuture SG.png b/public/images/partners/2X/Banner/SkillsFuture SG.png new file mode 100644 index 0000000..16a1256 Binary files /dev/null and b/public/images/partners/2X/Banner/SkillsFuture SG.png differ diff --git a/public/images/partners/2X/Banner/TASConnect.png b/public/images/partners/2X/Banner/TASConnect.png new file mode 100644 index 0000000..5fc0532 Binary files /dev/null and b/public/images/partners/2X/Banner/TASConnect.png differ diff --git "a/public/images/partners/2X/Banner/TRAM\303\211S.png" "b/public/images/partners/2X/Banner/TRAM\303\211S.png" new file mode 100644 index 0000000..351feb7 Binary files /dev/null and "b/public/images/partners/2X/Banner/TRAM\303\211S.png" differ diff --git a/public/images/partners/2X/Banner/Temasek Polytechnic.png b/public/images/partners/2X/Banner/Temasek Polytechnic.png new file mode 100644 index 0000000..3774def Binary files /dev/null and b/public/images/partners/2X/Banner/Temasek Polytechnic.png differ diff --git a/public/images/partners/2X/Banner/TradeGo.png b/public/images/partners/2X/Banner/TradeGo.png new file mode 100644 index 0000000..052dcdd Binary files /dev/null and b/public/images/partners/2X/Banner/TradeGo.png differ diff --git a/public/images/partners/2X/Banner/UOB.png b/public/images/partners/2X/Banner/UOB.png new file mode 100644 index 0000000..2d8f234 Binary files /dev/null and b/public/images/partners/2X/Banner/UOB.png differ diff --git a/public/images/partners/2X/Banner/VAYANA.png b/public/images/partners/2X/Banner/VAYANA.png new file mode 100644 index 0000000..3b98b1b Binary files /dev/null and b/public/images/partners/2X/Banner/VAYANA.png differ diff --git a/public/images/partners/2X/Banner/XDC Network.png b/public/images/partners/2X/Banner/XDC Network.png new file mode 100644 index 0000000..53ed604 Binary files /dev/null and b/public/images/partners/2X/Banner/XDC Network.png differ diff --git a/public/images/partners/2X/Banner/YIT HONG PTE LTD.png b/public/images/partners/2X/Banner/YIT HONG PTE LTD.png new file mode 100644 index 0000000..c21fcf3 Binary files /dev/null and b/public/images/partners/2X/Banner/YIT HONG PTE LTD.png differ diff --git a/public/images/partners/2X/Banner/ZenithBlox.png b/public/images/partners/2X/Banner/ZenithBlox.png new file mode 100644 index 0000000..9d770d1 Binary files /dev/null and b/public/images/partners/2X/Banner/ZenithBlox.png differ diff --git a/public/images/partners/2X/Banner/eTEU.png b/public/images/partners/2X/Banner/eTEU.png new file mode 100644 index 0000000..8f2f19f Binary files /dev/null and b/public/images/partners/2X/Banner/eTEU.png differ diff --git a/public/images/partners/2X/Banner/veriTAG.png b/public/images/partners/2X/Banner/veriTAG.png new file mode 100644 index 0000000..99570c8 Binary files /dev/null and b/public/images/partners/2X/Banner/veriTAG.png differ diff --git a/public/images/partners/2X/Card/Infrastructure/TradeTrust/ASTROn.png b/public/images/partners/2X/Card/Infrastructure/TradeTrust/ASTROn.png new file mode 100644 index 0000000..b0d033f Binary files /dev/null and b/public/images/partners/2X/Card/Infrastructure/TradeTrust/ASTROn.png differ diff --git a/public/images/partners/2X/Card/Infrastructure/TradeTrust/DLTLedgers.png b/public/images/partners/2X/Card/Infrastructure/TradeTrust/DLTLedgers.png new file mode 100644 index 0000000..7edd2b1 Binary files /dev/null and b/public/images/partners/2X/Card/Infrastructure/TradeTrust/DLTLedgers.png differ diff --git a/public/images/partners/2X/Card/Infrastructure/TradeTrust/STABILITY.png b/public/images/partners/2X/Card/Infrastructure/TradeTrust/STABILITY.png new file mode 100644 index 0000000..ac97b16 Binary files /dev/null and b/public/images/partners/2X/Card/Infrastructure/TradeTrust/STABILITY.png differ diff --git a/public/images/partners/2X/Card/Infrastructure/TradeTrust/XDC Network.png b/public/images/partners/2X/Card/Infrastructure/TradeTrust/XDC Network.png new file mode 100644 index 0000000..79448bb Binary files /dev/null and b/public/images/partners/2X/Card/Infrastructure/TradeTrust/XDC Network.png differ diff --git a/public/images/partners/2X/Card/Issuance Attestation/OpenCert/Institute of Technical Education.png b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/Institute of Technical Education.png new file mode 100644 index 0000000..2a168b9 Binary files /dev/null and b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/Institute of Technical Education.png differ diff --git a/public/images/partners/2X/Card/Issuance Attestation/OpenCert/LASALLE College of the Arts.png b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/LASALLE College of the Arts.png new file mode 100644 index 0000000..c9aa494 Binary files /dev/null and b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/LASALLE College of the Arts.png differ diff --git a/public/images/partners/2X/Card/Issuance Attestation/OpenCert/NAFA.png b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/NAFA.png new file mode 100644 index 0000000..6295596 Binary files /dev/null and b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/NAFA.png differ diff --git a/public/images/partners/2X/Card/Issuance Attestation/OpenCert/NIEC.png b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/NIEC.png new file mode 100644 index 0000000..905d36a Binary files /dev/null and b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/NIEC.png differ diff --git a/public/images/partners/2X/Card/Issuance Attestation/OpenCert/Nanyang Polytechnic.png b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/Nanyang Polytechnic.png new file mode 100644 index 0000000..28c6429 Binary files /dev/null and b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/Nanyang Polytechnic.png differ diff --git a/public/images/partners/2X/Card/Issuance Attestation/OpenCert/National University of Singapore.png b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/National University of Singapore.png new file mode 100644 index 0000000..169dcce Binary files /dev/null and b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/National University of Singapore.png differ diff --git a/public/images/partners/2X/Card/Issuance Attestation/OpenCert/Ngee Ann Polytechnic.png b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/Ngee Ann Polytechnic.png new file mode 100644 index 0000000..b2bad44 Binary files /dev/null and b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/Ngee Ann Polytechnic.png differ diff --git a/public/images/partners/2X/Card/Issuance Attestation/OpenCert/Republic Polytechnic.png b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/Republic Polytechnic.png new file mode 100644 index 0000000..bedf9ba Binary files /dev/null and b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/Republic Polytechnic.png differ diff --git a/public/images/partners/2X/Card/Issuance Attestation/OpenCert/SMU.png b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/SMU.png new file mode 100644 index 0000000..02547d4 Binary files /dev/null and b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/SMU.png differ diff --git a/public/images/partners/2X/Card/Issuance Attestation/OpenCert/Singapore Examinations and Assessment Board.png b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/Singapore Examinations and Assessment Board.png new file mode 100644 index 0000000..e0fa81b Binary files /dev/null and b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/Singapore Examinations and Assessment Board.png differ diff --git a/public/images/partners/2X/Card/Issuance Attestation/OpenCert/Singapore Polytechnic.png b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/Singapore Polytechnic.png new file mode 100644 index 0000000..3bf4484 Binary files /dev/null and b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/Singapore Polytechnic.png differ diff --git a/public/images/partners/2X/Card/Issuance Attestation/OpenCert/Singapore University of Social Sciences.png b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/Singapore University of Social Sciences.png new file mode 100644 index 0000000..79c5ccf Binary files /dev/null and b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/Singapore University of Social Sciences.png differ diff --git a/public/images/partners/2X/Card/Issuance Attestation/OpenCert/SkillsFuture SG.png b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/SkillsFuture SG.png new file mode 100644 index 0000000..cfccae7 Binary files /dev/null and b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/SkillsFuture SG.png differ diff --git a/public/images/partners/2X/Card/Issuance Attestation/OpenCert/Temasek Polytechnic.png b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/Temasek Polytechnic.png new file mode 100644 index 0000000..7bba28c Binary files /dev/null and b/public/images/partners/2X/Card/Issuance Attestation/OpenCert/Temasek Polytechnic.png differ diff --git a/public/images/partners/2X/Card/Issuance Attestation/TradeTrust/COFCO.png b/public/images/partners/2X/Card/Issuance Attestation/TradeTrust/COFCO.png new file mode 100644 index 0000000..bb31349 Binary files /dev/null and b/public/images/partners/2X/Card/Issuance Attestation/TradeTrust/COFCO.png differ diff --git a/public/images/partners/2X/Card/Issuance Attestation/TradeTrust/ICICI Bank.png b/public/images/partners/2X/Card/Issuance Attestation/TradeTrust/ICICI Bank.png new file mode 100644 index 0000000..72f409a Binary files /dev/null and b/public/images/partners/2X/Card/Issuance Attestation/TradeTrust/ICICI Bank.png differ diff --git a/public/images/partners/2X/Card/Issuance Attestation/TradeTrust/JSLA.png b/public/images/partners/2X/Card/Issuance Attestation/TradeTrust/JSLA.png new file mode 100644 index 0000000..c978aaa Binary files /dev/null and b/public/images/partners/2X/Card/Issuance Attestation/TradeTrust/JSLA.png differ diff --git a/public/images/partners/2X/Card/Issuance Attestation/TradeTrust/MAPTRASCO.png b/public/images/partners/2X/Card/Issuance Attestation/TradeTrust/MAPTRASCO.png new file mode 100644 index 0000000..80176bb Binary files /dev/null and b/public/images/partners/2X/Card/Issuance Attestation/TradeTrust/MAPTRASCO.png differ diff --git a/public/images/partners/2X/Card/Issuance Attestation/TradeTrust/Pacific International Lines.png b/public/images/partners/2X/Card/Issuance Attestation/TradeTrust/Pacific International Lines.png new file mode 100644 index 0000000..a2a7254 Binary files /dev/null and b/public/images/partners/2X/Card/Issuance Attestation/TradeTrust/Pacific International Lines.png differ diff --git a/public/images/partners/2X/Card/Issuance Attestation/TradeTrust/YIT HONG PTE LTD.png b/public/images/partners/2X/Card/Issuance Attestation/TradeTrust/YIT HONG PTE LTD.png new file mode 100644 index 0000000..5e15e1e Binary files /dev/null and b/public/images/partners/2X/Card/Issuance Attestation/TradeTrust/YIT HONG PTE LTD.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/AEOTRADE.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/AEOTRADE.png new file mode 100644 index 0000000..0cadac1 Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/AEOTRADE.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/Angsana Technology.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/Angsana Technology.png new file mode 100644 index 0000000..f5aaea3 Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/Angsana Technology.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/Automaxis.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/Automaxis.png new file mode 100644 index 0000000..c3c4d84 Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/Automaxis.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/Banco.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/Banco.png new file mode 100644 index 0000000..bde5f3a Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/Banco.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/BlockPeer.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/BlockPeer.png new file mode 100644 index 0000000..f869a4e Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/BlockPeer.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/BunkerChain.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/BunkerChain.png new file mode 100644 index 0000000..361587c Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/BunkerChain.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/CALISTA.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/CALISTA.png new file mode 100644 index 0000000..d1614b9 Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/CALISTA.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/CargoX.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/CargoX.png new file mode 100644 index 0000000..9315f27 Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/CargoX.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/ChainDoX.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/ChainDoX.png new file mode 100644 index 0000000..5daabd6 Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/ChainDoX.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/Credore.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/Credore.png new file mode 100644 index 0000000..ec436cc Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/Credore.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/DIMUTO.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/DIMUTO.png new file mode 100644 index 0000000..1e0e8a5 Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/DIMUTO.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/DOCKLAB.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/DOCKLAB.png new file mode 100644 index 0000000..ebc7c72 Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/DOCKLAB.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/Docsonblocks.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/Docsonblocks.png new file mode 100644 index 0000000..10ca80f Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/Docsonblocks.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/DocuShield.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/DocuShield.png new file mode 100644 index 0000000..5efe174 Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/DocuShield.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/DocuTrade.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/DocuTrade.png new file mode 100644 index 0000000..c677c67 Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/DocuTrade.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/FUIX LABS.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/FUIX LABS.png new file mode 100644 index 0000000..f73b34c Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/FUIX LABS.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/FilPass.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/FilPass.png new file mode 100644 index 0000000..4da4eb9 Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/FilPass.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/GUUD.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/GUUD.png new file mode 100644 index 0000000..9cb2f30 Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/GUUD.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/JUPYTON.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/JUPYTON.png new file mode 100644 index 0000000..607d77d Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/JUPYTON.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/Jed.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/Jed.png new file mode 100644 index 0000000..1ea808f Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/Jed.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/Linklogis.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/Linklogis.png new file mode 100644 index 0000000..1bd1c6f Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/Linklogis.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/Morpheus.Network.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/Morpheus.Network.png new file mode 100644 index 0000000..8aca59e Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/Morpheus.Network.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/SECRO.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/SECRO.png new file mode 100644 index 0000000..3f7c318 Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/SECRO.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/SGTraDex.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/SGTraDex.png new file mode 100644 index 0000000..022eba1 Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/SGTraDex.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/TASConnect.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/TASConnect.png new file mode 100644 index 0000000..d8cdbbb Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/TASConnect.png differ diff --git "a/public/images/partners/2X/Card/Solution Provider/TradeTrust/TRAM\303\211S.png" "b/public/images/partners/2X/Card/Solution Provider/TradeTrust/TRAM\303\211S.png" new file mode 100644 index 0000000..5c96e20 Binary files /dev/null and "b/public/images/partners/2X/Card/Solution Provider/TradeTrust/TRAM\303\211S.png" differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/TradeGo.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/TradeGo.png new file mode 100644 index 0000000..648c009 Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/TradeGo.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/VAYANA.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/VAYANA.png new file mode 100644 index 0000000..1b980e1 Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/VAYANA.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/ZenithBlox.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/ZenithBlox.png new file mode 100644 index 0000000..497e9df Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/ZenithBlox.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/eTEU.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/eTEU.png new file mode 100644 index 0000000..82fa826 Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/eTEU.png differ diff --git a/public/images/partners/2X/Card/Solution Provider/TradeTrust/veriTAG.png b/public/images/partners/2X/Card/Solution Provider/TradeTrust/veriTAG.png new file mode 100644 index 0000000..aa1c533 Binary files /dev/null and b/public/images/partners/2X/Card/Solution Provider/TradeTrust/veriTAG.png differ diff --git a/public/images/partners/2X/Card/Verification Validation/TradeTrust/Bank of China.png b/public/images/partners/2X/Card/Verification Validation/TradeTrust/Bank of China.png new file mode 100644 index 0000000..c560aa5 Binary files /dev/null and b/public/images/partners/2X/Card/Verification Validation/TradeTrust/Bank of China.png differ diff --git a/public/images/partners/2X/Card/Verification Validation/TradeTrust/DBS Group.png b/public/images/partners/2X/Card/Verification Validation/TradeTrust/DBS Group.png new file mode 100644 index 0000000..1ee92bb Binary files /dev/null and b/public/images/partners/2X/Card/Verification Validation/TradeTrust/DBS Group.png differ diff --git a/public/images/partners/2X/Card/Verification Validation/TradeTrust/UOB.png b/public/images/partners/2X/Card/Verification Validation/TradeTrust/UOB.png new file mode 100644 index 0000000..df3fa16 Binary files /dev/null and b/public/images/partners/2X/Card/Verification Validation/TradeTrust/UOB.png differ diff --git a/public/images/partners/AEOTRADE.svg b/public/images/partners/AEOTRADE.svg new file mode 100644 index 0000000..3b8c37d --- /dev/null +++ b/public/images/partners/AEOTRADE.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/ASTROn.svg b/public/images/partners/ASTROn.svg new file mode 100644 index 0000000..0bb9cef --- /dev/null +++ b/public/images/partners/ASTROn.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/Angsana Technology.svg b/public/images/partners/Angsana Technology.svg new file mode 100644 index 0000000..c188492 --- /dev/null +++ b/public/images/partners/Angsana Technology.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/Automaxis.svg b/public/images/partners/Automaxis.svg new file mode 100644 index 0000000..5932599 --- /dev/null +++ b/public/images/partners/Automaxis.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/Banco.svg b/public/images/partners/Banco.svg new file mode 100644 index 0000000..7576227 --- /dev/null +++ b/public/images/partners/Banco.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/Bank of China.svg b/public/images/partners/Bank of China.svg new file mode 100644 index 0000000..2894e24 --- /dev/null +++ b/public/images/partners/Bank of China.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/public/images/partners/BlockPeer.svg b/public/images/partners/BlockPeer.svg new file mode 100644 index 0000000..e25fd85 --- /dev/null +++ b/public/images/partners/BlockPeer.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/BunkerChain.svg b/public/images/partners/BunkerChain.svg new file mode 100644 index 0000000..c05496f --- /dev/null +++ b/public/images/partners/BunkerChain.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/CALISTA.svg b/public/images/partners/CALISTA.svg new file mode 100644 index 0000000..2374c9b --- /dev/null +++ b/public/images/partners/CALISTA.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/COFCO.svg b/public/images/partners/COFCO.svg new file mode 100644 index 0000000..f0a383a --- /dev/null +++ b/public/images/partners/COFCO.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/CargoX.svg b/public/images/partners/CargoX.svg new file mode 100644 index 0000000..b5e3fbd --- /dev/null +++ b/public/images/partners/CargoX.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/ChainDoX.svg b/public/images/partners/ChainDoX.svg new file mode 100644 index 0000000..e6af716 --- /dev/null +++ b/public/images/partners/ChainDoX.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/Credore.svg b/public/images/partners/Credore.svg new file mode 100644 index 0000000..a2a23bb --- /dev/null +++ b/public/images/partners/Credore.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/DBS Group.svg b/public/images/partners/DBS Group.svg new file mode 100644 index 0000000..79905c2 --- /dev/null +++ b/public/images/partners/DBS Group.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/DIMUTO.svg b/public/images/partners/DIMUTO.svg new file mode 100644 index 0000000..9cee423 --- /dev/null +++ b/public/images/partners/DIMUTO.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/DLTLedgers.svg b/public/images/partners/DLTLedgers.svg new file mode 100644 index 0000000..4fba3e4 --- /dev/null +++ b/public/images/partners/DLTLedgers.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/DOCKLAB.svg b/public/images/partners/DOCKLAB.svg new file mode 100644 index 0000000..6e9cb17 --- /dev/null +++ b/public/images/partners/DOCKLAB.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/Docsonblocks.svg b/public/images/partners/Docsonblocks.svg new file mode 100644 index 0000000..3b4a049 --- /dev/null +++ b/public/images/partners/Docsonblocks.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/DocuShield.svg b/public/images/partners/DocuShield.svg new file mode 100644 index 0000000..515ce01 --- /dev/null +++ b/public/images/partners/DocuShield.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/DocuTrade.svg b/public/images/partners/DocuTrade.svg new file mode 100644 index 0000000..c938304 --- /dev/null +++ b/public/images/partners/DocuTrade.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/FUIX LABS.svg b/public/images/partners/FUIX LABS.svg new file mode 100644 index 0000000..8b71a92 --- /dev/null +++ b/public/images/partners/FUIX LABS.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/FilPass.svg b/public/images/partners/FilPass.svg new file mode 100644 index 0000000..aa5c1c0 --- /dev/null +++ b/public/images/partners/FilPass.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/GUUD.svg b/public/images/partners/GUUD.svg new file mode 100644 index 0000000..6001e5d --- /dev/null +++ b/public/images/partners/GUUD.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/ICICI Bank.svg b/public/images/partners/ICICI Bank.svg new file mode 100644 index 0000000..6e4dcd9 --- /dev/null +++ b/public/images/partners/ICICI Bank.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/images/partners/Institute of Technical Education.svg b/public/images/partners/Institute of Technical Education.svg new file mode 100644 index 0000000..944c0d9 --- /dev/null +++ b/public/images/partners/Institute of Technical Education.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/JSLA.svg b/public/images/partners/JSLA.svg new file mode 100644 index 0000000..bc01fc4 --- /dev/null +++ b/public/images/partners/JSLA.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/JUPYTON.svg b/public/images/partners/JUPYTON.svg new file mode 100644 index 0000000..5720b66 --- /dev/null +++ b/public/images/partners/JUPYTON.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/LASALLE College of the Arts.svg b/public/images/partners/LASALLE College of the Arts.svg new file mode 100644 index 0000000..6dd11c1 --- /dev/null +++ b/public/images/partners/LASALLE College of the Arts.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/Linklogis.svg b/public/images/partners/Linklogis.svg new file mode 100644 index 0000000..f50bdb9 --- /dev/null +++ b/public/images/partners/Linklogis.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/MAPTRASCO.svg b/public/images/partners/MAPTRASCO.svg new file mode 100644 index 0000000..16473f3 --- /dev/null +++ b/public/images/partners/MAPTRASCO.svg @@ -0,0 +1,3175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/images/partners/Morpheus.Network.svg b/public/images/partners/Morpheus.Network.svg new file mode 100644 index 0000000..e8c1a19 --- /dev/null +++ b/public/images/partners/Morpheus.Network.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/NAFA.svg b/public/images/partners/NAFA.svg new file mode 100644 index 0000000..ce23ce0 --- /dev/null +++ b/public/images/partners/NAFA.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/NIEC.svg b/public/images/partners/NIEC.svg new file mode 100644 index 0000000..da9065c --- /dev/null +++ b/public/images/partners/NIEC.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/Nanyang Polytechnic.svg b/public/images/partners/Nanyang Polytechnic.svg new file mode 100644 index 0000000..b659dca --- /dev/null +++ b/public/images/partners/Nanyang Polytechnic.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/National University of Singapore.svg b/public/images/partners/National University of Singapore.svg new file mode 100644 index 0000000..0036689 --- /dev/null +++ b/public/images/partners/National University of Singapore.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/public/images/partners/Ngee Ann Polytechnic.svg b/public/images/partners/Ngee Ann Polytechnic.svg new file mode 100644 index 0000000..7dbba73 --- /dev/null +++ b/public/images/partners/Ngee Ann Polytechnic.svg @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/images/partners/Pacific International Lines.svg b/public/images/partners/Pacific International Lines.svg new file mode 100644 index 0000000..3a9bffb --- /dev/null +++ b/public/images/partners/Pacific International Lines.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/Republic Polytechnic.svg b/public/images/partners/Republic Polytechnic.svg new file mode 100644 index 0000000..d11cd22 --- /dev/null +++ b/public/images/partners/Republic Polytechnic.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/images/partners/SECRO.svg b/public/images/partners/SECRO.svg new file mode 100644 index 0000000..092cfab --- /dev/null +++ b/public/images/partners/SECRO.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/SGTraDex.svg b/public/images/partners/SGTraDex.svg new file mode 100644 index 0000000..ebb5be6 --- /dev/null +++ b/public/images/partners/SGTraDex.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/SMU.svg b/public/images/partners/SMU.svg new file mode 100644 index 0000000..3ff9c20 --- /dev/null +++ b/public/images/partners/SMU.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/images/partners/STABILITY.svg b/public/images/partners/STABILITY.svg new file mode 100644 index 0000000..c30256a --- /dev/null +++ b/public/images/partners/STABILITY.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/Singapore Examinations and Assessment Board.svg b/public/images/partners/Singapore Examinations and Assessment Board.svg new file mode 100644 index 0000000..bfe4c7c --- /dev/null +++ b/public/images/partners/Singapore Examinations and Assessment Board.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/Singapore Polytechnic.svg b/public/images/partners/Singapore Polytechnic.svg new file mode 100644 index 0000000..ea0e130 --- /dev/null +++ b/public/images/partners/Singapore Polytechnic.svg @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/images/partners/Singapore University of Social Sciences.svg b/public/images/partners/Singapore University of Social Sciences.svg new file mode 100644 index 0000000..cbbd070 --- /dev/null +++ b/public/images/partners/Singapore University of Social Sciences.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/SkillsFuture SG.svg b/public/images/partners/SkillsFuture SG.svg new file mode 100644 index 0000000..c08a485 --- /dev/null +++ b/public/images/partners/SkillsFuture SG.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/TASConnect.svg b/public/images/partners/TASConnect.svg new file mode 100644 index 0000000..bf0568a --- /dev/null +++ b/public/images/partners/TASConnect.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/Temasek Polytechnic.svg b/public/images/partners/Temasek Polytechnic.svg new file mode 100644 index 0000000..9428003 --- /dev/null +++ b/public/images/partners/Temasek Polytechnic.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/images/partners/TradeGo.svg b/public/images/partners/TradeGo.svg new file mode 100644 index 0000000..4cc2849 --- /dev/null +++ b/public/images/partners/TradeGo.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/UOB.svg b/public/images/partners/UOB.svg new file mode 100644 index 0000000..a312b8c --- /dev/null +++ b/public/images/partners/UOB.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/public/images/partners/VAYANA.svg b/public/images/partners/VAYANA.svg new file mode 100644 index 0000000..514b6ea --- /dev/null +++ b/public/images/partners/VAYANA.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/XDC Network.svg b/public/images/partners/XDC Network.svg new file mode 100644 index 0000000..c8d8983 --- /dev/null +++ b/public/images/partners/XDC Network.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/YIT HONG PTE LTD.svg b/public/images/partners/YIT HONG PTE LTD.svg new file mode 100644 index 0000000..2312f26 --- /dev/null +++ b/public/images/partners/YIT HONG PTE LTD.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/ZenithBlox.svg b/public/images/partners/ZenithBlox.svg new file mode 100644 index 0000000..3565732 --- /dev/null +++ b/public/images/partners/ZenithBlox.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/eTEU.svg b/public/images/partners/eTEU.svg new file mode 100644 index 0000000..350daa7 --- /dev/null +++ b/public/images/partners/eTEU.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/jed.svg b/public/images/partners/jed.svg new file mode 100644 index 0000000..e4f42b3 --- /dev/null +++ b/public/images/partners/jed.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/jindal.svg b/public/images/partners/jindal.svg new file mode 100644 index 0000000..e37a148 --- /dev/null +++ b/public/images/partners/jindal.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/lasalle-uas.svg b/public/images/partners/lasalle-uas.svg new file mode 100644 index 0000000..b9f7438 --- /dev/null +++ b/public/images/partners/lasalle-uas.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/trames.svg b/public/images/partners/trames.svg new file mode 100644 index 0000000..a8d6ac9 --- /dev/null +++ b/public/images/partners/trames.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/partners/veriTAG.svg b/public/images/partners/veriTAG.svg new file mode 100644 index 0000000..49f9e22 --- /dev/null +++ b/public/images/partners/veriTAG.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/App.test.tsx b/src/App.test.tsx index 99632ae..e90da4b 100644 --- a/src/App.test.tsx +++ b/src/App.test.tsx @@ -17,9 +17,9 @@ describe('App Component', () => { render() // Check if navigation elements are present - expect(screen.getByText('Home')).toBeInTheDocument() - // Ecosystem temporarily removed - expect(screen.getByText('News & Updates')).toBeInTheDocument() + expect(screen.getAllByText('About').length).toBeGreaterThan(0) + expect(screen.getAllByText('Partners').length).toBeGreaterThan(0) + expect(screen.getAllByText('News & Updates').length).toBeGreaterThan(0) }) it('starts with light mode by default', () => { diff --git a/src/App.tsx b/src/App.tsx index dc2a552..57c27e6 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -20,6 +20,16 @@ const BACKGROUND_ROUTE_RULES: BackgroundRouteRule[] = [ lightClass: 'app-shell--settings-light', darkClass: 'app-shell--settings-dark', }, + { + paths: ['/partners'], + lightClass: 'app-shell--partners-light', + darkClass: 'app-shell--partners-dark', + }, + { + paths: ['/about'], + lightClass: 'app-shell--about-light', + darkClass: 'app-shell--about-dark', + }, ] function App() { @@ -37,6 +47,10 @@ function App() { localStorage.setItem('darkMode', JSON.stringify(isDarkMode)) }, [isDarkMode]) + useEffect(() => { + window.scrollTo(0, 0) + }, [location.pathname]) + useEffect(() => { if (isDarkMode) { document.body.classList.add('dark-mode') diff --git a/src/__tests__/About.test.tsx b/src/__tests__/About.test.tsx new file mode 100644 index 0000000..0302ea0 --- /dev/null +++ b/src/__tests__/About.test.tsx @@ -0,0 +1,97 @@ +import { describe, it, expect } from 'vitest' +import { render, screen, within } from './test-utils' +import About from '../pages/About' +import capabilities from '../data/capabilities' + +const renderAbout = (isDarkMode = false) => + render() + +describe('About page', () => { + describe('hero', () => { + it('renders the main heading', () => { + renderAbout() + expect(screen.getByRole('heading', { level: 1 })).toBeInTheDocument() + expect(screen.getByText(/The Foundation of/i)).toBeInTheDocument() + expect(screen.getByText(/Digital Trust/i)).toBeInTheDocument() + }) + + it('renders the hero subtitle', () => { + renderAbout() + expect( + screen.getByText(/core infrastructure layer enabling secure/i) + ).toBeInTheDocument() + }) + }) + + describe('EcosystemCard integration', () => { + it('renders the ecosystem card heading', () => { + renderAbout() + expect( + screen.getByRole('heading', { + level: 2, + name: /How TrustVC Powers Multiple Ecosystems/i, + }) + ).toBeInTheDocument() + }) + + it('renders the ecosystem center image', () => { + renderAbout() + expect( + screen.getByAltText(/How TrustVC Powers Multiple Ecosystems/i) + ).toBeInTheDocument() + }) + }) + + describe('Core Capabilities section', () => { + it('renders the Core Capabilities heading', () => { + renderAbout() + expect( + screen.getByRole('heading', { level: 2, name: /Core Capabilities/i }) + ).toBeInTheDocument() + }) + + it(`renders all ${capabilities.length} capability cards`, () => { + renderAbout() + expect(screen.getAllByRole('heading', { level: 3 })).toHaveLength( + capabilities.length + ) + }) + + it('renders each capability title and description', () => { + renderAbout() + capabilities.forEach(cap => { + expect(screen.getByText(cap.title)).toBeInTheDocument() + expect(screen.getByText(cap.description)).toBeInTheDocument() + }) + }) + + it('renders each card with its own tags', () => { + renderAbout() + capabilities.forEach(cap => { + const card = screen.getByText(cap.title).closest('.rounded-2xl')! + cap.tags.forEach(tag => { + expect(within(card as HTMLElement).getByText(tag)).toBeInTheDocument() + }) + }) + }) + }) + + describe('dark / light mode', () => { + it('renders without errors in dark mode', () => { + renderAbout(true) + expect(screen.getByRole('heading', { level: 1 })).toBeInTheDocument() + }) + + it('applies dark mode classes to capability cards', () => { + const { container } = renderAbout(true) + expect( + container.querySelectorAll('.bg-neutral-20\\/30').length + ).toBeGreaterThan(0) + }) + + it('applies light mode classes to capability cards', () => { + const { container } = renderAbout(false) + expect(container.querySelectorAll('.bg-white').length).toBeGreaterThan(0) + }) + }) +}) diff --git a/src/__tests__/PartnerCard.test.tsx b/src/__tests__/PartnerCard.test.tsx new file mode 100644 index 0000000..8570820 --- /dev/null +++ b/src/__tests__/PartnerCard.test.tsx @@ -0,0 +1,154 @@ +import { describe, it, expect } from 'vitest' +import { render, screen } from './test-utils' +import PartnerCard from '../components/common/PartnerCard' +import type { Partner } from '../types/partner' + +const minimalPartner: Partner = { + name: 'Test Partner', + logo: '/images/partners/test.svg', +} + +const fullPartner: Partner = { + name: 'AEOTRADE', + logo: '/images/partners/AEOTRADE.svg', + website: 'https://www.aeotrade.com', + description: 'A trade finance platform', + verticalType: 'TradeTrust', + category: 'Solution Partners', +} + +describe('PartnerCard', () => { + describe('partner name', () => { + it('renders the partner name', () => { + render() + expect( + screen.getByRole('heading', { level: 3, name: 'Test Partner' }) + ).toBeInTheDocument() + }) + }) + + describe('logo', () => { + it('renders logo with correct src and alt attributes', () => { + render() + const img = screen.getByRole('img', { name: 'Test Partner' }) + expect(img).toHaveAttribute('src', '/images/partners/test.svg') + }) + + it('sets loading="lazy" on the logo', () => { + render() + expect(screen.getByRole('img')).toHaveAttribute('loading', 'lazy') + }) + }) + + describe('vertical type tag', () => { + it('renders TradeTrust tag with correct text', () => { + render() + expect(screen.getByText('TradeTrust')).toBeInTheDocument() + }) + + it('renders OpenCerts tag with correct text', () => { + const partner: Partner = { ...minimalPartner, verticalType: 'OpenCerts' } + render() + expect(screen.getByText('OpenCerts')).toBeInTheDocument() + }) + + it('renders no vertical tag when verticalType is absent', () => { + render() + expect(screen.queryByText('TradeTrust')).not.toBeInTheDocument() + expect(screen.queryByText('OpenCerts')).not.toBeInTheDocument() + }) + }) + + describe('category tag', () => { + it('renders category tag when provided', () => { + render() + expect(screen.getByText('Solution Partners')).toBeInTheDocument() + }) + + it('renders no category tag when absent', () => { + render() + expect(screen.queryByText('Solution Partners')).not.toBeInTheDocument() + expect(screen.queryByText('Infrastructure')).not.toBeInTheDocument() + }) + }) + + describe('description', () => { + it('renders description text when provided', () => { + render() + expect(screen.getByText('A trade finance platform')).toBeInTheDocument() + }) + + it('does not render description element when absent', () => { + render() + expect( + screen.queryByText('A trade finance platform') + ).not.toBeInTheDocument() + }) + }) + + describe('Visit Site link', () => { + it('renders Visit Site link with correct href', () => { + render() + const link = screen.getByRole('link', { name: /Visit Site/i }) + expect(link).toHaveAttribute('href', 'https://www.aeotrade.com') + }) + + it('opens Visit Site link in a new tab', () => { + render() + const link = screen.getByRole('link', { name: /Visit Site/i }) + expect(link).toHaveAttribute('target', '_blank') + expect(link).toHaveAttribute('rel', 'noopener noreferrer') + }) + + it('does not render Visit Site link when website is absent', () => { + render() + expect( + screen.queryByRole('link', { name: /Visit Site/i }) + ).not.toBeInTheDocument() + }) + }) + + describe('dark/light mode', () => { + it('applies dark mode background and border', () => { + const { container } = render( + + ) + const card = container.firstChild as HTMLElement + expect(card.className).toContain('bg-[#2A2D35]') + expect(card.className).toContain('border-neutral-10') + }) + + it('applies light mode background and border', () => { + const { container } = render( + + ) + const card = container.firstChild as HTMLElement + expect(card.className).toContain('bg-white') + expect(card.className).toContain('border-neutral-60') + }) + + it('applies dark mode TradeTrust tag colors', () => { + render( + + ) + const tag = screen.getByText('TradeTrust') + expect(tag.className).toContain('bg-[#0B384F]') + expect(tag.className).toContain('text-[#B3ECFF]') + }) + + it('applies light mode TradeTrust tag colors', () => { + render( + + ) + const tag = screen.getByText('TradeTrust') + expect(tag.className).toContain('bg-[#B3ECFF]') + expect(tag.className).toContain('text-[#0B384F]') + }) + }) +}) diff --git a/src/__tests__/Partners.test.tsx b/src/__tests__/Partners.test.tsx new file mode 100644 index 0000000..80fb455 --- /dev/null +++ b/src/__tests__/Partners.test.tsx @@ -0,0 +1,171 @@ +import { describe, it, expect } from 'vitest' +import { render, screen, fireEvent } from './test-utils' +import Partners from '../pages/Partners' +import partners from '../data/partners' + +const CATEGORIES = [ + 'All', + 'Issuance & Attestation', + 'Verification & Validation', + 'Solution Partners', + 'Infrastructure', +] + +describe('Partners page', () => { + describe('heading and subtitle', () => { + it('renders the page heading with "Our Partners"', () => { + render() + const heading = screen.getByRole('heading', { level: 1 }) + expect(heading).toHaveTextContent('Our Partners') + }) + + it('renders the subtitle text', () => { + render() + expect( + screen.getByText( + /The Global Engine for Verifiable Documents and Transferable Records/i + ) + ).toBeInTheDocument() + }) + }) + + describe('category filter', () => { + it('renders all 5 category filter buttons', () => { + render() + CATEGORIES.forEach(cat => { + expect(screen.getByRole('button', { name: cat })).toBeInTheDocument() + }) + }) + + it('"All" filter is active by default', () => { + render() + const allBtn = screen.getByRole('button', { name: 'All' }) + expect(allBtn.className).toContain('bg-primary-60') + expect(allBtn.className).toContain('text-white') + }) + + it('inactive filter buttons do not have active styling', () => { + render() + CATEGORIES.slice(1).forEach(cat => { + const btn = screen.getByRole('button', { name: cat }) + expect(btn.className).not.toContain('bg-primary-60') + }) + }) + + it('clicking a category makes it active', () => { + render() + const infraBtn = screen.getByRole('button', { name: 'Infrastructure' }) + fireEvent.click(infraBtn) + expect(infraBtn.className).toContain('bg-primary-60') + expect(infraBtn.className).toContain('text-white') + }) + + it('clicking a category deactivates the previously active filter', () => { + render() + fireEvent.click(screen.getByRole('button', { name: 'Infrastructure' })) + expect( + screen.getByRole('button', { name: 'All' }).className + ).not.toContain('bg-primary-60') + }) + + it('clicking "All" after a filter restores all partners', () => { + render() + fireEvent.click(screen.getByRole('button', { name: 'Infrastructure' })) + fireEvent.click(screen.getByRole('button', { name: 'All' })) + const cards = screen.getAllByRole('heading', { level: 3 }) + expect(cards).toHaveLength(partners.length) + }) + }) + + describe('partner grid', () => { + it('shows all partners when "All" is selected', () => { + render() + const cards = screen.getAllByRole('heading', { level: 3 }) + expect(cards).toHaveLength(partners.length) + }) + + it('filters to only Solution Partners when that category is selected', () => { + render() + fireEvent.click(screen.getByRole('button', { name: 'Solution Partners' })) + const expected = partners.filter(p => p.category === 'Solution Partners') + expect(screen.getAllByRole('heading', { level: 3 })).toHaveLength( + expected.length + ) + }) + + it('filters to only Infrastructure partners when that category is selected', () => { + render() + fireEvent.click(screen.getByRole('button', { name: 'Infrastructure' })) + const expected = partners.filter(p => p.category === 'Infrastructure') + expect(screen.getAllByRole('heading', { level: 3 })).toHaveLength( + expected.length + ) + }) + + it('filters to only Issuance & Attestation partners when that category is selected', () => { + render() + fireEvent.click( + screen.getByRole('button', { name: 'Issuance & Attestation' }) + ) + const expected = partners.filter( + p => p.category === 'Issuance & Attestation' + ) + expect(screen.getAllByRole('heading', { level: 3 })).toHaveLength( + expected.length + ) + }) + + it('filters to only Verification & Validation partners when that category is selected', () => { + render() + fireEvent.click( + screen.getByRole('button', { name: 'Verification & Validation' }) + ) + const expected = partners.filter( + p => p.category === 'Verification & Validation' + ) + expect(screen.getAllByRole('heading', { level: 3 })).toHaveLength( + expected.length + ) + }) + + it('renders the first partner name in the full list', () => { + render() + expect(screen.getByText(partners[0].name)).toBeInTheDocument() + }) + + it('renders PartnerCard with Visit Site link for partners with a website', () => { + render() + const partnerWithSite = partners.find(p => p.website)! + expect( + screen.getAllByRole('link', { name: /Visit Site/i }).length + ).toBeGreaterThan(0) + // The first partner with a website should appear in the page + expect(screen.getByText(partnerWithSite.name)).toBeInTheDocument() + }) + }) + + describe('dark/light mode', () => { + it('applies dark mode background', () => { + const { container } = render() + expect((container.firstChild as HTMLElement).className).toContain( + 'w-full' + ) + }) + + it('applies light mode background', () => { + const { container } = render() + expect((container.firstChild as HTMLElement).className).toContain( + 'w-full' + ) + }) + + it('passes isDarkMode to PartnerCard components', () => { + const { container: darkContainer } = render( + + ) + // PartnerCard dark mode uses bg-[#2A2D35] - verify at least one card has it + const darkCards = darkContainer.querySelectorAll('.bg-\\[\\#2A2D35\\]') + expect(darkCards.length).toBeGreaterThan(0) + }) + }) +}) diff --git a/src/__tests__/PartnersSection.test.tsx b/src/__tests__/PartnersSection.test.tsx new file mode 100644 index 0000000..e68d1f4 --- /dev/null +++ b/src/__tests__/PartnersSection.test.tsx @@ -0,0 +1,126 @@ +import { describe, it, expect, vi, afterEach } from 'vitest' +import { render, screen, fireEvent } from './test-utils' +import PartnersSection from '../components/home/PartnersSection' + +const mockNavigate = vi.hoisted(() => vi.fn()) + +vi.mock('react-router-dom', async () => { + const actual = await vi.importActual('react-router-dom') + return { + ...(actual as object), + useNavigate: () => mockNavigate, + } +}) + +const HOME_PARTNERS = [ + 'Institute of Technical Education', + 'Jed', + 'JSLA', + 'JUPYTON', + 'LASALLE College of the Arts', +] + +afterEach(() => { + vi.clearAllMocks() +}) + +describe('PartnersSection', () => { + describe('heading and tagline', () => { + it('renders "Our Partners" heading', () => { + render() + const heading = screen.getByRole('heading', { level: 2 }) + expect(heading).toHaveTextContent('Our Partners') + }) + + it('renders the tagline text', () => { + render() + expect( + screen.getByText(/Building a foundation of trust for every industry/i) + ).toBeInTheDocument() + }) + }) + + describe('partner logos', () => { + it('renders logos for home partners in the marquee', () => { + render() + HOME_PARTNERS.forEach(name => { + const imgs = screen.getAllByRole('img', { name }) + expect(imgs.length).toBeGreaterThanOrEqual(1) + }) + }) + + it('renders logos with eager loading for marquee animation', () => { + render() + const imgs = screen.getAllByRole('img') + imgs.forEach(img => expect(img).toHaveAttribute('loading', 'eager')) + }) + + it('duplicates partner logos for infinite marquee effect', () => { + render() + const firstPartnerImgs = screen.getAllByRole('img', { + name: HOME_PARTNERS[0], + }) + expect(firstPartnerImgs.length).toBe(2) + }) + + it('all partner logo containers are visible (no hidden class)', () => { + render() + const imgs = screen.getAllByRole('img', { name: HOME_PARTNERS[0] }) + imgs.forEach(img => { + const container = img.closest('div') + expect(container?.className).not.toContain('hidden') + }) + }) + }) + + describe('View All Partners CTA', () => { + it('renders View All Partners button', () => { + render() + expect( + screen.getByRole('button', { name: /View All Partners/i }) + ).toBeInTheDocument() + }) + + it('navigates to /partners when button is clicked', () => { + render() + fireEvent.click( + screen.getByRole('button', { name: /View All Partners/i }) + ) + expect(mockNavigate).toHaveBeenCalledWith('/partners') + }) + + it('calls navigate exactly once per click', () => { + render() + fireEvent.click( + screen.getByRole('button', { name: /View All Partners/i }) + ) + expect(mockNavigate).toHaveBeenCalledTimes(1) + }) + }) + + describe('dark/light mode', () => { + it('applies dark mode text class to "Our" span in heading', () => { + render() + const heading = screen.getByRole('heading', { level: 2 }) + expect(heading.innerHTML).toContain('text-neutral-60') + }) + + it('applies light mode text class to "Our" span in heading', () => { + render() + const heading = screen.getByRole('heading', { level: 2 }) + expect(heading.innerHTML).toContain('text-[#1E2026]') + }) + + it('applies dark mode class to tagline paragraph', () => { + render() + const tagline = screen.getByText(/Building a foundation of trust/i) + expect(tagline.className).toContain('text-neutral-50') + }) + + it('applies light mode class to tagline paragraph', () => { + render() + const tagline = screen.getByText(/Building a foundation of trust/i) + expect(tagline.className).toContain('text-[#3D444D]') + }) + }) +}) diff --git a/src/__tests__/home.test.tsx b/src/__tests__/home.test.tsx index 8721aa7..7a48a0a 100644 --- a/src/__tests__/home.test.tsx +++ b/src/__tests__/home.test.tsx @@ -46,4 +46,37 @@ describe('Home page', () => { renderHome(false) expect(screen.getByText(/Built for Developers,/i)).toBeInTheDocument() }) + + describe('Partners section', () => { + it('renders the Partners section heading', () => { + renderHome(false) + const heading = screen.getByRole('heading', { + level: 2, + name: /Our Partners/i, + }) + expect(heading).toBeInTheDocument() + }) + + it('renders the Partners section tagline', () => { + renderHome(false) + expect( + screen.getByText(/Building a foundation of trust for every industry/i) + ).toBeInTheDocument() + }) + + it('renders the View All Partners button', () => { + renderHome(false) + expect( + screen.getByRole('button', { name: /View All Partners/i }) + ).toBeInTheDocument() + }) + + it('renders at least one partner logo', () => { + renderHome(false) + const imgs = screen.getAllByRole('img', { + name: 'Institute of Technical Education', + }) + expect(imgs[0]).toBeInTheDocument() + }) + }) }) diff --git a/src/components/about/CapabilityCard/CapabilityCard.test.tsx b/src/components/about/CapabilityCard/CapabilityCard.test.tsx new file mode 100644 index 0000000..724afe2 --- /dev/null +++ b/src/components/about/CapabilityCard/CapabilityCard.test.tsx @@ -0,0 +1,127 @@ +import { describe, it, expect } from 'vitest' +import { render, screen } from '@testing-library/react' +import CapabilityCard from './CapabilityCard' +import { type Capability } from '../../../data/capabilities' + +const transferableOnlyCap: Capability = { + icon: '/images/about/single-source.svg', + tags: ['Transferable Record'], + title: 'Single Source of Truth', + description: + 'TrustVC uses a public blockchain to maintain a single source of truth for ETRs.', +} + +const dualTagCap: Capability = { + icon: '/images/about/unified-foundation.svg', + tags: ['Verifiable Document', 'Transferable Record'], + title: 'Unified Foundation', + description: + 'Single SDK powering multiple industry-specific verification solutions.', +} + +describe('CapabilityCard', () => { + describe('content rendering', () => { + it('renders the card title', () => { + render() + expect( + screen.getByRole('heading', { + level: 3, + name: transferableOnlyCap.title, + }) + ).toBeInTheDocument() + }) + + it('renders the card description', () => { + render() + expect( + screen.getByText(transferableOnlyCap.description) + ).toBeInTheDocument() + }) + + it('renders the icon image with correct alt text', () => { + render() + expect(screen.getByAltText(transferableOnlyCap.title)).toBeInTheDocument() + }) + + it('renders the icon image with correct src', () => { + render() + expect(screen.getByAltText(transferableOnlyCap.title)).toHaveAttribute( + 'src', + transferableOnlyCap.icon + ) + }) + }) + + describe('tag pills', () => { + it('renders a single Transferable Record tag', () => { + render() + expect(screen.getByText('Transferable Record')).toBeInTheDocument() + }) + + it('renders both tags for a dual-tag capability', () => { + render() + expect(screen.getByText('Verifiable Document')).toBeInTheDocument() + expect(screen.getByText('Transferable Record')).toBeInTheDocument() + }) + + it('applies correct styles to Transferable Record tag', () => { + render() + const tag = screen.getByText('Transferable Record') + expect(tag).toHaveStyle({ background: '#dfe1ff', color: '#312d62' }) + }) + + it('applies correct styles to Verifiable Document tag', () => { + render() + const tag = screen.getByText('Verifiable Document') + expect(tag).toHaveStyle({ background: '#b3ecff', color: '#0b384f' }) + }) + + it('renders pill with correct dimensions', () => { + render() + const tag = screen.getByText('Transferable Record') + expect(tag).toHaveStyle({ width: '128px', height: '24px' }) + }) + }) + + describe('dark mode', () => { + it('applies dark mode class to card', () => { + const { container } = render( + + ) + expect(container.firstChild).toHaveClass('bg-neutral-20/30') + }) + + it('applies light mode class to card', () => { + const { container } = render( + + ) + expect(container.firstChild).toHaveClass('bg-white') + }) + + it('applies dark mode class to icon container', () => { + const { container } = render( + + ) + expect(container.querySelector('.bg-neutral-20\\/60')).toBeInTheDocument() + }) + + it('applies light mode class to icon container', () => { + const { container } = render( + + ) + expect(container.querySelector('.bg-\\[\\#F5F6F7\\]')).toBeInTheDocument() + }) + + it('applies dark description color in dark mode', () => { + render() + const desc = screen.getByText(transferableOnlyCap.description) + expect(desc).toHaveStyle({ color: '#8B929A' }) + }) + + it('applies light description color in light mode', () => { + render() + const desc = screen.getByText(transferableOnlyCap.description) + expect(desc).toHaveStyle({ color: '#3D444D' }) + }) + }) +}) diff --git a/src/components/about/CapabilityCard/CapabilityCard.tsx b/src/components/about/CapabilityCard/CapabilityCard.tsx new file mode 100644 index 0000000..817f532 --- /dev/null +++ b/src/components/about/CapabilityCard/CapabilityCard.tsx @@ -0,0 +1,76 @@ +import clsx from 'clsx' +import { type Capability } from '../../../data/capabilities' + +const TAG_STYLES: Record = { + 'Transferable Record': { background: '#dfe1ff', color: '#312d62' }, + 'Verifiable Document': { background: '#b3ecff', color: '#0b384f' }, +} + +interface CapabilityCardProps { + cap: Capability + isDarkMode: boolean +} + +const CapabilityCard = ({ cap, isDarkMode }: CapabilityCardProps) => ( +
+
+
+ {cap.title} +
+
+ {cap.tags.map(tag => ( + + {tag} + + ))} +
+
+ +

+ {cap.title} +

+ +

+ {cap.description} +

+
+) + +export default CapabilityCard diff --git a/src/components/about/CapabilityCard/index.ts b/src/components/about/CapabilityCard/index.ts new file mode 100644 index 0000000..208e753 --- /dev/null +++ b/src/components/about/CapabilityCard/index.ts @@ -0,0 +1 @@ +export { default } from './CapabilityCard' diff --git a/src/components/about/EcosystemCard/EcosystemCard.test.tsx b/src/components/about/EcosystemCard/EcosystemCard.test.tsx new file mode 100644 index 0000000..10ee4d8 --- /dev/null +++ b/src/components/about/EcosystemCard/EcosystemCard.test.tsx @@ -0,0 +1,61 @@ +import { describe, it, expect } from 'vitest' +import { render, screen } from '@testing-library/react' +import EcosystemCard from './EcosystemCard' + +describe('EcosystemCard', () => { + it('renders the heading', () => { + render() + expect( + screen.getByRole('heading', { + level: 2, + name: /How TrustVC Powers Multiple Ecosystems/i, + }) + ).toBeInTheDocument() + }) + + it('renders the subtitle', () => { + render() + expect( + screen.getByText( + /One foundational platform, unlimited verification possibilities/i + ) + ).toBeInTheDocument() + }) + + it('renders the center image with correct alt text', () => { + render() + expect( + screen.getByAltText(/How TrustVC Powers Multiple Ecosystems/i) + ).toBeInTheDocument() + }) + + it('renders the center image with correct src', () => { + render() + expect( + screen.getByAltText(/How TrustVC Powers Multiple Ecosystems/i) + ).toHaveAttribute('src', '/images/about/center-image.svg') + }) + + it('applies the ecosystem card CSS classes', () => { + const { container } = render() + expect(container.querySelector('.about-ecosystem-card')).toBeInTheDocument() + expect( + container.querySelector('.about-ecosystem-card-content') + ).toBeInTheDocument() + }) + + it('has rounded corners only on sm+ breakpoint', () => { + const { container } = render() + const wrapper = container.firstChild as HTMLElement + expect(wrapper.classList.contains('sm:rounded-2xl')).toBe(true) + expect(wrapper.classList.contains('rounded-2xl')).toBe(false) + }) + + it('subtitle has white color style', () => { + render() + const subtitle = screen.getByText( + /One foundational platform, unlimited verification possibilities/i + ) + expect(subtitle).toHaveStyle({ color: '#FFFFFF' }) + }) +}) diff --git a/src/components/about/EcosystemCard/EcosystemCard.tsx b/src/components/about/EcosystemCard/EcosystemCard.tsx new file mode 100644 index 0000000..d5a1fec --- /dev/null +++ b/src/components/about/EcosystemCard/EcosystemCard.tsx @@ -0,0 +1,34 @@ +const EcosystemCard = () => ( +
+
+
+
+

+ How TrustVC Powers Multiple Ecosystems +

+

+ One foundational platform, unlimited verification possibilities. +

+ How TrustVC Powers Multiple Ecosystems +
+
+
+
+) + +export default EcosystemCard diff --git a/src/components/about/EcosystemCard/index.ts b/src/components/about/EcosystemCard/index.ts new file mode 100644 index 0000000..9539e90 --- /dev/null +++ b/src/components/about/EcosystemCard/index.ts @@ -0,0 +1 @@ +export { default } from './EcosystemCard' diff --git a/src/components/common/AttachmentFileList/AttachmentFileList.tsx b/src/components/common/AttachmentFileList/AttachmentFileList.tsx index 6c60333..67d5db3 100644 --- a/src/components/common/AttachmentFileList/AttachmentFileList.tsx +++ b/src/components/common/AttachmentFileList/AttachmentFileList.tsx @@ -23,7 +23,11 @@ export function AttachmentFileList({ + + + ) +} + +export default PartnersSection diff --git a/src/components/home/VerifySection/ActionLoader.test.tsx b/src/components/home/VerifySection/ActionLoader.test.tsx new file mode 100644 index 0000000..dc2b114 --- /dev/null +++ b/src/components/home/VerifySection/ActionLoader.test.tsx @@ -0,0 +1,348 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' +import { render, waitFor } from '../../../__tests__/test-utils' +import { ActionLoader } from './ActionLoader' + +// ─── Mocks ──────────────────────────────────────────────────────────────────── + +const { mockNavigate, mockUseLocation, mockDecryptString } = vi.hoisted(() => ({ + mockNavigate: vi.fn(), + mockUseLocation: vi.fn(), + mockDecryptString: vi.fn(), +})) + +vi.mock('react-router-dom', async () => { + const actual = + await vi.importActual('react-router-dom') + return { + ...actual, + useNavigate: () => mockNavigate, + useLocation: mockUseLocation, + } +}) + +vi.mock('@trustvc/trustvc', async () => { + const actual = + await vi.importActual('@trustvc/trustvc') + return { ...actual, decryptString: mockDecryptString } +}) + +// ─── Helpers ────────────────────────────────────────────────────────────────── + +const SAMPLE_URI = 'https://storage.example.com/documents/doc.json' +const SAMPLE_CHAIN_ID = 11155111 +const SAMPLE_DOC = { version: '2.0', data: { id: 'test-123' } } + +const encodeAction = (overrides: object = {}) => + encodeURIComponent( + JSON.stringify({ + type: 'DOCUMENT', + payload: { uri: SAMPLE_URI, chainId: SAMPLE_CHAIN_ID, ...overrides }, + }) + ) + +const setLocation = (search: string) => + mockUseLocation.mockReturnValue({ search, hash: '', pathname: '/' }) + +const makeFetch = (body: object, ok = true) => + vi + .fn() + .mockResolvedValue({ ok, status: ok ? 200 : 404, json: async () => body }) + +// ─── Tests ──────────────────────────────────────────────────────────────────── + +describe('ActionLoader', () => { + let mockLoadDocument: ReturnType + + beforeEach(() => { + vi.clearAllMocks() + mockLoadDocument = vi.fn().mockResolvedValue(undefined) + }) + + afterEach(() => { + vi.unstubAllGlobals() + }) + + // ── No-op when ?q= is absent ─────────────────────────────────────────────── + + it('does nothing when the URL has no ?q= param', async () => { + setLocation('') + vi.stubGlobal('fetch', makeFetch(SAMPLE_DOC)) + + render() + + // Flush microtasks + await new Promise(r => setTimeout(r, 0)) + expect(mockNavigate).not.toHaveBeenCalled() + expect(mockLoadDocument).not.toHaveBeenCalled() + expect(fetch).not.toHaveBeenCalled() + }) + + // ── URL cleaning ─────────────────────────────────────────────────────────── + + it('cleans the URL with replace:true before fetching', async () => { + setLocation(`?q=${encodeAction()}`) + vi.stubGlobal('fetch', makeFetch(SAMPLE_DOC)) + + render() + + // navigate is called synchronously inside useEffect, before the async fetch + expect(mockNavigate).toHaveBeenCalledWith('/', { replace: true }) + }) + + // ── Happy path ───────────────────────────────────────────────────────────── + + it('fetches document and calls loadDocument with doc, chainId string, and filename', async () => { + setLocation(`?q=${encodeAction()}`) + vi.stubGlobal('fetch', makeFetch(SAMPLE_DOC)) + + render() + + await waitFor(() => expect(mockLoadDocument).toHaveBeenCalledTimes(1)) + expect(mockLoadDocument).toHaveBeenCalledWith( + SAMPLE_DOC, + String(SAMPLE_CHAIN_ID), + 'doc.json' + ) + expect(fetch).toHaveBeenCalledWith(SAMPLE_URI) + }) + + it('unwraps { document: ... } opencerts wrapper before calling loadDocument', async () => { + const innerDoc = { actual: 'content' } + setLocation(`?q=${encodeAction()}`) + vi.stubGlobal('fetch', makeFetch({ document: innerDoc })) + + render() + + await waitFor(() => expect(mockLoadDocument).toHaveBeenCalledTimes(1)) + expect(mockLoadDocument).toHaveBeenCalledWith( + innerDoc, + String(SAMPLE_CHAIN_ID), + 'doc.json' + ) + }) + + it('derives fileName from the last path segment of the URI', async () => { + const uri = 'https://cdn.example.com/docs/my-trade-doc.tt' + setLocation(`?q=${encodeAction({ uri })}`) + vi.stubGlobal('fetch', makeFetch(SAMPLE_DOC)) + + render() + + await waitFor(() => expect(mockLoadDocument).toHaveBeenCalledTimes(1)) + expect(mockLoadDocument).toHaveBeenCalledWith( + SAMPLE_DOC, + String(SAMPLE_CHAIN_ID), + 'my-trade-doc.tt' + ) + }) + + it('falls back to "document.json" when URI ends with a trailing slash', async () => { + const uri = 'https://storage.example.com/' + setLocation(`?q=${encodeAction({ uri })}`) + vi.stubGlobal('fetch', makeFetch(SAMPLE_DOC)) + + render() + + await waitFor(() => expect(mockLoadDocument).toHaveBeenCalledTimes(1)) + const [, , name] = mockLoadDocument.mock.calls[0] + expect(name).toBe('document.json') + }) + + it('coerces a numeric chainId to string', async () => { + setLocation(`?q=${encodeAction({ chainId: 137 })}`) + vi.stubGlobal('fetch', makeFetch(SAMPLE_DOC)) + + render() + + await waitFor(() => expect(mockLoadDocument).toHaveBeenCalledTimes(1)) + const [, chainId] = mockLoadDocument.mock.calls[0] + expect(chainId).toBe('137') + expect(typeof chainId).toBe('string') + }) + + it('passes null chainId when chainId is absent from payload', async () => { + setLocation( + `?q=${encodeURIComponent(JSON.stringify({ type: 'DOCUMENT', payload: { uri: SAMPLE_URI } }))}` + ) + vi.stubGlobal('fetch', makeFetch(SAMPLE_DOC)) + + render() + + await waitFor(() => expect(mockLoadDocument).toHaveBeenCalledTimes(1)) + const [, chainId] = mockLoadDocument.mock.calls[0] + expect(chainId).toBeNull() + }) + + // ── Early returns for unsupported actions ────────────────────────────────── + + it('does not call loadDocument when type is not DOCUMENT', async () => { + setLocation( + `?q=${encodeURIComponent(JSON.stringify({ type: 'OTHER', payload: { uri: SAMPLE_URI, chainId: 1 } }))}` + ) + vi.stubGlobal('fetch', makeFetch(SAMPLE_DOC)) + + render() + + await new Promise(r => setTimeout(r, 20)) + expect(fetch).not.toHaveBeenCalled() + expect(mockLoadDocument).not.toHaveBeenCalled() + }) + + it('does not call loadDocument when payload.uri is missing', async () => { + setLocation( + `?q=${encodeURIComponent(JSON.stringify({ type: 'DOCUMENT', payload: { chainId: 1 } }))}` + ) + vi.stubGlobal('fetch', makeFetch(SAMPLE_DOC)) + + render() + + await new Promise(r => setTimeout(r, 20)) + expect(fetch).not.toHaveBeenCalled() + expect(mockLoadDocument).not.toHaveBeenCalled() + }) + + // ── Error handling ───────────────────────────────────────────────────────── + + it('logs an error and does not throw when fetch returns a non-ok response', async () => { + setLocation(`?q=${encodeAction()}`) + vi.stubGlobal('fetch', makeFetch({}, false)) + const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) + + render() + + await new Promise(r => setTimeout(r, 20)) + expect(mockLoadDocument).not.toHaveBeenCalled() + expect(errorSpy).toHaveBeenCalledWith( + 'ActionLoader: failed to load document from URL', + expect.any(Error) + ) + }) + + it('logs an error and does not throw when fetch rejects', async () => { + setLocation(`?q=${encodeAction()}`) + vi.stubGlobal( + 'fetch', + vi.fn().mockRejectedValue(new Error('Network error')) + ) + const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) + + render() + + await new Promise(r => setTimeout(r, 20)) + expect(mockLoadDocument).not.toHaveBeenCalled() + expect(errorSpy).toHaveBeenCalledWith( + 'ActionLoader: failed to load document from URL', + expect.any(Error) + ) + }) + + it('logs an error and does not throw when ?q= value is invalid JSON', async () => { + setLocation('?q=not-valid-json') + vi.stubGlobal('fetch', makeFetch(SAMPLE_DOC)) + const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) + + render() + + await new Promise(r => setTimeout(r, 20)) + expect(mockLoadDocument).not.toHaveBeenCalled() + expect(errorSpy).toHaveBeenCalledWith( + 'ActionLoader: failed to load document from URL', + expect.any(Error) + ) + }) + + it('still cleans the URL even when ?q= JSON is invalid', async () => { + setLocation('?q=not-valid-json') + vi.stubGlobal('fetch', makeFetch(SAMPLE_DOC)) + vi.spyOn(console, 'error').mockImplementation(() => {}) + + render() + + expect(mockNavigate).toHaveBeenCalledWith('/', { replace: true }) + }) + + // ── OA Encrypted documents (OPEN-ATTESTATION-TYPE-1) ────────────────────── + + describe('decryption', () => { + const ENCRYPTED_DOC = { + type: 'OPEN-ATTESTATION-TYPE-1', + cipherText: 'abc123==', + tag: 'tagValue==', + iv: 'ivValue', + } + const DECRYPTED_DOC = { version: '2.0', data: 'decrypted' } + const DECRYPTION_KEY = + '8813186d10c540b5ed97652b5d59e7f7636c1c3679729b924293c06a05fdaaed' + + it('decrypts an OA-encrypted document using the key from payload', async () => { + mockDecryptString.mockReturnValue(JSON.stringify(DECRYPTED_DOC)) + setLocation(`?q=${encodeAction({ key: DECRYPTION_KEY })}`) + vi.stubGlobal('fetch', makeFetch(ENCRYPTED_DOC)) + + render() + + await waitFor(() => expect(mockLoadDocument).toHaveBeenCalledTimes(1)) + expect(mockDecryptString).toHaveBeenCalledWith({ + tag: ENCRYPTED_DOC.tag, + cipherText: ENCRYPTED_DOC.cipherText, + iv: ENCRYPTED_DOC.iv, + key: DECRYPTION_KEY, + type: ENCRYPTED_DOC.type, + }) + expect(mockLoadDocument).toHaveBeenCalledWith( + DECRYPTED_DOC, + String(SAMPLE_CHAIN_ID), + 'doc.json' + ) + }) + + it('prefers the key from the URL hash anchor over payload.key', async () => { + const anchorKey = 'anchor-key-takes-priority' + mockDecryptString.mockReturnValue(JSON.stringify(DECRYPTED_DOC)) + mockUseLocation.mockReturnValue({ + search: `?q=${encodeAction({ key: DECRYPTION_KEY })}`, + hash: `#${encodeURIComponent(JSON.stringify({ key: anchorKey }))}`, + pathname: '/', + }) + vi.stubGlobal('fetch', makeFetch(ENCRYPTED_DOC)) + + render() + + await waitFor(() => expect(mockDecryptString).toHaveBeenCalledTimes(1)) + expect(mockDecryptString).toHaveBeenCalledWith( + expect.objectContaining({ key: anchorKey }) + ) + }) + + it('throws and logs an error when document is encrypted but no key is provided', async () => { + const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) + setLocation(`?q=${encodeAction()}`) // no key in payload + vi.stubGlobal('fetch', makeFetch(ENCRYPTED_DOC)) + + render() + + await new Promise(r => setTimeout(r, 20)) + expect(mockDecryptString).not.toHaveBeenCalled() + expect(mockLoadDocument).not.toHaveBeenCalled() + expect(errorSpy).toHaveBeenCalledWith( + 'ActionLoader: failed to load document from URL', + expect.any(Error) + ) + }) + + it('does not decrypt when document type is not OPEN-ATTESTATION-TYPE-1', async () => { + setLocation(`?q=${encodeAction({ key: DECRYPTION_KEY })}`) + vi.stubGlobal('fetch', makeFetch(SAMPLE_DOC)) // plain doc, not encrypted + + render() + + await waitFor(() => expect(mockLoadDocument).toHaveBeenCalledTimes(1)) + expect(mockDecryptString).not.toHaveBeenCalled() + expect(mockLoadDocument).toHaveBeenCalledWith( + SAMPLE_DOC, + String(SAMPLE_CHAIN_ID), + 'doc.json' + ) + }) + }) +}) diff --git a/src/components/home/VerifySection/ActionLoader.tsx b/src/components/home/VerifySection/ActionLoader.tsx new file mode 100644 index 0000000..03c548b --- /dev/null +++ b/src/components/home/VerifySection/ActionLoader.tsx @@ -0,0 +1,91 @@ +import React, { useEffect } from 'react' +import { useLocation, useNavigate } from 'react-router-dom' +import { decryptString } from '@trustvc/trustvc' + +interface ActionLoaderProps { + loadDocument: ( + doc: unknown, + chainId: string | null | undefined, + name: string + ) => Promise +} + +export const ActionLoader: React.FC = ({ loadDocument }) => { + const location = useLocation() + const navigate = useNavigate() + + useEffect(() => { + const params = new URLSearchParams(location.search) + const query = params.get('q') + if (!query) return + + // Decode optional decryption key from URL hash — anchor key takes priority over payload key + const anchorStr = decodeURIComponent(location.hash.substring(1)) + const anchor: { key?: string } = anchorStr + ? (() => { + try { + return JSON.parse(anchorStr) + } catch { + return {} + } + })() + : {} + + // Clean URL immediately so a refresh doesn't re-trigger + navigate('/', { replace: true }) + ;(async () => { + try { + const action = JSON.parse(decodeURIComponent(query)) + const { type, payload } = action ?? {} + + if (type !== 'DOCUMENT' || !payload?.uri) return + + const { uri, chainId, key: payloadKey } = payload + const key: string | undefined = anchor.key || payloadKey + + let document = await window.fetch(uri).then(response => { + if (response.status >= 400 && response.status < 600) { + throw new Error(`Unable to load the document from ${uri}`) + } + return response.json() + }) + + // opencerts-function returns the document in a nested document object + document = document.document || document + + if (!document) { + throw new Error(`Document at ${uri} is empty`) + } + + // will only decrypt if type is `OPEN-ATTESTATION-TYPE-1` + if (document.type === 'OPEN-ATTESTATION-TYPE-1') { + if (key) { + const decrypted = decryptString({ + tag: document.tag, + cipherText: document.cipherText, + iv: document.iv, + key, + type: document.type, + }) + document = JSON.parse(decrypted) + } else { + throw new Error( + `Unable to decrypt document with key=${key} and type=${document.type}` + ) + } + } + + const name = uri.split('/').pop() || 'document.json' + await loadDocument( + document, + chainId != null ? String(chainId) : null, + name + ) + } catch (err) { + console.error('ActionLoader: failed to load document from URL', err) + } + })() + }, []) // eslint-disable-line react-hooks/exhaustive-deps + + return null +} diff --git a/src/components/home/VerifySection/ObfuscatedMessage.tsx b/src/components/home/VerifySection/ObfuscatedMessage.tsx index 01ecc8c..d877905 100644 --- a/src/components/home/VerifySection/ObfuscatedMessage.tsx +++ b/src/components/home/VerifySection/ObfuscatedMessage.tsx @@ -34,6 +34,8 @@ export const ObfuscatedMessage: FunctionComponent = ({ return (
) => { diff --git a/src/components/home/VerifySection/VerifySection.tsx b/src/components/home/VerifySection/VerifySection.tsx index 8d280ee..613af20 100644 --- a/src/components/home/VerifySection/VerifySection.tsx +++ b/src/components/home/VerifySection/VerifySection.tsx @@ -1,5 +1,6 @@ import React from 'react' import { useVerify } from './useVerify' +import { ActionLoader } from './ActionLoader' import NetworkModal from './NetworkModal' import VerifyResult from './VerifyResult' import VerifyError from './VerifyError' @@ -52,6 +53,7 @@ const VerifySection: React.FC = ({ isDarkMode }) => { handleReset, handleNetworkConfirm, handleNetworkCancel, + loadDocument, } = useVerify() const { showOverlay, closeOverlay } = useOverlayContext() const handleConnectWallet = async () => { @@ -146,95 +148,98 @@ const VerifySection: React.FC = ({ isDarkMode }) => { ) return ( -
-
- {showEndorsementChain && ( - - )} -
-
- {verifyStatus === 'idle' && renderDropzone()} - {verifyStatus === 'verifying' && renderVerifying()} - {verifyStatus === 'network-select' && renderDropzone()} - {verifyStatus === 'valid' && ( - - )} + <> + +
+
+ {showEndorsementChain && ( + + )} +
+
+ {verifyStatus === 'idle' && renderDropzone()} + {verifyStatus === 'verifying' && renderVerifying()} + {verifyStatus === 'network-select' && renderDropzone()} + {verifyStatus === 'valid' && ( + + )} - {(verifyStatus === 'invalid' || verifyStatus === 'error') && ( - - )} - {verifyStatus === 'network-select' && ( - - )} -
-
-
-
Try our demo document!
-
-
-
- Experience the interoperability of our documents from the - documents gallery! + {(verifyStatus === 'invalid' || verifyStatus === 'error') && ( + + )} + {verifyStatus === 'network-select' && ( + + )} +
+
+
+
Try our demo document!
-
-
-
- +
+
+ +
-
+ ) } diff --git a/src/components/home/VerifySection/useVerify.test.ts b/src/components/home/VerifySection/useVerify.test.ts index 3f196b6..3da0e57 100644 --- a/src/components/home/VerifySection/useVerify.test.ts +++ b/src/components/home/VerifySection/useVerify.test.ts @@ -778,6 +778,147 @@ describe('useVerify', () => { }) }) + // ── loadDocument ────────────────────────────────────────────────────────── + + describe('loadDocument', () => { + it('sets fileName and transitions to valid on successful verification', async () => { + vi.mocked(verifyDocument).mockResolvedValue([ + { + name: 'OpenAttestationHash', + status: 'VALID', + type: 'DOCUMENT_INTEGRITY', + }, + ]) + vi.mocked(isTransferableRecord).mockReturnValue(false) + vi.mocked(isDocumentRevokable).mockReturnValue(false) + + const { result } = renderHook(() => useVerify(), { wrapper }) + + await act(async () => { + await result.current.loadDocument( + { test: true }, + '11155111', + 'action-doc.json' + ) + }) + + await waitFor(() => expect(result.current.verifyStatus).toBe('valid')) + expect(result.current.fileName).toBe('action-doc.json') + }) + + it('transitions through verifying before settling to valid', async () => { + let resolveFn!: (v: any) => void + vi.mocked(verifyDocument).mockReturnValue( + new Promise(res => { + resolveFn = res + }) + ) + vi.mocked(isTransferableRecord).mockReturnValue(false) + vi.mocked(isDocumentRevokable).mockReturnValue(false) + + const { result } = renderHook(() => useVerify(), { wrapper }) + + act(() => { + result.current.loadDocument({ test: true }, '1', 'doc.json') + }) + + expect(result.current.verifyStatus).toBe('verifying') + + await act(async () => { + resolveFn([ + { + name: 'OpenAttestationHash', + status: 'VALID', + type: 'DOCUMENT_INTEGRITY', + }, + ]) + }) + await waitFor(() => expect(result.current.verifyStatus).toBe('valid')) + }) + + it('resolves to invalid when fragments are invalid', async () => { + vi.mocked(verifyDocument).mockResolvedValue([ + { + name: 'OpenAttestationHash', + status: 'INVALID', + type: 'DOCUMENT_INTEGRITY', + }, + ]) + vi.mocked(isTransferableRecord).mockReturnValue(false) + vi.mocked(isDocumentRevokable).mockReturnValue(false) + + const { result } = renderHook(() => useVerify(), { wrapper }) + + await act(async () => { + await result.current.loadDocument({ test: true }, '1', 'doc.json') + }) + + await waitFor(() => expect(result.current.verifyStatus).toBe('invalid')) + }) + + it('sets error state when verifyDocument rejects', async () => { + vi.mocked(verifyDocument).mockRejectedValue(new Error('RPC down')) + vi.mocked(isTransferableRecord).mockReturnValue(false) + vi.mocked(isDocumentRevokable).mockReturnValue(false) + + const { result } = renderHook(() => useVerify(), { wrapper }) + + await act(async () => { + await result.current.loadDocument({ test: true }, '1', 'doc.json') + }) + + await waitFor(() => expect(result.current.verifyStatus).toBe('error')) + expect(result.current.errorType).toBe(TYPES.VERIFICATION_ERROR) + }) + + it('overwrites fileName when called a second time', async () => { + vi.mocked(verifyDocument).mockResolvedValue([ + { + name: 'OpenAttestationHash', + status: 'VALID', + type: 'DOCUMENT_INTEGRITY', + }, + ]) + vi.mocked(isTransferableRecord).mockReturnValue(false) + vi.mocked(isDocumentRevokable).mockReturnValue(false) + + const { result } = renderHook(() => useVerify(), { wrapper }) + + await act(async () => { + await result.current.loadDocument({ v: 1 }, '1', 'first.json') + }) + await waitFor(() => expect(result.current.verifyStatus).toBe('valid')) + + await act(async () => { + await result.current.loadDocument({ v: 2 }, '137', 'second.json') + }) + await waitFor(() => expect(result.current.verifyStatus).toBe('valid')) + + expect(result.current.fileName).toBe('second.json') + }) + + it('accepts null chainId and still calls verifyDocument', async () => { + vi.mocked(verifyDocument).mockResolvedValue([ + { + name: 'OpenAttestationHash', + status: 'VALID', + type: 'DOCUMENT_INTEGRITY', + }, + ]) + vi.mocked(isTransferableRecord).mockReturnValue(false) + vi.mocked(isDocumentRevokable).mockReturnValue(false) + + const { result } = renderHook(() => useVerify(), { wrapper }) + + await act(async () => { + await result.current.loadDocument({ test: true }, null, 'doc.json') + }) + + await waitFor(() => expect(result.current.verifyStatus).toBe('valid')) + expect(verifyDocument).toHaveBeenCalledTimes(1) + }) + }) + // ── getErrorTypeFromFragments ─────────────────────────────────────────────── describe('getErrorTypeFromFragments', () => { diff --git a/src/components/home/VerifySection/useVerify.ts b/src/components/home/VerifySection/useVerify.ts index 0bbeae0..abe37f6 100644 --- a/src/components/home/VerifySection/useVerify.ts +++ b/src/components/home/VerifySection/useVerify.ts @@ -75,6 +75,11 @@ export interface UseVerifyReturn { handleReset: () => void handleNetworkConfirm: (_chainId: string) => void handleNetworkCancel: () => void + loadDocument: ( + _doc: unknown, + _chainId: string | null | undefined, + _name: string + ) => Promise } const computeGroupStatus = ( @@ -508,6 +513,27 @@ export const useVerify = (): UseVerifyReturn => { } } + const loadDocument = async ( + doc: unknown, + chainId: string | null | undefined, + name: string + ) => { + const currentId = ++verificationIdRef.current + setFileName(name) + setVerifyStatus('verifying') + setFragments([]) + setPendingDoc(null) + clearVerificationMetadata() + + try { + await runVerification(doc, chainId, currentId) + } catch (err) { + clearVerificationMetadata() + setErrorType(getErrorTypeFromError(err)) + setVerifyStatus('error') + } + } + const handleReset = () => { setVerifyStatus('idle') setFragments([]) @@ -541,5 +567,6 @@ export const useVerify = (): UseVerifyReturn => { handleReset, handleNetworkConfirm, handleNetworkCancel, + loadDocument, } } diff --git a/src/data/capabilities.ts b/src/data/capabilities.ts new file mode 100644 index 0000000..e73a3c1 --- /dev/null +++ b/src/data/capabilities.ts @@ -0,0 +1,49 @@ +export interface Capability { + icon: string + tags: string[] + title: string + description: string +} + +const capabilities: Capability[] = [ + { + icon: '/images/about/single-source.svg', + tags: ['Transferable Record'], + title: 'Single Source of Truth', + description: + 'TrustVC uses a public blockchain to maintain a single source of truth for ETRs.', + }, + { + icon: '/images/about/unified-foundation.svg', + tags: ['Verifiable Document', 'Transferable Record'], + title: 'Unified Foundation', + description: + 'Single SDK powering multiple industry-specific verification solutions.', + }, + { + icon: '/images/about/global.svg', + tags: ['Verifiable Document', 'Transferable Record'], + title: 'Global Interoperability', + description: 'Cross-border verification utilising international standards.', + }, + { + icon: '/images/about/privacy.svg', + tags: ['Verifiable Document', 'Transferable Record'], + title: 'Privacy First', + description: 'Selective disclosure of data to protect user privacy.', + }, + { + icon: '/images/about/tamper.svg', + tags: ['Verifiable Document', 'Transferable Record'], + title: 'Tamper Evident', + description: 'Any modification invalidates the document.', + }, + { + icon: '/images/about/ecosystem.svg', + tags: ['Verifiable Document', 'Transferable Record'], + title: 'Ecosystem Approach', + description: 'Growing network of issuers, verifiers, and users worldwide.', + }, +] + +export default capabilities diff --git a/src/data/partners.ts b/src/data/partners.ts new file mode 100644 index 0000000..bbae7f0 --- /dev/null +++ b/src/data/partners.ts @@ -0,0 +1,687 @@ +import type { Partner } from '../types/partner' + +const partners: Partner[] = [ + { + name: 'AEOTRADE', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/AEOTRADE.png', + logo2x: + '/images/partners/2X/Card/Solution Provider/TradeTrust/AEOTRADE.png', + bannerLogo: '/images/partners/1X/Banner/AEOTRADE.png', + bannerLogo2x: '/images/partners/2X/Banner/AEOTRADE.png', + website: 'https://www.aeotrade.com', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'ASTROn', + logo: '/images/partners/1X/Card/Infrastructure/TradeTrust/ASTROn.png', + logo2x: '/images/partners/2X/Card/Infrastructure/TradeTrust/ASTROn.png', + bannerLogo: '/images/partners/1X/Banner/ASTROn.png', + bannerLogo2x: '/images/partners/2X/Banner/ASTROn.png', + website: 'https://bitfactory.cn', + description: '', + verticalType: 'TradeTrust', + category: 'Infrastructure', + }, + { + name: 'Angsana Technology', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/Angsana Technology.png', + logo2x: + '/images/partners/2X/Card/Solution Provider/TradeTrust/Angsana Technology.png', + bannerLogo: '/images/partners/1X/Banner/Angsana Technology.png', + bannerLogo2x: '/images/partners/2X/Banner/Angsana Technology.png', + website: 'https://angsanatech.com', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'Automaxis', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/Automaxis.png', + logo2x: + '/images/partners/2X/Card/Solution Provider/TradeTrust/Automaxis.png', + bannerLogo: '/images/partners/1X/Banner/Automaxis.png', + bannerLogo2x: '/images/partners/2X/Banner/Automaxis.png', + website: 'https://autom-axis.com', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'Banco', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/Banco.png', + logo2x: '/images/partners/2X/Card/Solution Provider/TradeTrust/Banco.png', + bannerLogo: '/images/partners/1X/Banner/Banco.png', + bannerLogo2x: '/images/partners/2X/Banner/Banco.png', + website: 'https://www.banco.com.sg', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'Bank of China', + logo: '/images/partners/1X/Card/Verification Validation/TradeTrust/Bank of China.png', + logo2x: + '/images/partners/2X/Card/Verification Validation/TradeTrust/Bank of China.png', + bannerLogo: '/images/partners/1X/Banner/Bank of China.png', + bannerLogo2x: '/images/partners/2X/Banner/Bank of China.png', + website: 'https://www.boc.cn/en/', + description: '', + verticalType: 'TradeTrust', + category: 'Verification & Validation', + }, + { + name: 'BlockPeer', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/BlockPeer.png', + logo2x: + '/images/partners/2X/Card/Solution Provider/TradeTrust/BlockPeer.png', + bannerLogo: '/images/partners/1X/Banner/BlockPeer.png', + bannerLogo2x: '/images/partners/2X/Banner/BlockPeer.png', + website: 'https://www.blockpeer.finance', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'BunkerChain', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/BunkerChain.png', + logo2x: + '/images/partners/2X/Card/Solution Provider/TradeTrust/BunkerChain.png', + bannerLogo: '/images/partners/1X/Banner/BunkerChain.png', + bannerLogo2x: '/images/partners/2X/Banner/BunkerChain.png', + website: 'https://bunkerchain.io', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'CALISTA', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/CALISTA.png', + logo2x: '/images/partners/2X/Card/Solution Provider/TradeTrust/CALISTA.png', + bannerLogo: '/images/partners/1X/Banner/CALISTA.png', + bannerLogo2x: '/images/partners/2X/Banner/CALISTA.png', + website: 'https://calistang.globaletrade.services/cng/home', + description: '', + verticalType: 'TradeTrust', + category: 'Infrastructure', + }, + { + name: 'COFCO', + logo: '/images/partners/1X/Card/Issuance Attestation/TradeTrust/COFCO.png', + logo2x: + '/images/partners/2X/Card/Issuance Attestation/TradeTrust/COFCO.png', + bannerLogo: '/images/partners/1X/Banner/COFCO.png', + bannerLogo2x: '/images/partners/2X/Banner/COFCO.png', + website: 'https://www.cofcointernational.com', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'CargoX', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/CargoX.png', + logo2x: '/images/partners/2X/Card/Solution Provider/TradeTrust/CargoX.png', + bannerLogo: '/images/partners/1X/Banner/CargoX.png', + bannerLogo2x: '/images/partners/2X/Banner/CargoX.png', + website: 'https://cargox.io', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'ChainDoX', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/ChainDoX.png', + logo2x: + '/images/partners/2X/Card/Solution Provider/TradeTrust/ChainDoX.png', + bannerLogo: '/images/partners/1X/Banner/ChainDoX.png', + bannerLogo2x: '/images/partners/2X/Banner/ChainDoX.png', + website: 'https://chaindox.com/', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'Credore', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/Credore.png', + logo2x: '/images/partners/2X/Card/Solution Provider/TradeTrust/Credore.png', + bannerLogo: '/images/partners/1X/Banner/Credore.png', + bannerLogo2x: '/images/partners/2X/Banner/Credore.png', + website: 'https://www.credore.xyz', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'DBS Group', + logo: '/images/partners/1X/Card/Verification Validation/TradeTrust/DBS Group.png', + logo2x: + '/images/partners/2X/Card/Verification Validation/TradeTrust/DBS Group.png', + bannerLogo: '/images/partners/1X/Banner/DBS Group.png', + bannerLogo2x: '/images/partners/2X/Banner/DBS Group.png', + website: 'https://www.dbsg.com/', + description: '', + verticalType: 'TradeTrust', + category: 'Verification & Validation', + }, + { + name: 'DIMUTO', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/DIMUTO.png', + logo2x: '/images/partners/2X/Card/Solution Provider/TradeTrust/DIMUTO.png', + bannerLogo: '/images/partners/1X/Banner/DIMUTO.png', + bannerLogo2x: '/images/partners/2X/Banner/DIMUTO.png', + website: 'https://dimuto.io', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'DLTLedgers', + logo: '/images/partners/1X/Card/Infrastructure/TradeTrust/DLTLedgers.png', + logo2x: '/images/partners/2X/Card/Infrastructure/TradeTrust/DLTLedgers.png', + bannerLogo: '/images/partners/1X/Banner/DLTLedgers.png', + bannerLogo2x: '/images/partners/2X/Banner/DLTLedgers.png', + website: 'https://dlt.sg/', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'DOCKLAB', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/DOCKLAB.png', + logo2x: '/images/partners/2X/Card/Solution Provider/TradeTrust/DOCKLAB.png', + bannerLogo: '/images/partners/1X/Banner/DOCKLAB.png', + bannerLogo2x: '/images/partners/2X/Banner/DOCKLAB.png', + website: 'https://docklab.nl', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'Docsonblocks', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/Docsonblocks.png', + logo2x: + '/images/partners/2X/Card/Solution Provider/TradeTrust/Docsonblocks.png', + bannerLogo: '/images/partners/1X/Banner/Docsonblocks.png', + bannerLogo2x: '/images/partners/2X/Banner/Docsonblocks.png', + website: 'https://app.docsonblocks.com/', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'DocuShield', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/DocuShield.png', + logo2x: + '/images/partners/2X/Card/Solution Provider/TradeTrust/DocuShield.png', + bannerLogo: '/images/partners/1X/Banner/DocuShield.png', + bannerLogo2x: '/images/partners/2X/Banner/DocuShield.png', + website: 'https://www.docushield.co.in/', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'DocuTrade', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/DocuTrade.png', + logo2x: + '/images/partners/2X/Card/Solution Provider/TradeTrust/DocuTrade.png', + bannerLogo: '/images/partners/1X/Banner/DocuTrade.png', + bannerLogo2x: '/images/partners/2X/Banner/DocuTrade.png', + website: 'https://docutrade.io', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'FUIX LABS', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/FUIX LABS.png', + logo2x: + '/images/partners/2X/Card/Solution Provider/TradeTrust/FUIX LABS.png', + bannerLogo: '/images/partners/1X/Banner/FUIX LABS.png', + bannerLogo2x: '/images/partners/2X/Banner/FUIX LABS.png', + website: 'https://fuixlabs.com', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'FilPass', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/FilPass.png', + logo2x: '/images/partners/2X/Card/Solution Provider/TradeTrust/FilPass.png', + bannerLogo: '/images/partners/1X/Banner/FilPass.png', + bannerLogo2x: '/images/partners/2X/Banner/FilPass.png', + website: 'https://filpass.ph', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'GUUD', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/GUUD.png', + logo2x: '/images/partners/2X/Card/Solution Provider/TradeTrust/GUUD.png', + bannerLogo: '/images/partners/1X/Banner/GUUD.png', + bannerLogo2x: '/images/partners/2X/Banner/GUUD.png', + website: 'https://guud.company', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'ICICI Bank', + logo: '/images/partners/1X/Card/Issuance Attestation/TradeTrust/ICICI Bank.png', + logo2x: + '/images/partners/2X/Card/Issuance Attestation/TradeTrust/ICICI Bank.png', + bannerLogo: '/images/partners/1X/Banner/ICICI Bank.png', + bannerLogo2x: '/images/partners/2X/Banner/ICICI Bank.png', + website: 'https://www.icicibank.com', + description: '', + verticalType: 'TradeTrust', + category: 'Verification & Validation', + }, + { + name: 'Institute of Technical Education', + logo: '/images/partners/1X/Card/Issuance Attestation/OpenCert/Institute of Technical Education.png', + logo2x: + '/images/partners/2X/Card/Issuance Attestation/OpenCert/Institute of Technical Education.png', + bannerLogo: + '/images/partners/1X/Banner/Institute of Technical Education.png', + bannerLogo2x: + '/images/partners/2X/Banner/Institute of Technical Education.png', + website: 'https://www.ite.edu.sg', + description: '', + verticalType: 'OpenCerts', + category: 'Issuance & Attestation', + }, + { + name: 'JSLA', + logo: '/images/partners/1X/Card/Issuance Attestation/TradeTrust/JSLA.png', + logo2x: '/images/partners/2X/Card/Issuance Attestation/TradeTrust/JSLA.png', + bannerLogo: '/images/partners/1X/Banner/JSLA.png', + bannerLogo2x: '/images/partners/2X/Banner/JSLA.png', + website: '', + description: '', + verticalType: 'TradeTrust', + category: 'Issuance & Attestation', + }, + { + name: 'JUPYTON', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/JUPYTON.png', + logo2x: '/images/partners/2X/Card/Solution Provider/TradeTrust/JUPYTON.png', + bannerLogo: '/images/partners/1X/Banner/JUPYTON.png', + bannerLogo2x: '/images/partners/2X/Banner/JUPYTON.png', + website: 'https://jupyton.com', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'Jed', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/Jed.png', + logo2x: '/images/partners/2X/Card/Solution Provider/TradeTrust/Jed.png', + bannerLogo: '/images/partners/1X/Banner/Jed.png', + bannerLogo2x: '/images/partners/2X/Banner/Jed.png', + website: 'https://www.jedtrade.com', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'LASALLE College of the Arts', + logo: '/images/partners/1X/Card/Issuance Attestation/OpenCert/LASALLE College of the Arts.png', + logo2x: + '/images/partners/2X/Card/Issuance Attestation/OpenCert/LASALLE College of the Arts.png', + bannerLogo: '/images/partners/1X/Banner/LASALLE College of the Arts.png', + bannerLogo2x: '/images/partners/2X/Banner/LASALLE College of the Arts.png', + website: 'https://www.lasalle.edu.sg', + description: '', + verticalType: 'OpenCerts', + category: 'Issuance & Attestation', + }, + { + name: 'Linklogis', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/Linklogis.png', + logo2x: + '/images/partners/2X/Card/Solution Provider/TradeTrust/Linklogis.png', + bannerLogo: '/images/partners/1X/Banner/Linklogis.png', + bannerLogo2x: '/images/partners/2X/Banner/Linklogis.png', + website: 'https://www.linklogis.com/en/', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'MAPTRASCO', + logo: '/images/partners/1X/Card/Issuance Attestation/TradeTrust/MAPTRASCO.png', + logo2x: + '/images/partners/2X/Card/Issuance Attestation/TradeTrust/MAPTRASCO.png', + bannerLogo: '/images/partners/1X/Banner/MAPTRASCO.png', + bannerLogo2x: '/images/partners/2X/Banner/MAPTRASCO.png', + website: 'https://khaitan.com.sg/', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'Morpheus.Network', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/Morpheus.Network.png', + logo2x: + '/images/partners/2X/Card/Solution Provider/TradeTrust/Morpheus.Network.png', + bannerLogo: '/images/partners/1X/Banner/Morpheus.Network.png', + bannerLogo2x: '/images/partners/2X/Banner/Morpheus.Network.png', + website: 'https://morpheus.network', + description: '', + verticalType: 'TradeTrust', + category: 'Infrastructure', + }, + { + name: 'NAFA', + logo: '/images/partners/1X/Card/Issuance Attestation/OpenCert/NAFA.png', + logo2x: '/images/partners/2X/Card/Issuance Attestation/OpenCert/NAFA.png', + bannerLogo: '/images/partners/1X/Banner/NAFA.png', + bannerLogo2x: '/images/partners/2X/Banner/NAFA.png', + website: 'https://www.nafa.edu.sg', + description: '', + verticalType: 'OpenCerts', + category: 'Issuance & Attestation', + }, + { + name: 'NIEC', + logo: '/images/partners/1X/Card/Issuance Attestation/OpenCert/NIEC.png', + logo2x: '/images/partners/2X/Card/Issuance Attestation/OpenCert/NIEC.png', + bannerLogo: '/images/partners/1X/Banner/NIEC.png', + bannerLogo2x: '/images/partners/2X/Banner/NIEC.png', + website: 'https://niec.edu.sg', + description: '', + verticalType: 'OpenCerts', + category: 'Issuance & Attestation', + }, + { + name: 'Nanyang Polytechnic', + logo: '/images/partners/1X/Card/Issuance Attestation/OpenCert/Nanyang Polytechnic.png', + logo2x: + '/images/partners/2X/Card/Issuance Attestation/OpenCert/Nanyang Polytechnic.png', + bannerLogo: '/images/partners/1X/Banner/Nanyang Polytechnic.png', + bannerLogo2x: '/images/partners/2X/Banner/Nanyang Polytechnic.png', + website: 'https://www.nyp.edu.sg', + description: '', + verticalType: 'OpenCerts', + category: 'Issuance & Attestation', + }, + { + name: 'National University of Singapore', + logo: '/images/partners/1X/Card/Issuance Attestation/OpenCert/National University of Singapore.png', + logo2x: + '/images/partners/2X/Card/Issuance Attestation/OpenCert/National University of Singapore.png', + bannerLogo: + '/images/partners/1X/Banner/National University of Singapore.png', + bannerLogo2x: + '/images/partners/2X/Banner/National University of Singapore.png', + website: 'https://nus.edu.sg', + description: '', + verticalType: 'OpenCerts', + category: 'Issuance & Attestation', + }, + { + name: 'Ngee Ann Polytechnic', + logo: '/images/partners/1X/Card/Issuance Attestation/OpenCert/Ngee Ann Polytechnic.png', + logo2x: + '/images/partners/2X/Card/Issuance Attestation/OpenCert/Ngee Ann Polytechnic.png', + bannerLogo: '/images/partners/1X/Banner/Ngee Ann Polytechnic.png', + bannerLogo2x: '/images/partners/2X/Banner/Ngee Ann Polytechnic.png', + website: 'https://www.np.edu.sg', + description: '', + verticalType: 'OpenCerts', + category: 'Issuance & Attestation', + }, + { + name: 'Pacific International Lines', + logo: '/images/partners/1X/Card/Issuance Attestation/TradeTrust/Pacific International Lines.png', + logo2x: + '/images/partners/2X/Card/Issuance Attestation/TradeTrust/Pacific International Lines.png', + bannerLogo: '/images/partners/1X/Banner/Pacific International Lines.png', + bannerLogo2x: '/images/partners/2X/Banner/Pacific International Lines.png', + website: 'https://www.pilship.com', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'Republic Polytechnic', + logo: '/images/partners/1X/Card/Issuance Attestation/OpenCert/Republic Polytechnic.png', + logo2x: + '/images/partners/2X/Card/Issuance Attestation/OpenCert/Republic Polytechnic.png', + bannerLogo: '/images/partners/1X/Banner/Republic Polytechnic.png', + bannerLogo2x: '/images/partners/2X/Banner/Republic Polytechnic.png', + website: 'https://www.rp.edu.sg', + description: '', + verticalType: 'OpenCerts', + category: 'Issuance & Attestation', + }, + { + name: 'SECRO', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/SECRO.png', + logo2x: '/images/partners/2X/Card/Solution Provider/TradeTrust/SECRO.png', + bannerLogo: '/images/partners/1X/Banner/SECRO.png', + bannerLogo2x: '/images/partners/2X/Banner/SECRO.png', + website: 'https://secro.io', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'SGTraDex', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/SGTraDex.png', + logo2x: + '/images/partners/2X/Card/Solution Provider/TradeTrust/SGTraDex.png', + bannerLogo: '/images/partners/1X/Banner/SGTraDex.png', + bannerLogo2x: '/images/partners/2X/Banner/SGTraDex.png', + website: 'https://sgtradex.com', + description: '', + verticalType: 'TradeTrust', + category: 'Infrastructure', + }, + { + name: 'SMU', + logo: '/images/partners/1X/Card/Issuance Attestation/OpenCert/SMU.png', + logo2x: '/images/partners/2X/Card/Issuance Attestation/OpenCert/SMU.png', + bannerLogo: '/images/partners/1X/Banner/SMU.png', + bannerLogo2x: '/images/partners/2X/Banner/SMU.png', + website: 'https://www.smu.edu.sg', + description: '', + verticalType: 'OpenCerts', + category: 'Issuance & Attestation', + }, + { + name: 'STABILITY', + logo: '/images/partners/1X/Card/Infrastructure/TradeTrust/STABILITY.png', + logo2x: '/images/partners/2X/Card/Infrastructure/TradeTrust/STABILITY.png', + bannerLogo: '/images/partners/1X/Banner/STABILITY.png', + bannerLogo2x: '/images/partners/2X/Banner/STABILITY.png', + website: 'https://stabilityprotocol.com', + description: '', + verticalType: 'TradeTrust', + category: 'Infrastructure', + }, + { + name: 'Singapore Examinations and Assessment Board', + logo: '/images/partners/1X/Card/Issuance Attestation/OpenCert/Singapore Examinations and Assessment Board.png', + logo2x: + '/images/partners/2X/Card/Issuance Attestation/OpenCert/Singapore Examinations and Assessment Board.png', + bannerLogo: + '/images/partners/1X/Banner/Singapore Examinations and Assessment Board.png', + bannerLogo2x: + '/images/partners/2X/Banner/Singapore Examinations and Assessment Board.png', + website: 'https://www.seab.gov.sg', + description: '', + verticalType: 'OpenCerts', + category: 'Issuance & Attestation', + }, + { + name: 'Singapore Polytechnic', + logo: '/images/partners/1X/Card/Issuance Attestation/OpenCert/Singapore Polytechnic.png', + logo2x: + '/images/partners/2X/Card/Issuance Attestation/OpenCert/Singapore Polytechnic.png', + bannerLogo: '/images/partners/1X/Banner/Singapore Polytechnic.png', + bannerLogo2x: '/images/partners/2X/Banner/Singapore Polytechnic.png', + website: 'https://www.sp.edu.sg', + description: '', + verticalType: 'OpenCerts', + category: 'Issuance & Attestation', + }, + { + name: 'Singapore University of Social Sciences', + logo: '/images/partners/1X/Card/Issuance Attestation/OpenCert/Singapore University of Social Sciences.png', + logo2x: + '/images/partners/2X/Card/Issuance Attestation/OpenCert/Singapore University of Social Sciences.png', + bannerLogo: + '/images/partners/1X/Banner/Singapore University of Social Sciences.png', + bannerLogo2x: + '/images/partners/2X/Banner/Singapore University of Social Sciences.png', + website: 'https://www.suss.edu.sg', + description: '', + verticalType: 'OpenCerts', + category: 'Issuance & Attestation', + }, + { + name: 'SkillsFuture SG', + logo: '/images/partners/1X/Card/Issuance Attestation/OpenCert/SkillsFuture SG.png', + logo2x: + '/images/partners/2X/Card/Issuance Attestation/OpenCert/SkillsFuture SG.png', + bannerLogo: '/images/partners/1X/Banner/SkillsFuture SG.png', + bannerLogo2x: '/images/partners/2X/Banner/SkillsFuture SG.png', + website: 'https://www.skillsfuture.gov.sg', + description: '', + verticalType: 'OpenCerts', + category: 'Issuance & Attestation', + }, + { + name: 'TASConnect', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/TASConnect.png', + logo2x: + '/images/partners/2X/Card/Solution Provider/TradeTrust/TASConnect.png', + bannerLogo: '/images/partners/1X/Banner/TASConnect.png', + bannerLogo2x: '/images/partners/2X/Banner/TASConnect.png', + website: 'https://tasconnect.com', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'TRAMÉS', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/TRAMÉS.png', + logo2x: '/images/partners/2X/Card/Solution Provider/TradeTrust/TRAMÉS.png', + bannerLogo: '/images/partners/1X/Banner/TRAMÉS.png', + bannerLogo2x: '/images/partners/2X/Banner/TRAMÉS.png', + website: 'https://trames.io', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'Temasek Polytechnic', + logo: '/images/partners/1X/Card/Issuance Attestation/OpenCert/Temasek Polytechnic.png', + logo2x: + '/images/partners/2X/Card/Issuance Attestation/OpenCert/Temasek Polytechnic.png', + bannerLogo: '/images/partners/1X/Banner/Temasek Polytechnic.png', + bannerLogo2x: '/images/partners/2X/Banner/Temasek Polytechnic.png', + website: 'https://www.tp.edu.sg', + description: '', + verticalType: 'OpenCerts', + category: 'Issuance & Attestation', + }, + { + name: 'TradeGo', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/TradeGo.png', + logo2x: '/images/partners/2X/Card/Solution Provider/TradeTrust/TradeGo.png', + bannerLogo: '/images/partners/1X/Banner/TradeGo.png', + bannerLogo2x: '/images/partners/2X/Banner/TradeGo.png', + website: 'https://tradego.com', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'UOB', + logo: '/images/partners/1X/Card/Verification Validation/TradeTrust/UOB.png', + logo2x: + '/images/partners/2X/Card/Verification Validation/TradeTrust/UOB.png', + bannerLogo: '/images/partners/1X/Banner/UOB.png', + bannerLogo2x: '/images/partners/2X/Banner/UOB.png', + website: 'https://www.uobgroup.com', + description: '', + verticalType: 'TradeTrust', + category: 'Verification & Validation', + }, + { + name: 'VAYANA', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/VAYANA.png', + logo2x: '/images/partners/2X/Card/Solution Provider/TradeTrust/VAYANA.png', + bannerLogo: '/images/partners/1X/Banner/VAYANA.png', + bannerLogo2x: '/images/partners/2X/Banner/VAYANA.png', + website: 'https://www.vayana.com', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'XDC Network', + logo: '/images/partners/1X/Card/Infrastructure/TradeTrust/XDC Network.png', + logo2x: + '/images/partners/2X/Card/Infrastructure/TradeTrust/XDC Network.png', + bannerLogo: '/images/partners/1X/Banner/XDC Network.png', + bannerLogo2x: '/images/partners/2X/Banner/XDC Network.png', + website: 'https://xdc.org', + description: '', + verticalType: 'TradeTrust', + category: 'Infrastructure', + }, + { + name: 'YIT HONG PTE LTD', + logo: '/images/partners/1X/Card/Issuance Attestation/TradeTrust/YIT HONG PTE LTD.png', + logo2x: + '/images/partners/2X/Card/Issuance Attestation/TradeTrust/YIT HONG PTE LTD.png', + bannerLogo: '/images/partners/1X/Banner/YIT HONG PTE LTD.png', + bannerLogo2x: '/images/partners/2X/Banner/YIT HONG PTE LTD.png', + website: 'https://www.yithong.com', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'ZenithBlox', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/ZenithBlox.png', + logo2x: + '/images/partners/2X/Card/Solution Provider/TradeTrust/ZenithBlox.png', + bannerLogo: '/images/partners/1X/Banner/ZenithBlox.png', + bannerLogo2x: '/images/partners/2X/Banner/ZenithBlox.png', + website: 'https://zenithblox.network', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'eTEU', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/eTEU.png', + logo2x: '/images/partners/2X/Card/Solution Provider/TradeTrust/eTEU.png', + bannerLogo: '/images/partners/1X/Banner/eTEU.png', + bannerLogo2x: '/images/partners/2X/Banner/eTEU.png', + website: 'https://eteu.co.uk', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, + { + name: 'veriTAG', + logo: '/images/partners/1X/Card/Solution Providers/TradeTrust/veriTAG.png', + logo2x: '/images/partners/2X/Card/Solution Provider/TradeTrust/veriTAG.png', + bannerLogo: '/images/partners/1X/Banner/veriTAG.png', + bannerLogo2x: '/images/partners/2X/Banner/veriTAG.png', + website: 'https://veritag.com', + description: '', + verticalType: 'TradeTrust', + category: 'Solution Partners', + }, +] + +export default partners diff --git a/src/index.css b/src/index.css index 40426b9..cb5f3d2 100644 --- a/src/index.css +++ b/src/index.css @@ -184,6 +184,203 @@ body.dark-mode { background-repeat: no-repeat; } +.app-shell--partners-light { + background-image: + url('/backgrounds/motif-left.png'), url('/backgrounds/motif-right.png'), + radial-gradient( + 84.7% 119.21% at 50% 15.3%, + #ffffff 0%, + rgba(223, 225, 255, 0.33) 100% + ); + background-size: + auto 100vh, + auto 100vh, + cover; + background-position: + left top, + right top, + center; + background-repeat: no-repeat, no-repeat, no-repeat; + min-width: 320px; + overflow-x: hidden; +} + +.app-shell--partners-dark { + background-image: + url('/backgrounds/motif-left.png'), url('/backgrounds/motif-right.png'), + radial-gradient( + 84.7% 119.21% at 50% 15.3%, + #1e2026 0%, + rgba(31, 27, 69, 0.33) 100% + ); + background-size: + auto 100vh, + auto 100vh, + cover; + background-position: + left top, + right top, + center; + background-repeat: no-repeat, no-repeat, no-repeat; + min-width: 320px; + overflow-x: hidden; +} + +@media (max-width: 639px) { + .app-shell--partners-light { + background-image: radial-gradient( + 84.7% 119.21% at 50% 15.3%, + #ffffff 0%, + rgba(223, 225, 255, 0.33) 100% + ); + background-size: cover; + background-position: center; + } + + .app-shell--partners-dark { + background-image: radial-gradient( + 84.7% 119.21% at 50% 15.3%, + #1e2026 0%, + rgba(31, 27, 69, 0.33) 100% + ); + background-size: cover; + background-position: center; + } +} + +.app-shell--about-light { + background-image: + url('/backgrounds/motif-left.png'), url('/backgrounds/motif-right.png'), + url('/backgrounds/bottom-backgound-grid.svg'), + radial-gradient( + 84.7% 119.21% at 50% 15.3%, + #ffffff 0%, + rgba(223, 225, 255, 0.33) 100% + ); + background-size: + auto 100vh, + auto 100vh, + 100% auto, + cover; + background-position: + left top, + right top, + bottom center, + center; + background-repeat: no-repeat, no-repeat, no-repeat, no-repeat; + min-width: 320px; + overflow-x: hidden; +} + +.app-shell--about-dark { + background-image: + url('/backgrounds/motif-left.png'), url('/backgrounds/motif-right.png'), + url('/backgrounds/bottom-backgound-grid.svg'), + radial-gradient( + 84.7% 119.21% at 50% 15.3%, + #1e2026 0%, + rgba(31, 27, 69, 0.33) 100% + ); + background-size: + auto 100vh, + auto 100vh, + 100% auto, + cover; + background-position: + left top, + right top, + bottom center, + center; + background-repeat: no-repeat, no-repeat, no-repeat, no-repeat; + min-width: 320px; + overflow-x: hidden; +} + +@media (max-width: 639px) { + .app-shell--about-light { + background-image: + url('/backgrounds/bottom-backgound-grid.svg'), + radial-gradient( + 84.7% 119.21% at 50% 15.3%, + #ffffff 0%, + rgba(223, 225, 255, 0.33) 100% + ); + background-size: + 100% auto, + cover; + background-position: + bottom center, + center; + } + + .app-shell--about-dark { + background-image: + url('/backgrounds/bottom-backgound-grid.svg'), + radial-gradient( + 84.7% 119.21% at 50% 15.3%, + #1e2026 0%, + rgba(31, 27, 69, 0.33) 100% + ); + background-size: + 100% auto, + cover; + background-position: center, center; + } +} + +.about-ecosystem-card { + position: relative; + overflow: hidden; + border-radius: 12px; + background: linear-gradient(97.83deg, #686ad2 10%, #167eb0 90%); + padding: 20px 30px; +} +.about-ecosystem-card-content { + position: relative; + background: #fff; + padding: 16px; + border-radius: 13px; + border: 1px solid rgba(169, 178, 187, 0.45); + box-sizing: border-box; +} +.about-ecosystem-card p { + background: none; + -webkit-background-clip: initial; + background-clip: initial; + -webkit-text-fill-color: #ffffff; +} + +.about-ecosystem-card::before { + content: ''; + display: block; + position: absolute; + top: 0; + right: 0; + width: 100%; + height: 100%; + background-image: url('/images/about/frame-top.svg'); + background-size: 100% auto; + background-position: top right; + background-repeat: no-repeat; + pointer-events: none; + z-index: 0; +} + +.about-ecosystem-card::after { + content: ''; + display: block; + position: absolute; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + background-image: url('/images/about/frame-bottom.svg'); + background-size: 100% auto; + background-position: bottom left; + background-repeat: no-repeat; + pointer-events: none; + z-index: 0; +} .app-shell--settings-light { background-image: url('/backgrounds/motif-left.png'), url('/backgrounds/motif-right.png'), @@ -1349,6 +1546,29 @@ p.small { } } +@keyframes marquee { + from { + transform: translateX(0); + } + to { + transform: translateX(-50%); + } +} + +/* Safari marquee fixes: pre-promote to GPU layer before animation starts */ +.animate-marquee { + -webkit-animation: marquee 200s linear infinite; + animation: marquee 200s linear infinite; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + will-change: transform; + /* translateZ(0) is intentionally on this element only, not its masked parent. + Combining WebkitMaskImage + 3D transform on the same element causes Safari + to drop the compositing layer, making child icons disappear. */ + -webkit-transform: translateZ(0); + transform: translateZ(0); +} + /* VerifySection - dropbox state variants */ .dropbox-area--centered { justify-content: center; @@ -4489,7 +4709,7 @@ p.small { z-index: 2; } -button, +button.solid, label.solid { --base: var(--primary-button-color, #5b5bb3); --hover-overlay: var(--Primary-33-40, #4d4b9854); diff --git a/src/pages/About/index.tsx b/src/pages/About/index.tsx new file mode 100644 index 0000000..2c0cf31 --- /dev/null +++ b/src/pages/About/index.tsx @@ -0,0 +1,67 @@ +import clsx from 'clsx' +import capabilities from '../../data/capabilities' +import CapabilityCard from '../../components/about/CapabilityCard' +import EcosystemCard from '../../components/about/EcosystemCard' + +interface AboutProps { + isDarkMode: boolean +} + +const About = ({ isDarkMode }: AboutProps) => ( +
+
+ {/* Hero */} +
+

+ + The Foundation of{' '} + + Digital Trust +

+

+ TrustVC serves as a core infrastructure layer enabling secure, + verifiable digital credentials across multiple industries and use + cases. +

+
+ +
+
+ +
+ + {/* Core Capabilities */} +
+

+ Core Capabilities +

+
+ +
+ {capabilities.map(cap => ( + + ))} +
+
+
+
+) + +export default About diff --git a/src/pages/Home/index.tsx b/src/pages/Home/index.tsx index 72469f3..26d1c69 100644 --- a/src/pages/Home/index.tsx +++ b/src/pages/Home/index.tsx @@ -2,6 +2,7 @@ import HeroSection from '../../components/home/HeroSection' import VerifySection from '../../components/home/VerifySection' import Carousel from '../../components/home/Carousel' import BuiltForDev from '../../components/home/BuiltForDev' +import PartnersSection from '../../components/home/PartnersSection' interface HomeProps { isDarkMode: boolean @@ -15,6 +16,7 @@ const Home = ({ isDarkMode }: HomeProps) => { +
) diff --git a/src/pages/Partners/index.tsx b/src/pages/Partners/index.tsx new file mode 100644 index 0000000..8eaaea0 --- /dev/null +++ b/src/pages/Partners/index.tsx @@ -0,0 +1,90 @@ +import { useState } from 'react' +import clsx from 'clsx' +import partners from '../../data/partners' +import PartnerCard from '../../components/common/PartnerCard' + +const CATEGORIES = [ + 'All', + 'Issuance & Attestation', + 'Verification & Validation', + 'Solution Partners', + 'Infrastructure', +] + +interface PartnersProps { + isDarkMode: boolean +} + +const Partners = ({ isDarkMode }: PartnersProps) => { + const [activeCategory, setActiveCategory] = useState('All') + + const filtered = + activeCategory === 'All' + ? partners + : partners.filter(p => p.category === activeCategory) + + return ( +
+
+ {/* Heading */} +
+

+ + Our{' '} + + Partners +

+

+ The Global Engine for Verifiable Documents and Transferable Records. +

+
+ + {/* Category filter */} +
+ {CATEGORIES.map(cat => ( + + ))} +
+ + {/* Grid */} +
+ {filtered.map(partner => ( + + ))} +
+
+
+ ) +} + +export default Partners diff --git a/src/routes.tsx b/src/routes.tsx index 9bad865..4f1ad0d 100644 --- a/src/routes.tsx +++ b/src/routes.tsx @@ -4,6 +4,8 @@ import Home from './pages/Home' import Contact from './pages/Contact' import Settings from './pages/Settings' import NotFound from './pages/NotFound' +import Partners from './pages/Partners' +import About from './pages/About' import NewsRouteFallback from './components/common/NewsRouteFallback' const News = lazy(() => import('./pages/News')) @@ -34,6 +36,8 @@ const AppRouter = ({ isDarkMode }: AppRouterProps) => { } /> + } /> + } /> } /> } /> } /> diff --git a/src/types/partner.ts b/src/types/partner.ts new file mode 100644 index 0000000..815e354 --- /dev/null +++ b/src/types/partner.ts @@ -0,0 +1,11 @@ +export interface Partner { + name: string + logo: string + logo2x?: string + bannerLogo?: string + bannerLogo2x?: string + website?: string + description?: string + verticalType?: string + category?: string +} diff --git a/tailwind.config.js b/tailwind.config.js index c14f305..0b5c6bb 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -70,6 +70,15 @@ export default { 'form-card': '0px 8px 32px rgba(104, 106, 210, 0.33)', 'form-card-dark': '0px 8px 32px 0px #686AD2', }, + keyframes: { + marquee: { + '0%': { transform: 'translateX(0)' }, + '100%': { transform: 'translateX(-50%)' }, + }, + }, + animation: { + marquee: 'marquee 200s linear infinite', + }, backgroundImage: { 'overlay-light': 'linear-gradient(0deg, rgba(255, 255, 255, 0.66), rgba(255, 255, 255, 0.66)), linear-gradient(0deg, rgba(222, 228, 233, 0), rgba(222, 228, 233, 0))',