Skip to content

Commit

Permalink
[feat] add free nip5 option (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
motorina0 authored Nov 29, 2024
1 parent 8d02d39 commit 00771df
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 40 deletions.
5 changes: 4 additions & 1 deletion src/boot/saas.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ const saas = {
data: {
domain_id: this.domain,
local_part: data.identifier,
pubkey: data.pubkey,
pubkey: data.pubkey || "",
years: data.years,
promo_code: data.promo_code,
referer: data.referer,
Expand Down Expand Up @@ -171,6 +171,9 @@ const saas = {
if (typeof data === "string") {
return data;
}
if (typeof data.detail === "string") {
return data.detail;
}
return data?.detail?.map((d) => d.msg).join(", ");
},
};
Expand Down
109 changes: 85 additions & 24 deletions src/components/cards/CardItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,40 +16,85 @@
</q-card-section>
<q-card-section class="text-grey-5 q-mb-sm">
<div v-if="data.available" class="text-h6">
<q-badge class="text-h6 q-mr-sm" color="secondary" text-color="primary">
{{ name }}
</q-badge>
<span>is available!</span>
&nbsp;Get it now for
<span
>{{
data.currency !== "sats"
? formatCurrency(data.price, data.currency)
: formatSat(data.price)
}}.</span
>
<div>
<q-badge
class="text-h6 q-mr-sm"
color="secondary"
text-color="primary"
>
<span v-text="data.identifier + '@nostr.com'"></span>
</q-badge>
<span>is available!</span>
&nbsp;Get it now for
<span
>{{
data.currency !== "sats"
? formatCurrency(data.price, data.currency)
: formatSat(data.price)
}}!</span
>
<q-btn
v-if="data.available"
rounded
color="secondary"
text-color="primary"
label="Add to Cart"
class="text-capitalize q-ml-auto float-right"
@click="action"
/>
</div>
</div>
<div v-else class="text-h6">
<span>
The handle <span>{{ name }}</span> is not available!
</span>
</div>

<div v-if="data.hasFreeOption" class="q-mt-lg text-h6">
<div class="q-ma-md q-pa-md"></div>
<q-badge
outline
class="text-h6 q-mr-sm"
color="secondary"
text-color="secondary"
>
<span v-text="data.identifier + '.'"></span>
<q-input
v-model="data.free_identifier_number"
type="number"
min="0"
max="999999"
autofocus
dense
:rules="[(val) => val.length <= 6 || 'Max 6 characters']"
class="my-input q-pb-none"
:input-style="{
fontSize: '22px',
color: '#7dd3fc',
}"
>
</q-input>
<span>@nostr.com</span>
</q-badge>

<span>is available for free!</span>
<q-btn
outline
rounded
color="primary"
text-color="secondary"
label="Get free identifier"
class="text-capitalize q-ml-auto float-right"
@click="free"
/>
</div>
</q-card-section>
<q-card-actions v-if="data.available">
<q-btn
rounded
color="secondary"
text-color="primary"
label="Add to Cart"
class="text-capitalize q-ml-auto float-right"
@click="action"
/>
</q-card-actions>
<q-card-actions v-if="data.available"> </q-card-actions>
</q-card>
</template>

<script setup>
defineProps(["name", "data", "close", "action"]);
defineProps(["name", "data", "close", "action", "free"]);
const formatCurrency = (value, currency) => {
return new Intl.NumberFormat(window.LOCALE, {
Expand All @@ -62,4 +107,20 @@ const formatSat = (value) => {
};
</script>

<style lang="scss"></style>
<style lang="scss">
.my-input {
font-style: "22px";
color: "#7dd3fc";
/* Chrome, Safari, Edge, Opera */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* Firefox */
input[type="number"] {
-moz-appearance: textfield;
}
}
</style>
1 change: 1 addition & 0 deletions src/pages/Cart.vue
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ onMounted(async () => {
if ($store.newCartIdentifier) {
const { data } = await saas.createIdentity({
identifier: $store.newCartIdentifier,
pubkey: $store.pubkey,
});
identities.value = identities.value.filter((i) => i.id !== data.id);
identities.value.unshift(data);
Expand Down
32 changes: 26 additions & 6 deletions src/pages/Identities.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@
</q-input>

<div
v-if="newIdentity && compareIgnoreCase(newIdentity.identifier, filterText)"
v-if="
newIdentity && compareIgnoreCase(newIdentity.identifier, filterText)
"
class="nip-list"
>
<CardItem
Expand Down Expand Up @@ -167,7 +169,7 @@ const filterIdentifier = (id, filter) => {
if (!filterText.value) {
return true;
}
filter = (filter || "").toLowerCase()
filter = (filter || "").toLowerCase();
if (id.local_part.toLowerCase().indexOf(filter) !== -1) {
return true;
}
Expand Down Expand Up @@ -209,11 +211,11 @@ const handleSearch = async () => {
};
const compareIgnoreCase = (a, b) => {
if (!a || !b){
return false
if (!a || !b) {
return false;
}
return a.toLowerCase() === b.toLowerCase()
}
return a.toLowerCase() === b.toLowerCase();
};
const handleBuy = () => {
$store.newCartIdentifier = filterText;
Expand All @@ -225,6 +227,24 @@ const handleBuy = () => {
onMounted(async () => {
identities.value = [...$store.identities.values()];
await getIdentities();
if ($store.freeCartIdentifier) {
try {
await saas.createIdentity({
identifier: $store.freeCartIdentifier,
pubkey: $store.pubkey || "",
});
} catch (error) {
$q.notify({
message: "Failed to create identifier.",
caption: saas.mapErrorToString(error),
color: "negative",
icon: "warning",
});
}
$store.freeCartIdentifier = null
$store.pubkey = null
await getIdentities();
}
});
</script>

Expand Down
50 changes: 50 additions & 0 deletions src/pages/Index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -67,16 +67,40 @@
/>
</template>
</q-input>

<div class="flex full-width justify-center" ref="nipCard">
<div class="nip-list q-pa-lg" v-if="$store.showCard">
<CardItem
:name="$store.handle"
:data="$store.handleData"
:close="closeCard"
:action="handleBuy"
:free="handleFreeId"
/>
</div>
</div>
<q-badge
v-if="$store.pubkey"
outline
color="secondary"
class="q-pt-none q-pb-none"
dense
>
<span
v-text="'npub: ' + $store.pubkey"
dense
style="white-space: normal; word-break: break-all"
></span>
<q-btn
@click="$store.pubkey = null"
class="q-ml-lg"
icon="close"
color="white"
flat
round
dense
/>
</q-badge>
</div>
</q-page>
</template>
Expand Down Expand Up @@ -107,6 +131,7 @@ const handleSearch = async () => {
try {
const { data } = await saas.queryIdentifier(handle.value);
$store.handle = handle.value;
data.hasFreeOption = !!data.free_identifier_number;
$store.handleData = data;
} catch (error) {
console.error("Error searching for identifier: ", error);
Expand Down Expand Up @@ -138,6 +163,31 @@ const handleBuy = () => {
}, 500);
};
const handleFreeId = () => {
if (!$store.isLoggedIn) {
$q.notify({
message: "Please to get your free identifier",
color: "warning",
textColor: "black",
});
}
$store.buying = true;
if ($store.handleData.hasFreeOption) {
$store.freeCartIdentifier =
$store.handleData.identifier +
"." +
$store.handleData.free_identifier_number.padStart(6, "0");
}
$store.handle = "";
setTimeout(() => {
$router.push({ path: "/identities" });
}, 500);
};
const pubkey = $route.query["npub"] || $route.query["pubkey"];
if (pubkey) {
$store.pubkey = pubkey;
}
if ($route.query["q"]) {
handle.value = $route.query["q"];
handleSearch();
Expand Down
25 changes: 16 additions & 9 deletions src/pages/Login.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,12 @@
:disable="inProgress"
/>
<q-btn

@click="isTermsAndConditionsRequest = false"
label="Back"
type="button"
class="full-width q-mt-md"
color="grey"
/>
@click="isTermsAndConditionsRequest = false"
label="Back"
type="button"
class="full-width q-mt-md"
color="grey"
/>
</q-card-section>
<q-card-section v-else class="q-ma-xl q-pa-md"
>Terms and Conditions loading....
Expand Down Expand Up @@ -186,7 +185,13 @@ export default defineComponent({
color: "positive",
});
this.store.username = this.username;
const path = this.store.newCartIdentifier ? "/cart" : "/";
let path = "/";
if (this.store.newCartIdentifier) {
path = "/cart";
} else if (this.store.freeCartIdentifier) {
path = "/identities";
}
setTimeout(() => this.$router.push(path), 500);
} catch (error) {
console.warn(error);
Expand Down Expand Up @@ -246,7 +251,9 @@ export default defineComponent({
},
async showTermsAndConditions() {
this.isTermsAndConditionsRequest = true;
this.termsAndConditions = await markdownToHTML(process.env.termsAndConditionsUrl);
this.termsAndConditions = await markdownToHTML(
process.env.termsAndConditionsUrl
);
},
async signup() {
if (!this.isSignupRequest) {
Expand Down
2 changes: 2 additions & 0 deletions src/stores/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { defineStore } from "pinia";
export const useAppStore = defineStore("store", {
state: () => ({
newCartIdentifier: null,
freeCartIdentifier: null,
username: null,
pubkey: null,
handle: "",
handleData: {},
buying: false,
Expand Down

0 comments on commit 00771df

Please sign in to comment.