Add payment methods screen
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Socket } from 'ngx-socket-io';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
|
||||
/*
|
||||
* The following interfaces are copied from the backend.
|
||||
@@ -26,17 +27,16 @@ export interface ICart {
|
||||
|
||||
export interface IPaymentMethod {
|
||||
method: any;
|
||||
amount: number
|
||||
amount: number;
|
||||
}
|
||||
|
||||
export enum PaymentStatus {
|
||||
CANCELLED = -2,
|
||||
REQUESTED = -1,
|
||||
PENDING = 0,
|
||||
PARTIALLY = 1,
|
||||
UNCONFIRMED = 2,
|
||||
DONE = 3,
|
||||
CANCELLED = 4
|
||||
UNCONFIRMED = 1,
|
||||
DONE = 2,
|
||||
}
|
||||
|
||||
export interface IInvoice {
|
||||
selector: string;
|
||||
paymentMethods: IPaymentMethod[];
|
||||
@@ -62,33 +62,132 @@ export class BackendService {
|
||||
|
||||
SERVER_URL = 'http://localhost:2009';
|
||||
|
||||
invoice: IInvoice | null = null;
|
||||
invoiceUpdate: BehaviorSubject<IInvoice | null>;
|
||||
|
||||
constructor(
|
||||
private socket: Socket,
|
||||
private http: HttpClient
|
||||
) {
|
||||
this.invoiceUpdate = new BehaviorSubject<IInvoice | null>(null);
|
||||
this.socket.on('status', (data: any) => {
|
||||
console.log('Status has been updated to: ', data);
|
||||
});
|
||||
this.socket.on('subscribe', (success: boolean) => {
|
||||
if (success) { console.log('We\'re getting the progress of this invoice!'); }
|
||||
else { console.log('Subscription failed'); }
|
||||
else { console.log('Subscribtion failed'); }
|
||||
});
|
||||
}
|
||||
|
||||
subscribeTo(selector: string) {
|
||||
getSocket(): Socket {
|
||||
return this.socket;
|
||||
}
|
||||
|
||||
subscribeTo(selector: string): void {
|
||||
this.socket.on('subscribe', (status: boolean) => {
|
||||
if (status) {
|
||||
this.updateInvoice();
|
||||
console.log('Successfully subscribed to this invoice');
|
||||
}
|
||||
else { console.log('Failed to subscribe'); }
|
||||
});
|
||||
|
||||
this.socket.emit('subscribe', { selector });
|
||||
}
|
||||
|
||||
getInvoice(selector: string): Promise<IInvoice> {
|
||||
updateInvoice(): void {
|
||||
if (this.invoice !== undefined || this.invoice !== null) {
|
||||
this.setInvoice(this.invoice?.selector!);
|
||||
}
|
||||
}
|
||||
|
||||
setInvoice(selector: string): Promise<IInvoice> {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
this.http.get(this.SERVER_URL + '/invoice/' + selector, {
|
||||
observe: 'body',
|
||||
responseType: 'json'
|
||||
}).toPromise().then((invoice) => {
|
||||
resolve(invoice as IInvoice);
|
||||
this.invoice = invoice as IInvoice;
|
||||
this.invoiceUpdate.next(this.invoice);
|
||||
resolve(this.invoice);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
setPaymentMethod(method: CryptoUnits): Promise<void> {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
this.http.post(`${this.SERVER_URL}/invoice/${this.invoice?.selector}/setmethod`, { method }, {
|
||||
responseType: 'json'
|
||||
}).toPromise().then(() => {
|
||||
this.setInvoice(this.invoice!!.selector);
|
||||
}).catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns Path to icon
|
||||
*/
|
||||
getIcon(unit: CryptoUnits): string {
|
||||
switch (unit) {
|
||||
case CryptoUnits.BITCOIN:
|
||||
return 'assets/Bitcoin.svg';
|
||||
case CryptoUnits.BITCOINCASH:
|
||||
return 'assets/BitcoinCash.svg';
|
||||
case CryptoUnits.DOGECOIN:
|
||||
return 'assets/Dogecoin.png';
|
||||
case CryptoUnits.ETHEREUM:
|
||||
return 'assets/Ethereum.svg';
|
||||
case CryptoUnits.LITECOIN:
|
||||
return 'assets/Litecoin.svg';
|
||||
case CryptoUnits.MONERO:
|
||||
return 'assets/Monero.svg';
|
||||
}
|
||||
}
|
||||
|
||||
findCryptoBySymbol(symbol: string): string | null {
|
||||
for (const coin in CryptoUnits) {
|
||||
// @ts-ignore: This actually works but I thing it's too hacky for TS. Allow me this one, please?
|
||||
if (CryptoUnits[coin] === symbol.toUpperCase()) {
|
||||
return coin.charAt(0).toUpperCase() + coin.toLowerCase().slice(1);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
getAmount(): string | undefined {
|
||||
return this.invoice?.paymentMethods.find(item => {
|
||||
return item.method === CryptoUnits.BITCOIN;
|
||||
})?.amount.toFixed(8);
|
||||
}
|
||||
|
||||
getStatus(): string {
|
||||
switch (this.invoice?.status) {
|
||||
case PaymentStatus.PENDING:
|
||||
return 'Pending';
|
||||
case PaymentStatus.UNCONFIRMED:
|
||||
return 'Unconfirmed';
|
||||
case PaymentStatus.DONE:
|
||||
return 'Paid';
|
||||
case PaymentStatus.CANCELLED:
|
||||
return 'Cancelled';
|
||||
default:
|
||||
return 'Unknown';
|
||||
}
|
||||
}
|
||||
|
||||
isInvoiceDone(): boolean {
|
||||
return this.invoice?.status === PaymentStatus.DONE;
|
||||
}
|
||||
|
||||
isInvoicePending(): boolean {
|
||||
return this.invoice?.status === PaymentStatus.PENDING;
|
||||
}
|
||||
|
||||
isInvoiceRequested(): boolean {
|
||||
return this.invoice?.status === PaymentStatus.REQUESTED;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<div class="header">
|
||||
<h2>LibrePay</h2>
|
||||
<a>Cancel payment</a>
|
||||
<a *ngIf="this.backend.isInvoicePending()">Cancel payment</a>
|
||||
</div>
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { BackendService } from '../backend.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-header',
|
||||
@@ -7,7 +8,7 @@ import { Component, OnInit } from '@angular/core';
|
||||
})
|
||||
export class HeaderComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
constructor(public backend: BackendService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
@@ -19,6 +19,17 @@
|
||||
/* box-shadow: 1px 1px 112px 23px rgba(0,0,0,0.75); */
|
||||
}
|
||||
|
||||
.smaller {
|
||||
min-width: 200px;
|
||||
width: 40vw !important;
|
||||
}
|
||||
|
||||
@media (max-width: 800px) {
|
||||
.content {
|
||||
width: 100vw !important;
|
||||
}
|
||||
}
|
||||
|
||||
.content * {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<div class="cube"></div>
|
||||
<div class="cube"></div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="content" [ngClass]="{smaller: this.backend.isInvoiceRequested()}">
|
||||
<app-header></app-header>
|
||||
<app-payment></app-payment>
|
||||
</div>
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { BackendService } from '../backend.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-pay',
|
||||
@@ -7,7 +8,7 @@ import { Component, OnInit } from '@angular/core';
|
||||
})
|
||||
export class PayComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
constructor(public backend: BackendService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
@@ -1,15 +1,23 @@
|
||||
.payment {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
height: 500px;
|
||||
background-color: hsl(0, 0%, 11%);
|
||||
border-radius: 8px;
|
||||
transform: translateY(-8px);
|
||||
}
|
||||
|
||||
.request {
|
||||
transform: translateY(-40px);
|
||||
}
|
||||
|
||||
.main {
|
||||
display: grid;
|
||||
height: 400px;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
|
||||
.qr {
|
||||
position: relative;
|
||||
transform: translateY(25%);
|
||||
@@ -42,12 +50,12 @@
|
||||
}
|
||||
|
||||
/* Data */
|
||||
.data {
|
||||
.main .data {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 50px;
|
||||
grid-template-rows: 1fr 4rem 4rem 4rem 1fr;
|
||||
}
|
||||
#target {
|
||||
.main #target {
|
||||
grid-row: 2;
|
||||
}
|
||||
#amount {
|
||||
@@ -57,6 +65,65 @@
|
||||
grid-row: 4;
|
||||
}
|
||||
|
||||
h3 {
|
||||
.main h3 {
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
#title {
|
||||
padding-top: 2rem;
|
||||
line-height: 1;
|
||||
font-size: 20pt;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#price {
|
||||
text-align: center;
|
||||
font-size: 16pt;
|
||||
}
|
||||
|
||||
#list {
|
||||
overflow-y: scroll;
|
||||
scroll-behavior: smooth;
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
#list::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#list li {
|
||||
padding-top: 10px;
|
||||
padding-left: 5%;
|
||||
padding-right: 5%;
|
||||
border-radius: 8px;
|
||||
display: grid;
|
||||
cursor: pointer;
|
||||
grid-template-columns: 75px 1fr;
|
||||
grid-row: 1fr;
|
||||
list-style: none;
|
||||
padding-bottom: 1rem;
|
||||
transition: .3s ease;
|
||||
line-height: 0;
|
||||
}
|
||||
#list li:hover {
|
||||
box-shadow: 0px 0px 61px 3px rgba(0,0,0,0.3) inset;
|
||||
}
|
||||
#list li img {
|
||||
height: 42px;
|
||||
width: 42px;
|
||||
margin: 0 auto;
|
||||
padding-top: 12px;
|
||||
grid-row-start: 1;
|
||||
grid-row-end: 2;
|
||||
}
|
||||
#list li p {
|
||||
grid-row: 1;
|
||||
grid-column: 2;
|
||||
}
|
||||
#list li h4 {
|
||||
grid-row: 2;
|
||||
grid-column: 2;
|
||||
}
|
||||
@@ -1,9 +1,23 @@
|
||||
<div class="payment">
|
||||
<div class="payment request" *ngIf="this.backend.isInvoiceRequested()">
|
||||
<h3 id="title">Choose your<br>payment method</h3>
|
||||
<p id="price">{{ this.backend.invoice!!.totalPrice!!.toFixed(2) }} €</p>
|
||||
|
||||
<ul id="list">
|
||||
<li *ngFor="let coin of this.backend.invoice!!.paymentMethods" (click)="chooseMethod(coin.method)">
|
||||
<img [src]="this.backend.getIcon(coin.method)">
|
||||
<div>
|
||||
<h4>{{ this.backend.findCryptoBySymbol(coin.method) }}</h4>
|
||||
<p>{{ coin.amount }} {{ coin.method }}</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="payment main" *ngIf="!this.backend.isInvoiceRequested() && ready">
|
||||
<div class="qrWrapper">
|
||||
<div class="qr">
|
||||
<img src="assets/Bitcoin.svg">
|
||||
<qrcode
|
||||
[qrdata]="'bitcoin:' + invoice!!.receiveAddress"
|
||||
[qrdata]="'bitcoin:' + this.backend.invoice!!.receiveAddress"
|
||||
[width]="256"
|
||||
[errorCorrectionLevel]="'M'"
|
||||
[elementType]="'svg'"
|
||||
@@ -12,16 +26,16 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="data" *ngIf="ready">
|
||||
<div class="data">
|
||||
<!-- Payment data -->
|
||||
<span id="target">Send to
|
||||
<h3>{{ invoice!!.receiveAddress }}</h3>
|
||||
<h3>{{ this.backend.invoice!.receiveAddress }}</h3>
|
||||
</span>
|
||||
<span id="amount">Amount
|
||||
<h3>{{ getAmount() }} BTC</h3>
|
||||
<h3>{{ this.backend.getAmount() }} BTC</h3>
|
||||
</span>
|
||||
<span id="status">Status
|
||||
<h3>{{ getStatus() }}</h3>
|
||||
<h3>{{ this.backend.getStatus() }}</h3>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { BackendService, IInvoice, CryptoUnits, PaymentStatus } from '../backend.service';
|
||||
import { BackendService, IInvoice, CryptoUnits, PaymentStatus, IPaymentMethod } from '../backend.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-payment',
|
||||
@@ -12,10 +12,9 @@ export class PaymentComponent implements OnInit {
|
||||
paymentSelector = '';
|
||||
choosenPaymentMethod = CryptoUnits.BITCOIN;
|
||||
ready = false;
|
||||
invoice: IInvoice | null = null;
|
||||
|
||||
constructor(
|
||||
private backend: BackendService,
|
||||
public backend: BackendService,
|
||||
private route: ActivatedRoute
|
||||
) { }
|
||||
|
||||
@@ -27,32 +26,13 @@ export class PaymentComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
async get() {
|
||||
this.invoice = await this.backend.getInvoice(this.paymentSelector);
|
||||
chooseMethod(coin: CryptoUnits) {
|
||||
this.backend.setPaymentMethod(coin);
|
||||
}
|
||||
|
||||
async get(): Promise<void> {
|
||||
await this.backend.setInvoice(this.paymentSelector);
|
||||
this.ready = true;
|
||||
}
|
||||
|
||||
getAmount() {
|
||||
return this.invoice?.paymentMethods.find(item => {
|
||||
return item.method === CryptoUnits.BITCOIN;
|
||||
})?.amount.toFixed(8);
|
||||
}
|
||||
|
||||
getStatus() {
|
||||
switch (this.invoice?.status) {
|
||||
case PaymentStatus.PENDING:
|
||||
return 'Pending';
|
||||
case PaymentStatus.PARTIALLY:
|
||||
return 'Partly';
|
||||
case PaymentStatus.UNCONFIRMED:
|
||||
return 'Unconfirmed';
|
||||
case PaymentStatus.DONE:
|
||||
return 'Paid';
|
||||
case PaymentStatus.CANCELLED:
|
||||
return 'Cancelled';
|
||||
default:
|
||||
return 'Unknown';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
63
src/assets/BitcoinCash.svg
Normal file
63
src/assets/BitcoinCash.svg
Normal file
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
height="64"
|
||||
width="64"
|
||||
version="1.1"
|
||||
id="svg905"
|
||||
sodipodi:docname="BitcoinCash.svg"
|
||||
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
|
||||
<metadata
|
||||
id="metadata911">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs909" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1024"
|
||||
id="namedview907"
|
||||
showgrid="false"
|
||||
inkscape:zoom="8.859375"
|
||||
inkscape:cx="32"
|
||||
inkscape:cy="32"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g903" />
|
||||
<g
|
||||
transform="translate(0.00630876,-0.00301984)"
|
||||
id="g903">
|
||||
<path
|
||||
fill="#f7931a"
|
||||
d="m63.033,39.744c-4.274,17.143-21.637,27.576-38.782,23.301-17.138-4.274-27.571-21.638-23.295-38.78,4.272-17.145,21.635-27.579,38.775-23.305,17.144,4.274,27.576,21.64,23.302,38.784z"
|
||||
id="path899"
|
||||
style="fill:#679a1b;fill-opacity:1" />
|
||||
<path
|
||||
fill="#FFF"
|
||||
d="m46.103,27.444c0.637-4.258-2.605-6.547-7.038-8.074l1.438-5.768-3.511-0.875-1.4,5.616c-0.923-0.23-1.871-0.447-2.813-0.662l1.41-5.653-3.509-0.875-1.439,5.766c-0.764-0.174-1.514-0.346-2.242-0.527l0.004-0.018-4.842-1.209-0.934,3.75s2.605,0.597,2.55,0.634c1.422,0.355,1.679,1.296,1.636,2.042l-1.638,6.571c0.098,0.025,0.225,0.061,0.365,0.117-0.117-0.029-0.242-0.061-0.371-0.092l-2.296,9.205c-0.174,0.432-0.615,1.08-1.609,0.834,0.035,0.051-2.552-0.637-2.552-0.637l-1.743,4.019,4.569,1.139c0.85,0.213,1.683,0.436,2.503,0.646l-1.453,5.834,3.507,0.875,1.439-5.772c0.958,0.26,1.888,0.5,2.798,0.726l-1.434,5.745,3.511,0.875,1.453-5.823c5.987,1.133,10.489,0.676,12.384-4.739,1.527-4.36-0.076-6.875-3.226-8.515,2.294-0.529,4.022-2.038,4.483-5.155zm-8.022,11.249c-1.085,4.36-8.426,2.003-10.806,1.412l1.928-7.729c2.38,0.594,10.012,1.77,8.878,6.317zm1.086-11.312c-0.99,3.966-7.1,1.951-9.082,1.457l1.748-7.01c1.982,0.494,8.365,1.416,7.334,5.553z"
|
||||
id="path901" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
BIN
src/assets/Dogecoin.png
Normal file
BIN
src/assets/Dogecoin.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 53 KiB |
11
src/assets/Ethereum.svg
Normal file
11
src/assets/Ethereum.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="256px" height="417px" viewBox="0 0 256 417" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
|
||||
<g>
|
||||
<polygon fill="#343434" points="127.9611 0 125.1661 9.5 125.1661 285.168 127.9611 287.958 255.9231 212.32"/>
|
||||
<polygon fill="#8C8C8C" points="127.962 0 0 212.32 127.962 287.959 127.962 154.158"/>
|
||||
<polygon fill="#3C3C3B" points="127.9611 312.1866 126.3861 314.1066 126.3861 412.3056 127.9611 416.9066 255.9991 236.5866"/>
|
||||
<polygon fill="#8C8C8C" points="127.962 416.9052 127.962 312.1852 0 236.5852"/>
|
||||
<polygon fill="#141414" points="127.9611 287.9577 255.9211 212.3207 127.9611 154.1587"/>
|
||||
<polygon fill="#393939" points="0.0009 212.3208 127.9609 287.9578 127.9609 154.1588"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 840 B |
1
src/assets/Litecoin.svg
Normal file
1
src/assets/Litecoin.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="2500" height="2500" viewBox="0.847 0.876 329.254 329.256"><title>Litecoin</title><path d="M330.102 165.503c0 90.922-73.705 164.629-164.626 164.629C74.554 330.132.848 256.425.848 165.503.848 74.582 74.554.876 165.476.876c90.92 0 164.626 73.706 164.626 164.627" fill="#bebebe"/><path d="M295.15 165.505c0 71.613-58.057 129.675-129.674 129.675-71.616 0-129.677-58.062-129.677-129.675 0-71.619 58.061-129.677 129.677-129.677 71.618 0 129.674 58.057 129.674 129.677" fill="#bebebe"/><path d="M155.854 209.482l10.693-40.264 25.316-9.249 6.297-23.663-.215-.587-24.92 9.104 17.955-67.608h-50.921l-23.481 88.23-19.605 7.162-6.478 24.395 19.59-7.156-13.839 51.998h135.521l8.688-32.362h-84.601" fill="#fff"/></svg>
|
||||
|
After Width: | Height: | Size: 750 B |
18
src/assets/Monero.svg
Normal file
18
src/assets/Monero.svg
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="monero" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 200 200" style="enable-background:new 0 0 200 200;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:none;}
|
||||
.st1{fill:#F16822;}
|
||||
.st2{fill:#4D4D4D;}
|
||||
</style>
|
||||
<g>
|
||||
<path class="st0" d="M197.5,100c0,53.8-43.7,97.5-97.5,97.5c-53.8,0-97.5-43.7-97.5-97.5C2.5,46.1,46.1,2.5,100,2.5
|
||||
C153.8,2.5,197.5,46.1,197.5,100z"/>
|
||||
<path id="_149931032_1_" class="st1" d="M100,2.5C46.2,2.5,2.4,46.2,2.5,100c0,10.8,1.7,21.1,4.9,30.8h29.2v-82l63.4,63.4
|
||||
l63.4-63.4v82h29.2c3.2-9.7,4.9-20,5-30.8C197.6,46.2,153.8,2.5,100,2.5L100,2.5z"/>
|
||||
<path id="_149931160_1_" class="st2" d="M85.4,126.7L57.8,99v51.6H47.2H36.6l-20,0c17.1,28.1,48,46.9,83.3,46.9
|
||||
c35.3,0,66.2-18.8,83.3-46.9l-20,0h-18.9h-2.2V99l-27.7,27.7L100,141.3L85.4,126.7L85.4,126.7z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1020 B |
@@ -1,8 +1,13 @@
|
||||
/* You can add global styles to this file, and also import other style files */
|
||||
*{
|
||||
* {
|
||||
font-family: 'Inter', sans-serif;
|
||||
}
|
||||
|
||||
body, html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:host{
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
Reference in New Issue
Block a user