This commit is contained in:
you 2024-06-26 14:45:39 +03:00
commit 99f9c91a60
18 changed files with 5408 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
/node_modules/
/public/build/
.DS_Store

19
README.md Normal file
View File

@ -0,0 +1,19 @@
# svelte app
This is a project template for [Svelte](https://svelte.dev) apps. It lives at https://github.com/sveltejs/template.
# after cloning this repo
```bash
npm i
```
# start app
```bash
npm run dev
```
# build app
```bash
npm run build
```

2834
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

33
package.json Normal file
View File

@ -0,0 +1,33 @@
{
"name": "svelte-app",
"version": "1.0.0",
"private": true,
"type": "module",
"scripts": {
"build": "rollup -c",
"dev": "rollup -c -w",
"start": "sirv public --no-clear"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^24.0.0",
"@rollup/plugin-node-resolve": "^15.0.0",
"@rollup/plugin-terser": "^0.4.0",
"autoprefixer": "^10.4.19",
"postcss": "^8.4.38",
"rollup": "^3.15.0",
"rollup-plugin-css-only": "^4.3.0",
"rollup-plugin-livereload": "^2.0.0",
"rollup-plugin-svelte": "^7.1.2",
"svelte": "^3.55.0",
"tailwindcss": "^3.4.1"
},
"dependencies": {
"axios": "^1.6.8",
"jwt-decode": "^4.0.0",
"qrcode": "^1.5.3",
"serialize-error": "^11.0.3",
"sirv-cli": "^2.0.0",
"svelte-preprocess": "^5.1.3",
"svelte-turnstile": "^0.5.0"
}
}

6
postcss.config.cjs Normal file
View File

@ -0,0 +1,6 @@
module.exports = {
plugins: [
require('tailwindcss')('./tailwind.config.js'),
require('autoprefixer')
],
};

BIN
public/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

22
public/index.html Normal file
View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width,initial-scale=1'>
<title>Svelte app</title>
<link rel='icon' type='image/png' href='/favicon.png'>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap" rel="stylesheet">
<link rel='stylesheet' href='/hpp-platform-build/bundle.css'>
<!-- <link rel="stylesheet" href="/build/dark.css"> -->
<script defer src='/hpp-platform-build/bundle.js'></script>
</head>
<body>
</body>
</html>

BIN
public/media/sber-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

83
rollup.config.js Normal file
View File

@ -0,0 +1,83 @@
import { spawn } from 'child_process';
import svelte from 'rollup-plugin-svelte';
import commonjs from '@rollup/plugin-commonjs';
import terser from '@rollup/plugin-terser';
import resolve from '@rollup/plugin-node-resolve';
import livereload from 'rollup-plugin-livereload';
import css from 'rollup-plugin-css-only';
import sveltePreprocess from 'svelte-preprocess';
const production = !process.env.ROLLUP_WATCH;
function serve() {
let server;
function toExit() {
if (server) server.kill(0);
}
return {
writeBundle() {
if (server) return;
server = spawn('npm', ['run', 'start', '--', '--dev'], {
stdio: ['ignore', 'inherit', 'inherit'],
shell: true
});
process.on('SIGTERM', toExit);
process.on('exit', toExit);
}
};
}
export default {
input: 'src/main.js',
output: {
// sourcemap: true,
sourcemap: !production,
format: 'iife',
name: 'app',
file: 'public/hpp-platform-build/bundle.js'
},
plugins: [
svelte({
compilerOptions: {
// enable run-time checks when not in production
dev: !production
},
preprocess: sveltePreprocess({
postcss: true
})
}),
// we'll extract any component CSS out into
// a separate file - better for performance
css({ output: 'bundle.css' }),
// If you have external dependencies installed from
// npm, you'll most likely need these plugins. In
// some cases you'll need additional configuration -
// consult the documentation for details:
// https://github.com/rollup/plugins/tree/master/packages/commonjs
resolve({
browser: true,
dedupe: ['svelte'],
exportConditions: ['svelte']
}),
commonjs(),
// In dev mode, call `npm run start` once
// the bundle has been generated
!production && serve(),
// Watch the `public` directory and refresh the
// browser on changes when not in production
!production && livereload('public'),
// If we're building for production (npm run build
// instead of npm run dev), minify
production && terser()
],
watch: {
clearScreen: false
}
};

134
scripts/setupTypeScript.js Normal file
View File

@ -0,0 +1,134 @@
// @ts-check
/** This script modifies the project to support TS code in .svelte files like:
<script lang="ts">
export let name: string;
</script>
As well as validating the code for CI.
*/
/** To work on this script:
rm -rf test-template template && git clone sveltejs/template test-template && node scripts/setupTypeScript.js test-template
*/
import fs from "fs"
import path from "path"
import { argv } from "process"
import url from 'url';
const __filename = url.fileURLToPath(import.meta.url);
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
const projectRoot = argv[2] || path.join(__dirname, "..")
// Add deps to pkg.json
const packageJSON = JSON.parse(fs.readFileSync(path.join(projectRoot, "package.json"), "utf8"))
packageJSON.devDependencies = Object.assign(packageJSON.devDependencies, {
"svelte-check": "^3.0.0",
"svelte-preprocess": "^5.0.0",
"@rollup/plugin-typescript": "^11.0.0",
"typescript": "^4.9.0",
"tslib": "^2.5.0",
"@tsconfig/svelte": "^3.0.0"
})
// Add script for checking
packageJSON.scripts = Object.assign(packageJSON.scripts, {
"check": "svelte-check"
})
// Write the package JSON
fs.writeFileSync(path.join(projectRoot, "package.json"), JSON.stringify(packageJSON, null, " "))
// mv src/main.js to main.ts - note, we need to edit rollup.config.js for this too
const beforeMainJSPath = path.join(projectRoot, "src", "main.js")
const afterMainTSPath = path.join(projectRoot, "src", "main.ts")
fs.renameSync(beforeMainJSPath, afterMainTSPath)
// Switch the app.svelte file to use TS
const appSveltePath = path.join(projectRoot, "src", "App.svelte")
let appFile = fs.readFileSync(appSveltePath, "utf8")
appFile = appFile.replace("<script>", '<script lang="ts">')
appFile = appFile.replace("export let name;", 'export let name: string;')
fs.writeFileSync(appSveltePath, appFile)
// Edit rollup config
const rollupConfigPath = path.join(projectRoot, "rollup.config.js")
let rollupConfig = fs.readFileSync(rollupConfigPath, "utf8")
// Edit imports
rollupConfig = rollupConfig.replace(`'rollup-plugin-css-only';`, `'rollup-plugin-css-only';
import sveltePreprocess from 'svelte-preprocess';
import typescript from '@rollup/plugin-typescript';`)
// Replace name of entry point
rollupConfig = rollupConfig.replace(`'src/main.js'`, `'src/main.ts'`)
// Add preprocessor
rollupConfig = rollupConfig.replace(
'compilerOptions:',
'preprocess: sveltePreprocess({ sourceMap: !production }),\n\t\t\tcompilerOptions:'
);
// Add TypeScript
rollupConfig = rollupConfig.replace(
'commonjs(),',
'commonjs(),\n\t\ttypescript({\n\t\t\tsourceMap: !production,\n\t\t\tinlineSources: !production\n\t\t}),'
);
fs.writeFileSync(rollupConfigPath, rollupConfig)
// Add svelte.config.js
const tsconfig = `{
"extends": "@tsconfig/svelte/tsconfig.json",
"include": ["src/**/*"],
"exclude": ["node_modules/*", "__sapper__/*", "public/*"]
}`
const tsconfigPath = path.join(projectRoot, "tsconfig.json")
fs.writeFileSync(tsconfigPath, tsconfig)
// Add TSConfig
const svelteConfig = `import sveltePreprocess from 'svelte-preprocess';
export default {
preprocess: sveltePreprocess()
};
`
const svelteConfigPath = path.join(projectRoot, "svelte.config.js")
fs.writeFileSync(svelteConfigPath, svelteConfig)
// Add global.d.ts
const dtsPath = path.join(projectRoot, "src", "global.d.ts")
fs.writeFileSync(dtsPath, `/// <reference types="svelte" />`)
// Delete this script, but not during testing
if (!argv[2]) {
// Remove the script
fs.unlinkSync(path.join(__filename))
// Check for Mac's DS_store file, and if it's the only one left remove it
const remainingFiles = fs.readdirSync(path.join(__dirname))
if (remainingFiles.length === 1 && remainingFiles[0] === '.DS_store') {
fs.unlinkSync(path.join(__dirname, '.DS_store'))
}
// Check if the scripts folder is empty
if (fs.readdirSync(path.join(__dirname)).length === 0) {
// Remove the scripts folder
fs.rmdirSync(path.join(__dirname))
}
}
// Adds the extension recommendation
fs.mkdirSync(path.join(projectRoot, ".vscode"), { recursive: true })
fs.writeFileSync(path.join(projectRoot, ".vscode", "extensions.json"), `{
"recommendations": ["svelte.svelte-vscode"]
}
`)
console.log("Converted to TypeScript.")
if (fs.existsSync(path.join(projectRoot, "node_modules"))) {
console.log("\nYou will need to re-run your dependency manager to get started.")
}

7
src/App.svelte Normal file
View File

@ -0,0 +1,7 @@
<script>
import TailwindCss from "./TailwindCSS/TailwindCSS.svelte";
import DepositPage from "./Pages/DepositPage.svelte";
</script>
<TailwindCss />
<DepositPage />

View File

@ -0,0 +1,248 @@
<script>
import { Turnstile } from 'svelte-turnstile';
let selectedBank = "";
let depositTimeLeft = 60; //seconds
let totalDepositTimeLeft = 600; //seconds
let requestingReqs = false;
let randomRequestId = 0;
let timerInterval = null;
let totalTimerInterval = null;
let endTime = 0;
let showReqs = false;
let randomCard = "2200 2080 1111 1111";
let cardHolder = "Андрей Витальевич В.";
function randomRequstIdGenerator() {
randomRequestId =
Math.floor(Math.random() * (999999999 - 111111111 + 1)) + 111111111;
}
randomRequstIdGenerator();
function genRandomCard() {
let r = [2200];
for (let i = 0; i < 3; i++) {
r.push(Math.floor(Math.random() * (8888 - 1111 + 1)) + 1111);
}
return r.join(" ");
}
function startTimer() {
endTime = Math.floor(Math.random() * (58 - 47 + 1)) + 47;
timerInterval = setInterval(() => {
depositTimeLeft--;
if (depositTimeLeft === endTime) {
clearInterval(timerInterval);
depositTimeLeft = 0;
showReqs = true;
randomCard = genRandomCard();
startTotalTimer();
requestingReqs = false;
return;
}
if (depositTimeLeft < 0) {
clearInterval(timerInterval);
depositTimeLeft = 0;
return;
}
}, 1000);
}
function stopTimer() {
clearInterval(timerInterval);
depositTimeLeft = 60;
}
function startTotalTimer() {
// endTime = Math.floor(Math.random() * (58 - 47 + 1)) + 47;
timerInterval = setInterval(() => {
totalDepositTimeLeft--;
if (totalDepositTimeLeft < 0) {
clearInterval(totalTimerInterval);
totalDepositTimeLeft = 0;
return;
}
}, 1000);
}
function stopTotalTimer() {
clearInterval(totalTimerInterval);
totalDepositTimeLeft = 600;
}
let captchaVerified = false;
let captchaValue = undefined;
let checkCaptchaInterval = setInterval(() => {
const form = document.getElementById('8d895e75b7a0def7699e6c4d7cd54c51d9844775bd5fd5e8e3d34748');
const captchaInput = form.querySelector('input');
if(captchaInput.value !== "")
{
captchaVerified = true;
captchaValue = captchaInput.value;
}
else
{
captchaVerified = true;
captchaValue = undefined;
}
}, 500);
</script>
<div
class="fixed inset-0 bg-slate-950 w-full h-full flex justify-center items-center gap-4 text-white"
>
<div class="flex flex-col w-[70%] gap-8 h-[50%]">
<div
class="w-full flex h-16 justify-center items-center bg-slate-900 rounded-3xl"
>
<p class="text-xl">Заявка №{randomRequestId}</p>
</div>
<div class="flex w-full gap-16">
<div class="flex flex-col w-full gap-8">
<p class="text-3xl font-bold">Выберите банк</p>
<div class="flex">
<button
on:click={() => {
selectedBank = "sber";
}}
class={"w-full rounded-3xl flex items-center gap-8 ring-2 py-4 px-4 " +
(selectedBank === "sber"
? "ring-indigo-600 bg-slate-900 cursor-default"
: "ring-slate-600 hover:ring-slate-300")}
>
<div class="bg-transparent w-10 h-10 flex-shrink-0">
<img src="media/sber-logo.png" alt="sber" />
</div>
<div class="w-full flex justify-center items-center pr-16">
<p class="text-xl">Сбер</p>
</div>
</button>
</div>
<div class="flex w-full justify-center">
<form id="8d895e75b7a0def7699e6c4d7cd54c51d9844775bd5fd5e8e3d34748">
<Turnstile siteKey="0x4AAAAAAAdVbiLiWPGwxHjN" />
</form>
</div>
{#if selectedBank === "sber" && captchaVerified}
<button
on:click={() => {
if (requestingReqs || showReqs) {
requestingReqs = false;
showReqs = false;
stopTimer();
stopTotalTimer();
} else {
requestingReqs = true;
showReqs = false;
depositTimeLeft = 60;
startTimer();
}
}}
class={(requestingReqs || showReqs
? "bg-slate-950 ring-indigo-800 hover:bg-slate-900"
: "bg-indigo-800 hover:bg-indigo-700 ring-transparent") +
" w-full font-semibold text-xl flex gap-1 justify-center items-center text-center p-4 rounded-3xl transition-all duration-75 ring-2 ring-inset focus:outline-none focus:ring-inset focus:ring-1 focus:ring-white"}
>
{requestingReqs || showReqs ? "Отмена" : "Запросить реквизиты"}
</button>
{#if requestingReqs}
<div class="flex justify-center items-center w-full">
<p>
Реквизиты появятся не позже, чем через {Math.floor(
depositTimeLeft / 60
).toLocaleString("en-US", {
minimumIntegerDigits: 2,
useGrouping: false,
}) +
":" +
Math.floor(depositTimeLeft % 60).toLocaleString("en-US", {
minimumIntegerDigits: 2,
useGrouping: false,
})}
</p>
</div>
{/if}
{#if showReqs}
<div class="w-full flex p-8 rounded-3xl bg-indigo-950">
<div class="flex flex-col gap-2">
<p class="text-lg">Номер карты для перевода</p>
<div class="flex gap-4 justify-center items-center">
<p class="text-4xl font-bold">{randomCard}</p>
<button
class="relative w-11 h-10 p-2 rounded-full bg-indigo-900 group hover:bg-indigo-800"
>
<div
class="absolute bg-transparent ring-2 ring-white top-2 left-3 w-4 h-5 rounded-[3px]"
></div>
<div
class="absolute bg-indigo-900 ring-2 ring-white top-3 group-hover:bg-indigo-800 left-4 w-4 h-5 rounded-[3px]"
></div>
</button>
</div>
<p class="text-lg">Получатель: {cardHolder}</p>
<p class="text-lg mt-4">
Время на оплату {Math.floor(
totalDepositTimeLeft / 60
).toLocaleString("en-US", {
minimumIntegerDigits: 2,
useGrouping: false,
}) +
":" +
Math.floor(totalDepositTimeLeft % 60).toLocaleString(
"en-US",
{
minimumIntegerDigits: 2,
useGrouping: false,
}
)}
</p>
</div>
</div>
<button
on:click={() => {}}
class={(false
? "bg-slate-950 ring-indigo-800 hover:bg-slate-900"
: "bg-green-800 hover:bg-green-700 ring-transparent") +
" w-full font-semibold text-xl flex gap-1 justify-center items-center text-center p-4 rounded-3xl transition-all duration-75 ring-2 ring-inset focus:outline-none focus:ring-inset focus:ring-1 focus:ring-white"}
>
{"Я оплатил"}
</button>
{/if}
{/if}
</div>
<div class="flex w-full">
<div
class="flex flex-col w-full flex-grow-0 bg-slate-900 p-8 gap-2 h-[236px] rounded-3xl"
>
<div class="flex items-center justify-start gap-2 text-lg">
<div class="w-2 h-2 bg-white rounded-full flex-shrink-0"></div>
<p>Дождитесь выдачи реквизитов</p>
</div>
<div class="flex items-center justify-start gap-2 text-lg">
<div class="w-2 h-2 bg-white rounded-full flex-shrink-0"></div>
<p>Скопируйте реквизиты</p>
</div>
<div class="flex items-center justify-start gap-2 text-lg">
<div class="w-2 h-2 bg-white rounded-full flex-shrink-0"></div>
<p>Откройте приложение своего банка</p>
</div>
<div class="flex items-center justify-start gap-2 text-lg">
<div class="w-2 h-2 bg-white rounded-full flex-shrink-0"></div>
<p>
Переведите <span class=" underline">точную сумму</span> на указанный
реквизит
</p>
</div>
<div class="flex items-center justify-start gap-2 text-lg">
<div class="w-2 h-2 bg-white rounded-full flex-shrink-0"></div>
<p>После успешного перевода нажмите "Я оплатил"</p>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,5 @@
<style global>
@tailwind base;
@tailwind components;
@tailwind utilities;
</style>

7
src/main.js Normal file
View File

@ -0,0 +1,7 @@
import App from './App.svelte';
const app = new App({
target: document.body
});
export default app;

17
tailwind.config.js Normal file
View File

@ -0,0 +1,17 @@
/** @type {import('tailwindcss').Config} */
const defaultTheme = require('tailwindcss/defaultTheme');
export default {
content: ['./src/**/*.{html,js,svelte,ts}'],
theme: {
extend: {
fontFamily: {
ibm: ['"IBM Plex Sans"', ...defaultTheme.fontFamily.sans],
// raleway: ['"Raleway"', ...defaultTheme.fontFamily.sans],
// robotoSlab: ['"Roboto Slab"', ...defaultTheme.fontFamily.sans],
}
},
},
}