Browse Source

Awesome QR at checkout

vue
Lev 2 years ago
parent
commit
c336c62c32
  1. 28
      .idea/workspace.xml
  2. 27
      package-lock.json
  3. 1
      package.json
  4. 4
      src/components/ZonePricing.vue
  5. 29
      src/result.ts
  6. 82
      src/views/Checkout.vue

28
.idea/workspace.xml

@ -1,15 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="ddb8afd5-d3ba-47b1-b6d0-227403f1abf7" name="Changes" comment="&quot;All zones&quot; button + some other stuff"> <list default="true" id="ddb8afd5-d3ba-47b1-b6d0-227403f1abf7" name="Changes" comment="Awesome QR at checkout">
<change afterPath="$PROJECT_DIR$/src/assets/icons/ton_left.svg" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/assets/main.css" beforeDir="false" afterPath="$PROJECT_DIR$/src/assets/main.css" afterDir="false" /> <change beforePath="$PROJECT_DIR$/package-lock.json" beforeDir="false" afterPath="$PROJECT_DIR$/package-lock.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/components/DarkLayout.vue" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/DarkLayout.vue" afterDir="false" /> <change beforePath="$PROJECT_DIR$/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/package.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/components/Header.vue" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/Header.vue" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/components/ZonePricing.vue" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/ZonePricing.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/views/Explore.vue" beforeDir="false" afterPath="$PROJECT_DIR$/src/views/Explore.vue" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/result.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/result.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/views/FindQ.vue" beforeDir="false" afterPath="$PROJECT_DIR$/src/views/FindQ.vue" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/views/Checkout.vue" beforeDir="false" afterPath="$PROJECT_DIR$/src/views/Checkout.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/views/Get.vue" beforeDir="false" afterPath="$PROJECT_DIR$/src/views/Get.vue" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -77,7 +75,7 @@
<workItem from="1670927344373" duration="29000" /> <workItem from="1670927344373" duration="29000" />
<workItem from="1670927391338" duration="2277000" /> <workItem from="1670927391338" duration="2277000" />
<workItem from="1671024025708" duration="19806000" /> <workItem from="1671024025708" duration="19806000" />
<workItem from="1671204365793" duration="15716000" /> <workItem from="1671204365793" duration="19127000" />
</task> </task>
<task id="LOCAL-00001" summary="Wrote the landing"> <task id="LOCAL-00001" summary="Wrote the landing">
<created>1670844191163</created> <created>1670844191163</created>
@ -149,7 +147,14 @@
<option name="project" value="LOCAL" /> <option name="project" value="LOCAL" />
<updated>1671227655693</updated> <updated>1671227655693</updated>
</task> </task>
<option name="localTasksCounter" value="11" /> <task id="LOCAL-00011" summary="&quot;All zones&quot; button + some other stuff">
<created>1671240411281</created>
<option name="number" value="00011" />
<option name="presentableId" value="LOCAL-00011" />
<option name="project" value="LOCAL" />
<updated>1671240411281</updated>
</task>
<option name="localTasksCounter" value="12" />
<servers /> <servers />
</component> </component>
<component name="TypeScriptGeneratedFilesManager"> <component name="TypeScriptGeneratedFilesManager">
@ -178,6 +183,7 @@
<MESSAGE value="Displaying results" /> <MESSAGE value="Displaying results" />
<MESSAGE value="Checkout, Explore" /> <MESSAGE value="Checkout, Explore" />
<MESSAGE value="&quot;All zones&quot; button + some other stuff" /> <MESSAGE value="&quot;All zones&quot; button + some other stuff" />
<option name="LAST_COMMIT_MESSAGE" value="&quot;All zones&quot; button + some other stuff" /> <MESSAGE value="Awesome QR at checkout" />
<option name="LAST_COMMIT_MESSAGE" value="Awesome QR at checkout" />
</component> </component>
</project> </project>

27
package-lock.json generated

@ -11,6 +11,7 @@
"@popperjs/core": "^2.11.6", "@popperjs/core": "^2.11.6",
"axios": "^1.2.1", "axios": "^1.2.1",
"bulma": "^0.9.4", "bulma": "^0.9.4",
"qr-code-styling": "^1.6.0-rc.1",
"sass": "^1.56.2", "sass": "^1.56.2",
"vue": "^3.2.45", "vue": "^3.2.45",
"vue-contenteditable": "^4.1.0", "vue-contenteditable": "^4.1.0",
@ -2122,6 +2123,19 @@
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
}, },
"node_modules/qr-code-styling": {
"version": "1.6.0-rc.1",
"resolved": "https://registry.npmjs.org/qr-code-styling/-/qr-code-styling-1.6.0-rc.1.tgz",
"integrity": "sha512-ModRIiW6oUnsP18QzrRYZSc/CFKFKIdj7pUs57AEVH20ajlglRpN3HukjHk0UbNMTlKGuaYl7Gt6/O5Gg2NU2Q==",
"dependencies": {
"qrcode-generator": "^1.4.3"
}
},
"node_modules/qrcode-generator": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/qrcode-generator/-/qrcode-generator-1.4.4.tgz",
"integrity": "sha512-HM7yY8O2ilqhmULxGMpcHSF1EhJJ9yBj8gvDEuZ6M+KGJ0YY2hKpnXvRD+hZPLrDVck3ExIGhmPtSdcjC+guuw=="
},
"node_modules/queue-microtask": { "node_modules/queue-microtask": {
"version": "1.2.3", "version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@ -4154,6 +4168,19 @@
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
}, },
"qr-code-styling": {
"version": "1.6.0-rc.1",
"resolved": "https://registry.npmjs.org/qr-code-styling/-/qr-code-styling-1.6.0-rc.1.tgz",
"integrity": "sha512-ModRIiW6oUnsP18QzrRYZSc/CFKFKIdj7pUs57AEVH20ajlglRpN3HukjHk0UbNMTlKGuaYl7Gt6/O5Gg2NU2Q==",
"requires": {
"qrcode-generator": "^1.4.3"
}
},
"qrcode-generator": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/qrcode-generator/-/qrcode-generator-1.4.4.tgz",
"integrity": "sha512-HM7yY8O2ilqhmULxGMpcHSF1EhJJ9yBj8gvDEuZ6M+KGJ0YY2hKpnXvRD+hZPLrDVck3ExIGhmPtSdcjC+guuw=="
},
"queue-microtask": { "queue-microtask": {
"version": "1.2.3", "version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",

1
package.json

@ -13,6 +13,7 @@
"@popperjs/core": "^2.11.6", "@popperjs/core": "^2.11.6",
"axios": "^1.2.1", "axios": "^1.2.1",
"bulma": "^0.9.4", "bulma": "^0.9.4",
"qr-code-styling": "^1.6.0-rc.1",
"sass": "^1.56.2", "sass": "^1.56.2",
"vue": "^3.2.45", "vue": "^3.2.45",
"vue-contenteditable": "^4.1.0", "vue-contenteditable": "^4.1.0",

4
src/components/ZonePricing.vue

@ -26,7 +26,7 @@
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td>{{ '*'.repeat(zone.length_1) + zone.zone }}</td> <td>{{ '*'.repeat(zone.length_1) + '.' + zone.zone }}</td>
<td v-if="zone.canAuction()"> <td v-if="zone.canAuction()">
<TonButton>{{ zone.price_auction_1 }}</TonButton> <TonButton>{{ zone.price_auction_1 }}</TonButton>
</td> </td>
@ -35,7 +35,7 @@
</td> </td>
</tr> </tr>
<tr> <tr>
<td>{{ '*'.repeat(zone.length_2) + zone.zone }}</td> <td>{{ '*'.repeat(zone.length_2) + '.' + zone.zone }}</td>
<td v-if="zone.canAuction()"> <td v-if="zone.canAuction()">
<TonButton>{{ zone.price_auction_2 }}</TonButton> <TonButton>{{ zone.price_auction_2 }}</TonButton>
</td> </td>

29
src/result.ts

@ -28,6 +28,10 @@ export class Result {
canBuy(): boolean { canBuy(): boolean {
return this.buy_price !== undefined && this.buy_price !== null; return this.buy_price !== undefined && this.buy_price !== null;
} }
zone(): string {
return this.domain.split('.').slice(1).join('.');
}
} }
const sleep = (milliseconds: number) => { const sleep = (milliseconds: number) => {
@ -53,3 +57,28 @@ export async function get_domain_result(domain: string) {
} }
return new Result(domain, 5, 3); return new Result(domain, 5, 3);
} }
export class TonLink {
address: string;
sum?: number;
message: string;
constructor(address: string, message: string, sum?: number) {
this.address = address;
this.sum = sum;
this.message = message;
}
getLink(): string {
let link = `ton://${this.address}/transfer?message=${this.message}`;
if (this.sum !== undefined) {
link += `&amount=${this.sum}`;
}
return link;
}
}
// Get the link for buying a domain
export function get_ton_link(res: Result) {
return new TonLink(res.zone(), res.buy_price!, 'b/' + res.domain);
}

82
src/views/Checkout.vue

@ -1,15 +1,22 @@
<template> <template>
<DarkLayout> <DarkLayout>
<!-- todo: button to go back to Get --> <!-- todo: button to go back to Get -->
<div class="to-buy">To buy</div> <!-- todo: handle auction -->
<div class="text">To buy</div>
<DomainBar :zone="'.' + zone" :value="domain" :has_button="false" :editable="false"/> <DomainBar :zone="'.' + zone" :value="domain" :has_button="false" :editable="false"/>
<div class="text">Scan this:</div>
<div class="qr">
<div ref="qrCode"></div>
</div>
</DarkLayout> </DarkLayout>
</template> </template>
<script> <script>
import DarkLayout from "../components/DarkLayout.vue"; import DarkLayout from "../components/DarkLayout.vue";
import DomainBar from "../components/DomainBar.vue"; import DomainBar from "../components/DomainBar.vue";
import {get_domain_result, get_ton_link} from "../result";
import QRCodeStyling from 'qr-code-styling';
export default { export default {
name: "Checkout", name: "Checkout",
components: {DomainBar, DarkLayout}, components: {DomainBar, DarkLayout},
@ -20,10 +27,77 @@ export default {
zone: { zone: {
type: String, type: String,
} }
},
data() {
return {
result: null,
ton_link: null,
qr_code: null,
}
},
methods: {
async get_result() {
this.result = await get_domain_result(this.domain + '.' + this.zone);
this.ton_link = await get_ton_link(this.result);
}
},
mounted() {
this.get_result().then(
() => {
this.qr_code = new QRCodeStyling(this.options)
this.qr_code.append(this.$refs["qrCode"])
}
)
},
computed: {
loaded () {
return this.result !== null && this.ton_link !== null;
},
options () {
if (!this.loaded) {
return null;
}
return {
width: 300,
height: 300,
type: 'svg',
data: this.ton_link.getLink(),
image: '/favicon.png',
margin: 10,
qrOptions: {
typeNumber: 0,
mode: 'Byte',
errorCorrectionLevel: 'Q'
},
imageOptions: {
hideBackgroundDots: true,
imageSize: 0.4,
margin: 5,
crossOrigin: 'anonymous',
},
dotsOptions: {
color: '#282e46',
type: 'rounded'
},
backgroundOptions: {
color: '#ffffff',
},
cornersSquareOptions: {
color: '#282e46',
type: 'extra-rounded',
},
cornersDotOptions: {
color: '#282e46',
type: 'dot',
}
};
}
} }
} }
</script> </script>
<style scoped> <style>
.qr > div > svg {
border-radius: 2rem;
}
</style> </style>
Loading…
Cancel
Save