mirror of
https://github.com/pezkuwichain/pwap.git
synced 2026-06-20 05:51:09 +00:00
Compare commits
9 Commits
f7c070e45b
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 070d682759 | |||
| cd56ab8fb6 | |||
| b012fcaaac | |||
| 7a1d3e7917 | |||
| 2ee3caac0d | |||
| 78e93e9766 | |||
| 83d66feacc | |||
| d6ace14e70 | |||
| 2cbfd21539 |
@@ -159,6 +159,9 @@ jobs:
|
||||
COSIGN_EXPERIMENTAL: '1'
|
||||
run: |
|
||||
IMAGE_DIGEST="${{ steps.meta.outputs.image }}@${{ steps.build.outputs.digest }}"
|
||||
# cosign needs its own registry auth — docker/login-action only writes
|
||||
# ~/.docker/config.json which cosign on self-hosted runner can't read
|
||||
echo "${{ secrets.GITHUB_TOKEN }}" | cosign login ghcr.io -u "${{ github.actor }}" --password-stdin
|
||||
echo "Signing $IMAGE_DIGEST"
|
||||
cosign sign --yes "$IMAGE_DIGEST"
|
||||
echo "✅ Image signed (transparency log: rekor.sigstore.dev)"
|
||||
@@ -328,8 +331,8 @@ jobs:
|
||||
COSIGN_EXPERIMENTAL: '1'
|
||||
run: |
|
||||
IMAGE="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.sha.outputs.sha }}"
|
||||
echo "${{ secrets.GITHUB_TOKEN }}" | cosign login ghcr.io -u "${{ github.actor }}" --password-stdin
|
||||
echo "Verifying signature for $IMAGE"
|
||||
# Identity = workflow that built this image (build-image job in this repo)
|
||||
cosign verify "$IMAGE" \
|
||||
--certificate-identity-regexp "^https://github.com/pezkuwichain/pwap/.github/workflows/quality-gate.yml@" \
|
||||
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
|
||||
@@ -625,11 +628,14 @@ jobs:
|
||||
with:
|
||||
node-version: '20'
|
||||
|
||||
- name: Web — npm audit (high + critical)
|
||||
- name: Web — npm audit (high + critical, production deps only)
|
||||
working-directory: ./web
|
||||
run: |
|
||||
npm install
|
||||
npm audit --audit-level=high
|
||||
# Audit only production dependencies. Build tooling (vite, esbuild,
|
||||
# vite-plugin-node-polyfills → elliptic, etc.) ships to no user, and
|
||||
# advisories on those dev deps kept blocking production deploys.
|
||||
npm audit --audit-level=high --omit=dev
|
||||
|
||||
- name: TruffleHog — PR diff (verified secrets only)
|
||||
if: github.event_name == 'pull_request'
|
||||
|
||||
-1
Submodule exchange deleted from bb3bc812ed
Generated
+111
-90
@@ -3508,9 +3508,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@remix-run/router": {
|
||||
"version": "1.23.2",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.2.tgz",
|
||||
"integrity": "sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w==",
|
||||
"version": "1.23.3",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.3.tgz",
|
||||
"integrity": "sha512-4An71tdz9X8+3sI4Qqqd2LWd9vS39J7sqd9EU4Scw7TJE/qB10Flv/UuqbPVgfQV9XoK8Np6jNquZitnZq5i+Q==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
@@ -5071,31 +5071,31 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/expect": {
|
||||
"version": "4.0.18",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.18.tgz",
|
||||
"integrity": "sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==",
|
||||
"version": "4.1.8",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.8.tgz",
|
||||
"integrity": "sha512-h3nDO677RDLEGlBxyQ5CW8RlMThSKSRLUePLOx09gNIWRL40edgA1GCZSZgf1W55MFAG6/Sw14KeaAnqv0NKdQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@standard-schema/spec": "^1.0.0",
|
||||
"@standard-schema/spec": "^1.1.0",
|
||||
"@types/chai": "^5.2.2",
|
||||
"@vitest/spy": "4.0.18",
|
||||
"@vitest/utils": "4.0.18",
|
||||
"chai": "^6.2.1",
|
||||
"tinyrainbow": "^3.0.3"
|
||||
"@vitest/spy": "4.1.8",
|
||||
"@vitest/utils": "4.1.8",
|
||||
"chai": "^6.2.2",
|
||||
"tinyrainbow": "^3.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/vitest"
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/mocker": {
|
||||
"version": "4.0.18",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.18.tgz",
|
||||
"integrity": "sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ==",
|
||||
"version": "4.1.8",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.8.tgz",
|
||||
"integrity": "sha512-LEiN/xe4OSIbKe9HQIp5OC24agGD9J5CnmMgsLohVVoOPWL9a2sBoR6VBx43jQZb7Kr1l4RCuyCJzcAa0+dojw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vitest/spy": "4.0.18",
|
||||
"@vitest/spy": "4.1.8",
|
||||
"estree-walker": "^3.0.3",
|
||||
"magic-string": "^0.30.21"
|
||||
},
|
||||
@@ -5104,7 +5104,7 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"msw": "^2.4.9",
|
||||
"vite": "^6.0.0 || ^7.0.0-0"
|
||||
"vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"msw": {
|
||||
@@ -5126,26 +5126,26 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/pretty-format": {
|
||||
"version": "4.0.18",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.18.tgz",
|
||||
"integrity": "sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==",
|
||||
"version": "4.1.8",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.8.tgz",
|
||||
"integrity": "sha512-9GasEBxpZ1VYIpqHf/0+YGg121uSNwCKOJqIrTwWP/TB7DmFCiaBpNl3aPZzoLWfWkuqhbH8vJIVobZkvdo2cA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tinyrainbow": "^3.0.3"
|
||||
"tinyrainbow": "^3.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/vitest"
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/runner": {
|
||||
"version": "4.0.18",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.18.tgz",
|
||||
"integrity": "sha512-rpk9y12PGa22Jg6g5M3UVVnTS7+zycIGk9ZNGN+m6tZHKQb7jrP7/77WfZy13Y/EUDd52NDsLRQhYKtv7XfPQw==",
|
||||
"version": "4.1.8",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.8.tgz",
|
||||
"integrity": "sha512-EmVxeBAfMJvycdjd6Hm+RbFBbA9fKvo0Kx37hNpBYoYeavH3RNsBXWDooR1mgD52dCrxIIuP7UotpfiwOikvcg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vitest/utils": "4.0.18",
|
||||
"@vitest/utils": "4.1.8",
|
||||
"pathe": "^2.0.3"
|
||||
},
|
||||
"funding": {
|
||||
@@ -5153,13 +5153,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/snapshot": {
|
||||
"version": "4.0.18",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.18.tgz",
|
||||
"integrity": "sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA==",
|
||||
"version": "4.1.8",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.8.tgz",
|
||||
"integrity": "sha512-acfZboRmAIf05DEKcBQy33VXojFJjtUdLyo7oOmV9kebb2xdU01UknNiPuPZoJZQyO7DF0gZdTGTpeAzET9QPQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vitest/pretty-format": "4.0.18",
|
||||
"@vitest/pretty-format": "4.1.8",
|
||||
"@vitest/utils": "4.1.8",
|
||||
"magic-string": "^0.30.21",
|
||||
"pathe": "^2.0.3"
|
||||
},
|
||||
@@ -5168,9 +5169,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/spy": {
|
||||
"version": "4.0.18",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.18.tgz",
|
||||
"integrity": "sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==",
|
||||
"version": "4.1.8",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.8.tgz",
|
||||
"integrity": "sha512-6EevtBp6OZOPF7bmz36HrGMeP3txgVSrgebWxHOafDXGkhIzfXK14f8KF6MuFfgXXUeHxmpD3BQxkV00/3s5mA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
@@ -5178,14 +5179,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/utils": {
|
||||
"version": "4.0.18",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.18.tgz",
|
||||
"integrity": "sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==",
|
||||
"version": "4.1.8",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.8.tgz",
|
||||
"integrity": "sha512-uOJamYALNhfJ6iolExyQM40yIQwDqYnkKtQ5VCiSe17E33H0aQ/u+1GlRuz4LZBk6Mm3sg90G9hEbmEt37C1Zg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vitest/pretty-format": "4.0.18",
|
||||
"tinyrainbow": "^3.0.3"
|
||||
"@vitest/pretty-format": "4.1.8",
|
||||
"convert-source-map": "^2.0.0",
|
||||
"tinyrainbow": "^3.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/vitest"
|
||||
@@ -5455,9 +5457,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@walletconnect/jsonrpc-ws-connection/node_modules/ws": {
|
||||
"version": "7.5.10",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
|
||||
"integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
|
||||
"version": "7.5.11",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.11.tgz",
|
||||
"integrity": "sha512-zS54Oen9bITtp7kp2XM3AydrCIq1D+HwJOuH+c+e4LfpL/lotP5osijd+UoMnxwAam1GN8R4KtLAyIrIcBNpiA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8.3.0"
|
||||
@@ -6568,13 +6570,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/browserify-sign": {
|
||||
"version": "4.2.5",
|
||||
"resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.5.tgz",
|
||||
"integrity": "sha512-C2AUdAJg6rlM2W5QMp2Q4KGQMVBwR1lIimTsUnutJ8bMpW5B52pGpR2gEnNBNwijumDo5FojQ0L9JrXA8m4YEw==",
|
||||
"version": "4.2.6",
|
||||
"resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.6.tgz",
|
||||
"integrity": "sha512-sd+Q65fjlWCYWtZKXiKfrUc8d+4jtp/8f0W2NkwzLtoW4bI6UDnWusLWIurHnmurW0XShIRxpwiOX4EoPtXUAg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"bn.js": "^5.2.2",
|
||||
"bn.js": "^5.2.3",
|
||||
"browserify-rsa": "^4.1.1",
|
||||
"create-hash": "^1.2.0",
|
||||
"create-hmac": "^1.1.7",
|
||||
@@ -7029,6 +7031,13 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/convert-source-map": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
||||
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/cookie-es": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-1.2.3.tgz",
|
||||
@@ -7642,9 +7651,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/dompurify": {
|
||||
"version": "3.4.2",
|
||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.2.tgz",
|
||||
"integrity": "sha512-lHeS9SA/IKeIFFyYciHBr2n0v1VMPlSj843HdLOwjb2OxNwdq9Xykxqhk+FE42MzAdHvInbAolSE4mhahPpjXA==",
|
||||
"version": "3.4.10",
|
||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.10.tgz",
|
||||
"integrity": "sha512-0xzNv0e7oYC6yyuOGZIABPM4qtg3QxLFniDNPP4ZP90wR8Yq3zgwpRbrNiT4N3IKqDbbYFEJLV+JWEs19aZ//w==",
|
||||
"license": "(MPL-2.0 OR Apache-2.0)",
|
||||
"optionalDependencies": {
|
||||
"@types/trusted-types": "^2.0.7"
|
||||
@@ -7860,9 +7869,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/es-module-lexer": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz",
|
||||
"integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==",
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz",
|
||||
"integrity": "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
@@ -11148,9 +11157,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/qs": {
|
||||
"version": "6.15.1",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz",
|
||||
"integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==",
|
||||
"version": "6.15.2",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz",
|
||||
"integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
@@ -11368,12 +11377,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "6.30.3",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.3.tgz",
|
||||
"integrity": "sha512-XRnlbKMTmktBkjCLE8/XcZFlnHvr2Ltdr1eJX4idL55/9BbORzyZEaIkBFDhFGCEWBBItsVrDxwx3gnisMitdw==",
|
||||
"version": "6.30.4",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.4.tgz",
|
||||
"integrity": "sha512-SVUsDe+DybHM/WmYKIVYhZh1o5Dcuf16yM6WjG02Q9XVFMZIJyHYhwrr6bFBXZkVP6z69kNkMyBCujt8FaFLJA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.23.2"
|
||||
"@remix-run/router": "1.23.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
@@ -11383,13 +11392,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-router-dom": {
|
||||
"version": "6.30.3",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.3.tgz",
|
||||
"integrity": "sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag==",
|
||||
"version": "6.30.4",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.4.tgz",
|
||||
"integrity": "sha512-q4HvNl+mmDdkS0g+MqiBZNteQJCuimWoOyHMy4T/RQLAn9Z29+E91QXRaxOujeMl2HTzRSS0KFPd7lxX3PjV0Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.23.2",
|
||||
"react-router": "6.30.3"
|
||||
"@remix-run/router": "1.23.3",
|
||||
"react-router": "6.30.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
@@ -12238,9 +12247,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/std-env": {
|
||||
"version": "3.10.0",
|
||||
"resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz",
|
||||
"integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz",
|
||||
"integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
@@ -12697,9 +12706,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tinyrainbow": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.0.3.tgz",
|
||||
"integrity": "sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==",
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz",
|
||||
"integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@@ -13299,31 +13308,31 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vitest": {
|
||||
"version": "4.0.18",
|
||||
"resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.18.tgz",
|
||||
"integrity": "sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==",
|
||||
"version": "4.1.8",
|
||||
"resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.8.tgz",
|
||||
"integrity": "sha512-flY6ScbCIt9HThs+C5HS7jvGOB560DJtk/Z15IQROTA6zEy49Nh8T/dofWTQL+n3vswqn87sbJNiuqw1SDp5Ig==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vitest/expect": "4.0.18",
|
||||
"@vitest/mocker": "4.0.18",
|
||||
"@vitest/pretty-format": "4.0.18",
|
||||
"@vitest/runner": "4.0.18",
|
||||
"@vitest/snapshot": "4.0.18",
|
||||
"@vitest/spy": "4.0.18",
|
||||
"@vitest/utils": "4.0.18",
|
||||
"es-module-lexer": "^1.7.0",
|
||||
"expect-type": "^1.2.2",
|
||||
"@vitest/expect": "4.1.8",
|
||||
"@vitest/mocker": "4.1.8",
|
||||
"@vitest/pretty-format": "4.1.8",
|
||||
"@vitest/runner": "4.1.8",
|
||||
"@vitest/snapshot": "4.1.8",
|
||||
"@vitest/spy": "4.1.8",
|
||||
"@vitest/utils": "4.1.8",
|
||||
"es-module-lexer": "^2.0.0",
|
||||
"expect-type": "^1.3.0",
|
||||
"magic-string": "^0.30.21",
|
||||
"obug": "^2.1.1",
|
||||
"pathe": "^2.0.3",
|
||||
"picomatch": "^4.0.3",
|
||||
"std-env": "^3.10.0",
|
||||
"std-env": "^4.0.0-rc.1",
|
||||
"tinybench": "^2.9.0",
|
||||
"tinyexec": "^1.0.2",
|
||||
"tinyglobby": "^0.2.15",
|
||||
"tinyrainbow": "^3.0.3",
|
||||
"vite": "^6.0.0 || ^7.0.0",
|
||||
"tinyrainbow": "^3.1.0",
|
||||
"vite": "^6.0.0 || ^7.0.0 || ^8.0.0",
|
||||
"why-is-node-running": "^2.3.0"
|
||||
},
|
||||
"bin": {
|
||||
@@ -13339,12 +13348,15 @@
|
||||
"@edge-runtime/vm": "*",
|
||||
"@opentelemetry/api": "^1.9.0",
|
||||
"@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0",
|
||||
"@vitest/browser-playwright": "4.0.18",
|
||||
"@vitest/browser-preview": "4.0.18",
|
||||
"@vitest/browser-webdriverio": "4.0.18",
|
||||
"@vitest/ui": "4.0.18",
|
||||
"@vitest/browser-playwright": "4.1.8",
|
||||
"@vitest/browser-preview": "4.1.8",
|
||||
"@vitest/browser-webdriverio": "4.1.8",
|
||||
"@vitest/coverage-istanbul": "4.1.8",
|
||||
"@vitest/coverage-v8": "4.1.8",
|
||||
"@vitest/ui": "4.1.8",
|
||||
"happy-dom": "*",
|
||||
"jsdom": "*"
|
||||
"jsdom": "*",
|
||||
"vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@edge-runtime/vm": {
|
||||
@@ -13365,6 +13377,12 @@
|
||||
"@vitest/browser-webdriverio": {
|
||||
"optional": true
|
||||
},
|
||||
"@vitest/coverage-istanbul": {
|
||||
"optional": true
|
||||
},
|
||||
"@vitest/coverage-v8": {
|
||||
"optional": true
|
||||
},
|
||||
"@vitest/ui": {
|
||||
"optional": true
|
||||
},
|
||||
@@ -13373,6 +13391,9 @@
|
||||
},
|
||||
"jsdom": {
|
||||
"optional": true
|
||||
},
|
||||
"vite": {
|
||||
"optional": false
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -13614,9 +13635,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.19.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz",
|
||||
"integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",
|
||||
"version": "8.21.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz",
|
||||
"integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
<?xml version="1.0"?>
|
||||
<svg width="512" height="512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
|
||||
<linearGradient id="fireGradient" x1="0%" y1="100%" x2="0%" y2="0%">
|
||||
<stop offset="0%" style="stop-color:#1B5E20;stop-opacity:1"></stop>
|
||||
<stop offset="30%" style="stop-color:#FF6F00;stop-opacity:1"></stop>
|
||||
<stop offset="60%" style="stop-color:#FFD600;stop-opacity:1"></stop>
|
||||
<stop offset="100%" style="stop-color:#D32F2F;stop-opacity:1"></stop>
|
||||
</linearGradient>
|
||||
|
||||
|
||||
<linearGradient id="innerFlame" x1="0%" y1="100%" x2="0%" y2="0%">
|
||||
<stop offset="0%" style="stop-color:#FFD600;stop-opacity:1"></stop>
|
||||
<stop offset="50%" style="stop-color:#FF8F00;stop-opacity:1"></stop>
|
||||
<stop offset="100%" style="stop-color:#FF5722;stop-opacity:1"></stop>
|
||||
</linearGradient>
|
||||
|
||||
|
||||
<filter id="glow">
|
||||
<feGaussianBlur stdDeviation="8" result="coloredBlur"></feGaussianBlur>
|
||||
<feMerge>
|
||||
<feMergeNode in="coloredBlur"></feMergeNode>
|
||||
<feMergeNode in="SourceGraphic"></feMergeNode>
|
||||
</feMerge>
|
||||
</filter>
|
||||
|
||||
|
||||
<radialGradient id="sunGlow" cx="50%" cy="50%" r="50%">
|
||||
<stop offset="0%" style="stop-color:#FFD600;stop-opacity:0.6"></stop>
|
||||
<stop offset="100%" style="stop-color:#FFD600;stop-opacity:0"></stop>
|
||||
</radialGradient>
|
||||
</defs>
|
||||
|
||||
|
||||
<circle cx="256" cy="256" r="240" fill="#1a1a2e" opacity="0.9"></circle>
|
||||
|
||||
|
||||
<circle cx="256" cy="280" r="180" fill="url(#sunGlow)" filter="url(#glow)"></circle>
|
||||
|
||||
|
||||
<path d="M256 60
 C280 120 340 160 360 220
 C380 280 360 340 340 380
 C320 420 280 460 256 470
 C232 460 192 420 172 380
 C152 340 132 280 152 220
 C172 160 232 120 256 60Z" fill="url(#fireGradient)" filter="url(#glow)">
|
||||
|
||||
</path>
|
||||
|
||||
|
||||
<path d="M256 140
 C270 180 310 210 320 260
 C330 310 320 350 300 380
 C280 410 268 430 256 440
 C244 430 232 410 212 380
 C192 350 182 310 192 260
 C202 210 242 180 256 140Z" fill="url(#innerFlame)" opacity="0.95">
|
||||
|
||||
</path>
|
||||
|
||||
|
||||
<ellipse cx="256" cy="320" rx="50" ry="80" fill="#FFFDE7" opacity="0.8">
|
||||
|
||||
|
||||
</ellipse>
|
||||
|
||||
|
||||
<circle cx="200" cy="180" r="8" fill="#4CAF50" opacity="0.8">
|
||||
|
||||
|
||||
</circle>
|
||||
<circle cx="312" cy="200" r="6" fill="#4CAF50" opacity="0.7">
|
||||
|
||||
|
||||
</circle>
|
||||
<circle cx="230" cy="150" r="5" fill="#81C784" opacity="0.6">
|
||||
|
||||
</circle>
|
||||
<circle cx="280" cy="165" r="7" fill="#66BB6A" opacity="0.7">
|
||||
|
||||
</circle>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -5,6 +5,7 @@ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Wallet, TrendingUp, RefreshCw, Award, Plus, Coins, Send, Shield, Users, Fuel, Lock } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { ASSET_IDS, getAssetSymbol } from '@pezkuwi/lib/wallet';
|
||||
import { Pez20Badge } from './Pez20Badge';
|
||||
import { AddTokenModal } from './AddTokenModal';
|
||||
import { TransferModal } from './TransferModal';
|
||||
import { XCMTeleportModal } from './XCMTeleportModal';
|
||||
@@ -811,6 +812,7 @@ export const AccountBalance: React.FC = () => {
|
||||
<CardTitle className="text-lg font-medium text-gray-300 whitespace-nowrap">
|
||||
{t('balance.pezBalance')}
|
||||
</CardTitle>
|
||||
<Pez20Badge className="flex-shrink-0" />
|
||||
</div>
|
||||
<Button
|
||||
size="sm"
|
||||
@@ -853,6 +855,7 @@ export const AccountBalance: React.FC = () => {
|
||||
<CardTitle className="text-lg font-medium text-gray-300">
|
||||
{t('balance.usdtBalance')}
|
||||
</CardTitle>
|
||||
<Pez20Badge className="flex-shrink-0" />
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
|
||||
@@ -110,8 +110,8 @@ const APP_SECTIONS: AppSection[] = [
|
||||
{ title: 'mobile.app.whatsKurd', icon: '💬', route: '/social/whatskurd' },
|
||||
{ title: 'mobile.app.forum', icon: '📰', route: '/forum' },
|
||||
{ title: 'mobile.app.kurdMedia', icon: '📺', route: '/social/kurdmedia' },
|
||||
{ title: 'mobile.app.events', icon: '📅', route: '/forum', comingSoon: true },
|
||||
{ title: 'mobile.app.help', icon: '❓', route: '/help' },
|
||||
{ title: 'mobile.app.events', icon: '📅', route: '/forum', href: 'https://kurdishtts.pezkiwi.app' },
|
||||
{ title: 'mobile.app.loto', icon: '🔥', imgIcon: '/loto-icon.svg', route: '/forum', href: 'https://loto.pex.mom' },
|
||||
{ title: 'mobile.app.music', icon: '🎵', route: '/forum', comingSoon: true },
|
||||
{ title: 'mobile.app.rewshenbir',icon: '📡', imgIcon: '/rewshenbir-icon.png', route: '/rewshenbir', href: 'https://rewshenbir.pezkuwi.app' },
|
||||
{ title: 'mobile.app.referral', icon: '👥', route: '/dashboard', requiresAuth: true },
|
||||
|
||||
@@ -87,8 +87,8 @@ const APP_SECTIONS: AppSection[] = [
|
||||
{ title: 'mobile.app.whatsKurd', icon: '💬', route: '/social/whatskurd' },
|
||||
{ title: 'mobile.app.forum', icon: '📰', route: '/forum' },
|
||||
{ title: 'mobile.app.kurdMedia', icon: '📺', route: '/social/kurdmedia' },
|
||||
{ title: 'mobile.app.events', icon: '📅', route: '/forum', comingSoon: true },
|
||||
{ title: 'mobile.app.help', icon: '❓', route: '/help' },
|
||||
{ title: 'mobile.app.events', icon: '📅', route: '/forum', href: 'https://kurdishtts.pezkiwi.app' },
|
||||
{ title: 'mobile.app.loto', icon: '🔥', imgIcon: '/loto-icon.svg', route: '/forum', href: 'https://loto.pex.mom' },
|
||||
{ title: 'mobile.app.music', icon: '🎵', route: '/forum', comingSoon: true },
|
||||
{ title: 'mobile.app.rewshenbir', icon: '📡', imgIcon: '/rewshenbir-icon.png', route: '/rewshenbir', href: 'https://rewshenbir.pezkuwi.app' },
|
||||
{ title: 'mobile.app.referral', icon: '👥', route: '/dashboard', requiresAuth: true },
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import React from 'react';
|
||||
|
||||
/**
|
||||
* Small pill marking a token as a Pezkuwi token-standard asset.
|
||||
* PEZ-20 = fungible standard (pallet-assets on Asset Hub), PEZ-721 = NFT standard.
|
||||
* See docs.pezkuwichain.io → Token Standards.
|
||||
*/
|
||||
export const Pez20Badge: React.FC<{ standard?: 'PEZ-20' | 'PEZ-721'; className?: string }> = ({
|
||||
standard = 'PEZ-20',
|
||||
className = '',
|
||||
}) => (
|
||||
<a
|
||||
href="https://docs.pezkuwichain.io/token-standards"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
title={`${standard} token standard on Pezkuwi Asset Hub`}
|
||||
className={
|
||||
'inline-flex items-center rounded-full border border-blue-500/40 bg-blue-500/10 ' +
|
||||
'px-2 py-0.5 text-[10px] font-semibold tracking-wide text-blue-300 ' +
|
||||
'hover:bg-blue-500/20 transition-colors no-underline ' +
|
||||
className
|
||||
}
|
||||
>
|
||||
{standard}
|
||||
</a>
|
||||
);
|
||||
|
||||
export default Pez20Badge;
|
||||
@@ -15,6 +15,8 @@ interface ChainStats {
|
||||
validators: number;
|
||||
nominators: number;
|
||||
collators: number;
|
||||
collatorsAH: number;
|
||||
collatorsPeople: number;
|
||||
activeProposals: number;
|
||||
totalVoters: number;
|
||||
citizenCount: number;
|
||||
@@ -325,6 +327,7 @@ const LandingPageDesktop: React.FC = () => {
|
||||
const [stats, setStats] = useState<ChainStats>({
|
||||
latestBlock: 0, finalizedBlock: 0, blockHash: '',
|
||||
peers: 0, validators: 0, nominators: 0, collators: 0,
|
||||
collatorsAH: 0, collatorsPeople: 0,
|
||||
activeProposals: 0, totalVoters: 0, citizenCount: 0,
|
||||
tokensStakedPct: '—',
|
||||
});
|
||||
@@ -417,12 +420,7 @@ const LandingPageDesktop: React.FC = () => {
|
||||
const validators = sessionVals.length;
|
||||
setStats(prev => ({ ...prev, activeProposals, totalVoters, validators }));
|
||||
} catch {}
|
||||
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const nomCount = await (api.query.staking as any).counterForNominators?.();
|
||||
if (nomCount != null) setStats(prev => ({ ...prev, nominators: nomCount.toNumber() }));
|
||||
} catch {}
|
||||
// Nominators/staking migrated to Asset Hub — counted in the Asset Hub effect below.
|
||||
})();
|
||||
}, [api, isApiReady]);
|
||||
|
||||
@@ -448,10 +446,18 @@ const LandingPageDesktop: React.FC = () => {
|
||||
}
|
||||
} catch {}
|
||||
|
||||
// Nominators live on Asset Hub after the staking migration (AHM).
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const collCount = await (assetHubApi.query.collatorSelection as any)?.candidates?.();
|
||||
if (collCount != null) setStats(prev => ({ ...prev, collators: collCount.length }));
|
||||
const nomCount = await (assetHubApi.query.staking as any)?.counterForNominators?.();
|
||||
if (nomCount != null) setStats(prev => ({ ...prev, nominators: nomCount.toNumber() }));
|
||||
} catch {}
|
||||
|
||||
// Collators are the invulnerable set (not staking candidates, which are empty).
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const inv = await (assetHubApi.query.collatorSelection as any)?.invulnerables?.();
|
||||
if (inv != null) setStats(prev => ({ ...prev, collatorsAH: inv.length, collators: inv.length + prev.collatorsPeople }));
|
||||
} catch {}
|
||||
})();
|
||||
}, [assetHubApi, isAssetHubReady]);
|
||||
@@ -465,6 +471,13 @@ const LandingPageDesktop: React.FC = () => {
|
||||
const entries = await (peopleApi.query as any).tiki?.citizenNft?.entries?.();
|
||||
if (entries) setStats(prev => ({ ...prev, citizenCount: entries.length }));
|
||||
} catch {}
|
||||
|
||||
// People Chain also runs invulnerable collators — add them to the total.
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const inv = await (peopleApi.query.collatorSelection as any)?.invulnerables?.();
|
||||
if (inv != null) setStats(prev => ({ ...prev, collatorsPeople: inv.length, collators: prev.collatorsAH + inv.length }));
|
||||
} catch {}
|
||||
})();
|
||||
}, [peopleApi, isPeopleReady]);
|
||||
|
||||
@@ -1086,7 +1099,7 @@ const LandingPageDesktop: React.FC = () => {
|
||||
<PalletItem icon="lp-i-chat" label={t('landing.pallets.whatskurd')} to="/social/whatskurd" requiresLogin />
|
||||
<PalletItem icon="lp-i-forum" label={t('landing.pallets.forum')} to="/forum" />
|
||||
<PalletItem icon="lp-i-media" label={t('landing.pallets.kurdmedia')} to="/social/kurdmedia" requiresLogin />
|
||||
<PalletItem icon="lp-i-cal" label={t('landing.pallets.events')} locked />
|
||||
<PalletItem icon="lp-i-cal" label={t('landing.pallets.events')} external="https://kurdishtts.pezkiwi.app" />
|
||||
<PalletItem icon="lp-i-help" label={t('landing.pallets.help')} to="/help" />
|
||||
<PalletItem icon="lp-i-music" label={t('landing.pallets.music')} locked />
|
||||
<PalletItem imgSrc="/rewshenbir-icon.png" label={t('landing.pallets.rewshenbir')} external="https://rewshenbir.pezkuwi.app" />
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Card, CardContent } from '@/components/ui/card';
|
||||
import { PlusCircle, Home, ClipboardList, TrendingUp, CheckCircle2, Clock, Store, Zap, Blocks, MessageSquare } from 'lucide-react';
|
||||
import { PlusCircle, Home, ClipboardList, TrendingUp, CheckCircle2, Clock, Store, Zap, Blocks, MessageSquare, CreditCard } from 'lucide-react';
|
||||
import { AdList } from './AdList';
|
||||
import { CreateAd } from './CreateAd';
|
||||
import { NotificationBell } from './NotificationBell';
|
||||
@@ -191,6 +191,15 @@ export function P2PDashboard() {
|
||||
</Badge>
|
||||
)}
|
||||
</button>
|
||||
<a
|
||||
href="https://buy-sell.pezkiwi.app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="relative flex flex-col items-center gap-0.5 px-3 py-1.5 rounded-lg hover:bg-amber-900/30 transition-colors"
|
||||
>
|
||||
<CreditCard className="w-5 h-5 text-amber-400" />
|
||||
<span className="text-[10px] text-amber-300">{t('p2pNav.buyVisa')}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1561,6 +1561,7 @@ export default {
|
||||
'p2pNav.orders': 'الطلبات',
|
||||
'p2pNav.ads': 'الإعلانات',
|
||||
'p2pNav.messages': 'الرسائل',
|
||||
'p2pNav.buyVisa': 'اشترِ بفيزا',
|
||||
|
||||
// P2P Messages Inbox
|
||||
'p2pMessages.title': 'الرسائل',
|
||||
@@ -3787,7 +3788,7 @@ export default {
|
||||
'mobile.app.bank': 'البنك',
|
||||
'mobile.app.exchange': 'البورصة',
|
||||
'mobile.app.dex': 'Pez-DEX',
|
||||
'mobile.app.p2p': 'P2P',
|
||||
'mobile.app.p2p': 'P2P/Buy-Sell',
|
||||
'mobile.app.b2b': 'B2B',
|
||||
'mobile.app.bacZekat': 'الضريبة/الزكاة',
|
||||
'mobile.app.launchpad': 'منصة الإطلاق',
|
||||
@@ -3804,6 +3805,7 @@ export default {
|
||||
'mobile.app.kurdMedia': 'كورد ميديا',
|
||||
'mobile.app.events': 'الفعاليات',
|
||||
'mobile.app.help': 'المساعدة',
|
||||
'mobile.app.loto': 'لوتو',
|
||||
'mobile.app.music': 'الموسيقى',
|
||||
'mobile.app.vpn': 'VPN',
|
||||
'mobile.app.referral': 'الإحالة',
|
||||
|
||||
@@ -1551,6 +1551,7 @@ export default {
|
||||
'p2pNav.orders': 'داواکاریەکان',
|
||||
'p2pNav.ads': 'ڕیکلامەکان',
|
||||
'p2pNav.messages': 'پەیامەکان',
|
||||
'p2pNav.buyVisa': 'بە ڤیزا بکڕە',
|
||||
|
||||
// P2P Messages Inbox
|
||||
'p2pMessages.title': 'پەیامەکان',
|
||||
@@ -3777,7 +3778,7 @@ export default {
|
||||
'mobile.app.bank': 'بانک',
|
||||
'mobile.app.exchange': 'ئاڵوگۆڕ',
|
||||
'mobile.app.dex': 'Pez-DEX',
|
||||
'mobile.app.p2p': 'P2P',
|
||||
'mobile.app.p2p': 'P2P/Buy-Sell',
|
||||
'mobile.app.b2b': 'B2B',
|
||||
'mobile.app.bacZekat': 'باج/زەکات',
|
||||
'mobile.app.launchpad': 'دەستپێکردن',
|
||||
@@ -3794,6 +3795,7 @@ export default {
|
||||
'mobile.app.kurdMedia': 'کوردمیدیا',
|
||||
'mobile.app.events': 'چالاکی',
|
||||
'mobile.app.help': 'یارمەتی',
|
||||
'mobile.app.loto': 'لۆتۆ',
|
||||
'mobile.app.music': 'مۆسیقا',
|
||||
'mobile.app.vpn': 'VPN',
|
||||
'mobile.app.referral': 'ئاماژە',
|
||||
|
||||
@@ -1915,6 +1915,7 @@ export default {
|
||||
'p2pNav.orders': 'Orders',
|
||||
'p2pNav.ads': 'Ads',
|
||||
'p2pNav.messages': 'Messages',
|
||||
'p2pNav.buyVisa': 'Buy with Visa',
|
||||
|
||||
// P2P Messages Inbox
|
||||
'p2pMessages.title': 'Messages',
|
||||
@@ -3839,7 +3840,7 @@ export default {
|
||||
'mobile.app.bank': 'Bank',
|
||||
'mobile.app.exchange': 'Exchange',
|
||||
'mobile.app.dex': 'Pez-DEX',
|
||||
'mobile.app.p2p': 'P2P',
|
||||
'mobile.app.p2p': 'P2P/Buy-Sell',
|
||||
'mobile.app.b2b': 'B2B',
|
||||
'mobile.app.bacZekat': 'Bac/Zekat',
|
||||
'mobile.app.launchpad': 'Launchpad',
|
||||
@@ -3856,6 +3857,7 @@ export default {
|
||||
'mobile.app.kurdMedia': 'KurdMedia',
|
||||
'mobile.app.events': 'Events',
|
||||
'mobile.app.help': 'Help',
|
||||
'mobile.app.loto': 'Loto',
|
||||
'mobile.app.music': 'Music',
|
||||
'mobile.app.vpn': 'VPN',
|
||||
'mobile.app.rewshenbir': 'Rewshenbir',
|
||||
|
||||
@@ -1585,6 +1585,7 @@ export default {
|
||||
'p2pNav.orders': 'سفارشات',
|
||||
'p2pNav.ads': 'آگهیها',
|
||||
'p2pNav.messages': 'پیامها',
|
||||
'p2pNav.buyVisa': 'خرید با ویزا',
|
||||
|
||||
// P2P Messages Inbox
|
||||
'p2pMessages.title': 'پیامها',
|
||||
@@ -3821,7 +3822,7 @@ export default {
|
||||
'mobile.app.bank': 'بانک',
|
||||
'mobile.app.exchange': 'صرافی',
|
||||
'mobile.app.dex': 'Pez-DEX',
|
||||
'mobile.app.p2p': 'P2P',
|
||||
'mobile.app.p2p': 'P2P/Buy-Sell',
|
||||
'mobile.app.b2b': 'B2B',
|
||||
'mobile.app.bacZekat': 'مالیات/زکات',
|
||||
'mobile.app.launchpad': 'سکوی پرتاب',
|
||||
@@ -3838,6 +3839,7 @@ export default {
|
||||
'mobile.app.kurdMedia': 'کوردمدیا',
|
||||
'mobile.app.events': 'رویدادها',
|
||||
'mobile.app.help': 'کمک',
|
||||
'mobile.app.loto': 'لاتاری',
|
||||
'mobile.app.music': 'موسیقی',
|
||||
'mobile.app.vpn': 'VPN',
|
||||
'mobile.app.referral': 'ارجاع',
|
||||
|
||||
@@ -1573,6 +1573,7 @@ export default {
|
||||
'p2pNav.orders': 'Ferman',
|
||||
'p2pNav.ads': 'Reklam',
|
||||
'p2pNav.messages': 'Peyam',
|
||||
'p2pNav.buyVisa': 'Bi Visa bikire',
|
||||
|
||||
// P2P Messages Inbox
|
||||
'p2pMessages.title': 'Peyam',
|
||||
@@ -3804,7 +3805,7 @@ export default {
|
||||
'mobile.app.bank': 'Bank',
|
||||
'mobile.app.exchange': 'Danûstandin',
|
||||
'mobile.app.dex': 'Pez-DEX',
|
||||
'mobile.app.p2p': 'P2P',
|
||||
'mobile.app.p2p': 'P2P/Buy-Sell',
|
||||
'mobile.app.b2b': 'B2B',
|
||||
'mobile.app.bacZekat': 'Bac/Zekat',
|
||||
'mobile.app.launchpad': 'Destpêk',
|
||||
@@ -3821,6 +3822,7 @@ export default {
|
||||
'mobile.app.kurdMedia': 'KurdMedya',
|
||||
'mobile.app.events': 'Çalakî',
|
||||
'mobile.app.help': 'Alîkarî',
|
||||
'mobile.app.loto': 'Loto',
|
||||
'mobile.app.music': 'Muzîk',
|
||||
'mobile.app.vpn': 'VPN',
|
||||
'mobile.app.rewshenbir': 'Rewşenbir',
|
||||
|
||||
@@ -1567,6 +1567,7 @@ export default {
|
||||
'p2pNav.orders': 'Siparişler',
|
||||
'p2pNav.ads': 'İlanlar',
|
||||
'p2pNav.messages': 'Mesajlar',
|
||||
'p2pNav.buyVisa': 'Visa ile Al',
|
||||
|
||||
// P2P Messages Inbox
|
||||
'p2pMessages.title': 'Mesajlar',
|
||||
@@ -3807,7 +3808,7 @@ export default {
|
||||
'mobile.app.bank': 'Banka',
|
||||
'mobile.app.exchange': 'Borsa',
|
||||
'mobile.app.dex': 'Pez-DEX',
|
||||
'mobile.app.p2p': 'P2P',
|
||||
'mobile.app.p2p': 'P2P/Buy-Sell',
|
||||
'mobile.app.b2b': 'B2B',
|
||||
'mobile.app.bacZekat': 'Vergi/Zekat',
|
||||
'mobile.app.launchpad': 'Launchpad',
|
||||
@@ -3824,6 +3825,7 @@ export default {
|
||||
'mobile.app.kurdMedia': 'KurdMedya',
|
||||
'mobile.app.events': 'Etkinlikler',
|
||||
'mobile.app.help': 'Yardım',
|
||||
'mobile.app.loto': 'Loto',
|
||||
'mobile.app.music': 'Müzik',
|
||||
'mobile.app.vpn': 'VPN',
|
||||
'mobile.app.rewshenbir': 'Rewshenbir',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { supabase } from '@/lib/supabase';
|
||||
import { Loader2 } from 'lucide-react';
|
||||
@@ -12,7 +12,6 @@ const BEREKETLI_API = `${BEREKETLI_URL}/v1`;
|
||||
*/
|
||||
export default function Bereketli() {
|
||||
const { t } = useTranslation();
|
||||
const [error, setError] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
@@ -20,8 +19,10 @@ export default function Bereketli() {
|
||||
const {
|
||||
data: { session },
|
||||
} = await supabase.auth.getSession();
|
||||
// Not signed in: skip SSO and send the user to the Bereketli site,
|
||||
// which handles its own login. Never dead-end on this interstitial.
|
||||
if (!session?.access_token) {
|
||||
setError(t('bereketli.noSession', 'Lütfen önce giriş yapın'));
|
||||
window.location.href = BEREKETLI_URL;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -46,27 +47,14 @@ export default function Bereketli() {
|
||||
});
|
||||
window.location.href = `${BEREKETLI_URL}/app?auth=${btoa(params.toString())}`;
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'Bağlantı hatası');
|
||||
// SSO failed (expired token, network, etc.) — fall back to the public
|
||||
// Bereketli site instead of stranding the user on app.pezkuwichain.io.
|
||||
if (import.meta.env.DEV) console.warn('Bereketli SSO failed, falling back:', err);
|
||||
window.location.href = BEREKETLI_URL;
|
||||
}
|
||||
})();
|
||||
}, [t]);
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-950 flex items-center justify-center px-6">
|
||||
<div className="text-center space-y-4">
|
||||
<p className="text-red-400 text-sm">{error}</p>
|
||||
<a
|
||||
href="/"
|
||||
className="inline-block px-4 py-2 bg-green-600 text-white rounded-lg text-sm"
|
||||
>
|
||||
{t('common.backToHome', 'Ana Sayfaya Dön')}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-950 flex items-center justify-center">
|
||||
<div className="text-center space-y-3">
|
||||
|
||||
@@ -9,6 +9,7 @@ interface MediaChannel {
|
||||
descriptionKu: string;
|
||||
description: string;
|
||||
color: string;
|
||||
url?: string;
|
||||
}
|
||||
|
||||
interface SocialPlatform {
|
||||
@@ -21,7 +22,7 @@ interface SocialPlatform {
|
||||
|
||||
const MEDIA_CHANNELS: MediaChannel[] = [
|
||||
{ id: 'dkstv', nameKu: 'DKS TV', name: 'DKS TV', icon: '📺', descriptionKu: 'Televizyona Dewleta Dijîtal a Kurdistanê', description: 'Digital Kurdistan State Television', color: '#E53935' },
|
||||
{ id: 'dksgzt', nameKu: 'DKS Rojname', name: 'DKS Gazette', icon: '📰', descriptionKu: 'Nûçe û Daxuyaniyên Fermî', description: 'Official News & Announcements', color: '#1E88E5' },
|
||||
{ id: 'dksgzt', nameKu: 'DKS Rojname', name: 'DKS Gazette', icon: '📰', descriptionKu: 'Nûçe û Daxuyaniyên Fermî', description: 'Official News & Announcements', color: '#1E88E5', url: 'https://news.pex.mom' },
|
||||
{ id: 'dksradio', nameKu: 'DKS Radyo', name: 'DKS Radio', icon: '📻', descriptionKu: 'Radyoya Dewleta Dijîtal a Kurdistanê', description: 'Digital Kurdistan State Radio', color: '#7B1FA2' },
|
||||
{ id: 'dksmusic', nameKu: 'DKS Muzîk', name: 'DKS Music', icon: '🎵', descriptionKu: 'Weşana Muzîka Kurdî', description: 'Kurdish Music Streaming', color: '#00897B' },
|
||||
{ id: 'dkspodcast',nameKu: 'DKS Podcast', name: 'DKS Podcast', icon: '🎙️', descriptionKu: 'Podcast û Gotûbêjên Kurdî', description: 'Kurdish Podcasts & Talks', color: '#F4511E' },
|
||||
@@ -71,20 +72,38 @@ export default function KurdMediaPage() {
|
||||
<p className="text-sm text-gray-300 mb-1">{t('kurdMedia.channels.desc', 'Weşanên fermî yên Dewleta Dijîtal a Kurdistanê.')}</p>
|
||||
<p className="text-xs text-gray-500 mb-4">{t('kurdMedia.channels.descEn', 'Official broadcasts of Digital Kurdistan State. TV, radio, news and more.')}</p>
|
||||
<div className="space-y-3">
|
||||
{MEDIA_CHANNELS.map(ch => (
|
||||
<div key={ch.id} className="flex items-center gap-3 bg-gray-800 rounded-xl p-3">
|
||||
<div className="w-12 h-12 rounded-xl flex items-center justify-center text-2xl flex-shrink-0" style={{ backgroundColor: ch.color }}>
|
||||
{ch.icon}
|
||||
{MEDIA_CHANNELS.map(ch => {
|
||||
const inner = (
|
||||
<>
|
||||
<div className="w-12 h-12 rounded-xl flex items-center justify-center text-2xl flex-shrink-0" style={{ backgroundColor: ch.color }}>
|
||||
{ch.icon}
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<p className="font-semibold text-white text-sm">{ch.nameKu}</p>
|
||||
<p className="text-xs text-gray-400 truncate">{ch.descriptionKu}</p>
|
||||
</div>
|
||||
{ch.url ? (
|
||||
<span className="text-[10px] font-bold text-green-400 bg-green-400/10 px-2 py-1 rounded-full flex-shrink-0">
|
||||
{t('kurdMedia.open', 'Open')} ↗
|
||||
</span>
|
||||
) : (
|
||||
<span className="text-[10px] font-bold text-yellow-400 bg-yellow-400/10 px-2 py-1 rounded-full flex-shrink-0">
|
||||
{t('kurdMedia.soon', 'Soon')}
|
||||
</span>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
return ch.url ? (
|
||||
<a key={ch.id} href={ch.url} target="_blank" rel="noopener noreferrer"
|
||||
className="flex items-center gap-3 bg-gray-800 rounded-xl p-3 hover:bg-gray-700 transition-colors">
|
||||
{inner}
|
||||
</a>
|
||||
) : (
|
||||
<div key={ch.id} className="flex items-center gap-3 bg-gray-800 rounded-xl p-3">
|
||||
{inner}
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<p className="font-semibold text-white text-sm">{ch.nameKu}</p>
|
||||
<p className="text-xs text-gray-400 truncate">{ch.descriptionKu}</p>
|
||||
</div>
|
||||
<span className="text-[10px] font-bold text-yellow-400 bg-yellow-400/10 px-2 py-1 rounded-full flex-shrink-0">
|
||||
{t('kurdMedia.soon', 'Soon')}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user