@oasisomniverse/angular 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +37 -0
- package/src/components/avatar/avatar-wallet.component.ts +49 -0
- package/src/components/avatar/edit-avatar.component.ts +28 -0
- package/src/components/avatar/search-avatar.component.ts +45 -0
- package/src/components/avatar/view-avatar.component.ts +49 -0
- package/src/components/avatar-connect/avatar-connect.component.ts +78 -0
- package/src/components/avatar-profile/avatar-profile.component.ts +146 -0
- package/src/components/coming-soon/coming-soon.component.ts +27 -0
- package/src/components/confirmation/confirmation.component.ts +38 -0
- package/src/components/contact/contact.component.ts +64 -0
- package/src/components/data-screen/add-data.component.ts +50 -0
- package/src/components/data-screen/cross-chain-management.component.ts +28 -0
- package/src/components/data-screen/load-data.component.ts +28 -0
- package/src/components/data-screen/manage-data.component.ts +50 -0
- package/src/components/data-screen/off-chain-management.component.ts +28 -0
- package/src/components/data-screen/search-data.component.ts +40 -0
- package/src/components/eggs/eggs.component.ts +76 -0
- package/src/components/eggs/manage-eggs.component.ts +50 -0
- package/src/components/eggs/search-eggs.component.ts +40 -0
- package/src/components/eggs/view-eggs.component.ts +49 -0
- package/src/components/forgot-password/forgot-password.component.ts +80 -0
- package/src/components/game/game.component.ts +58 -0
- package/src/components/game/search-profiles.component.ts +36 -0
- package/src/components/game/view-achievements.component.ts +48 -0
- package/src/components/game/view-leagues.component.ts +48 -0
- package/src/components/game/view-tournaments.component.ts +49 -0
- package/src/components/hyperdrive/hyperdrive.component.ts +81 -0
- package/src/components/karma/search-karma.component.ts +36 -0
- package/src/components/karma/view-avatar-karma.component.ts +51 -0
- package/src/components/karma/view-karma.component.ts +46 -0
- package/src/components/karma/vote-karma.component.ts +48 -0
- package/src/components/karma-panel/karma-panel.component.ts +87 -0
- package/src/components/karma-toast/karma-toast.component.ts +33 -0
- package/src/components/login/login.component.ts +95 -0
- package/src/components/map/add-2d-object-map.component.ts +42 -0
- package/src/components/map/add-3d-object-map.component.ts +43 -0
- package/src/components/map/add-quest-to-map.component.ts +42 -0
- package/src/components/map/download-our-world.component.ts +28 -0
- package/src/components/map/manage-map.component.ts +28 -0
- package/src/components/map/map.component.ts +70 -0
- package/src/components/map/plot-route-on-map.component.ts +42 -0
- package/src/components/map/search-map.component.ts +44 -0
- package/src/components/map/view-global-3d-map.component.ts +28 -0
- package/src/components/map/view-halons-on-map.component.ts +28 -0
- package/src/components/map/view-oapp-on-map.component.ts +28 -0
- package/src/components/map/view-quest-on-map.component.ts +28 -0
- package/src/components/menu-message/menu-message.component.ts +69 -0
- package/src/components/messages/message.component.ts +59 -0
- package/src/components/messaging/messaging.component.ts +89 -0
- package/src/components/mission/manage-mission.component.ts +43 -0
- package/src/components/mission/mission.component.ts +63 -0
- package/src/components/mission/search-mission.component.ts +36 -0
- package/src/components/mission/view-mission.component.ts +49 -0
- package/src/components/modal/modal.component.ts +28 -0
- package/src/components/navbar/navbar.component.ts +64 -0
- package/src/components/nft/contact-popup.component.ts +41 -0
- package/src/components/nft/manage-oasis-nft.component.ts +43 -0
- package/src/components/nft/nft.component.ts +70 -0
- package/src/components/nft/purchase-oasis-nft.component.ts +53 -0
- package/src/components/nft/purchase-oasis-virtual-land-nft.component.ts +28 -0
- package/src/components/nft/search-oasis-nft.component.ts +36 -0
- package/src/components/nft/solana.component.ts +28 -0
- package/src/components/nft/view-oasis-nft.component.ts +52 -0
- package/src/components/oapp/create-oapp.component.ts +43 -0
- package/src/components/oapp/deploy-oapp.component.ts +42 -0
- package/src/components/oapp/download-our-world.component.ts +28 -0
- package/src/components/oapp/edit-oapp.component.ts +41 -0
- package/src/components/oapp/install-oapp.component.ts +36 -0
- package/src/components/oapp/launch-oapp.component.ts +58 -0
- package/src/components/oapp/manage-oapp.component.ts +42 -0
- package/src/components/oapp/oapp.component.ts +70 -0
- package/src/components/oapp/search-oapp.component.ts +36 -0
- package/src/components/oasis-card/oasis-card.component.ts +30 -0
- package/src/components/onet/onet.component.ts +77 -0
- package/src/components/onode/onode.component.ts +73 -0
- package/src/components/provider/activity-pub.component.ts +44 -0
- package/src/components/provider/compare-provider-speeds.component.ts +48 -0
- package/src/components/provider/eosio.component.ts +44 -0
- package/src/components/provider/ethereum.component.ts +44 -0
- package/src/components/provider/holochain.component.ts +44 -0
- package/src/components/provider/ipfs.component.ts +44 -0
- package/src/components/provider/manage-auto-fail-over.component.ts +42 -0
- package/src/components/provider/manage-auto-replicaton.component.ts +42 -0
- package/src/components/provider/manage-load-balancing.component.ts +42 -0
- package/src/components/provider/manage-providers.component.ts +28 -0
- package/src/components/provider/mongo-db.component.ts +44 -0
- package/src/components/provider/neo4j.component.ts +44 -0
- package/src/components/provider/search-providers.component.ts +36 -0
- package/src/components/provider/seeds-provider.component.ts +42 -0
- package/src/components/provider/solid.component.ts +44 -0
- package/src/components/provider/sql-lite.component.ts +44 -0
- package/src/components/provider/three-fold.component.ts +44 -0
- package/src/components/provider/view-provider-stats.component.ts +61 -0
- package/src/components/provider/view-providers.component.ts +54 -0
- package/src/components/provider-dropdown/provider-dropdown.component.ts +64 -0
- package/src/components/providers/providers.component.ts +60 -0
- package/src/components/quest/manage-quest.component.ts +43 -0
- package/src/components/quest/quest.component.ts +65 -0
- package/src/components/quest/search-quest.component.ts +36 -0
- package/src/components/quest/view-quest.component.ts +49 -0
- package/src/components/reset-password/reset-password.component.ts +68 -0
- package/src/components/search-avatars/search-avatars.component.ts +80 -0
- package/src/components/seeds/accept-invite.component.ts +44 -0
- package/src/components/seeds/donate-seeds.component.ts +42 -0
- package/src/components/seeds/manage-seeds.component.ts +42 -0
- package/src/components/seeds/pay-with-seeds.component.ts +41 -0
- package/src/components/seeds/reward-seeds.component.ts +41 -0
- package/src/components/seeds/search-seeds.component.ts +36 -0
- package/src/components/seeds/seeds.component.ts +75 -0
- package/src/components/seeds/send-invite.component.ts +41 -0
- package/src/components/seeds/view-organizations.component.ts +55 -0
- package/src/components/seeds/view-seeds.component.ts +78 -0
- package/src/components/settings/settings.component.ts +96 -0
- package/src/components/signup/signup.component.ts +118 -0
- package/src/components/star-field/star-field.component.ts +44 -0
- package/src/components/verify-email/verify-email.component.ts +48 -0
- package/src/components/wallet/wallet.component.ts +83 -0
- package/src/index.ts +145 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Component, Input, Output, EventEmitter, signal } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
|
|
4
|
+
@Component({
|
|
5
|
+
selector: 'oasis-view-oasis-nft',
|
|
6
|
+
standalone: true,
|
|
7
|
+
imports: [CommonModule],
|
|
8
|
+
template: `
|
|
9
|
+
<div class="von-shell">
|
|
10
|
+
<div class="von-header"><span>🎨</span><h2 class="von-title">View OASIS NFTs</h2></div>
|
|
11
|
+
<div class="von-grid">
|
|
12
|
+
@for (nft of nfts(); track nft.id) {
|
|
13
|
+
<div class="von-card">
|
|
14
|
+
<div class="von-preview">{{ nft.emoji }}</div>
|
|
15
|
+
<div class="von-body">
|
|
16
|
+
<div class="von-name">{{ nft.name }}</div>
|
|
17
|
+
<div class="von-collection">{{ nft.collection }}</div>
|
|
18
|
+
<div class="von-price">{{ nft.price }}</div>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
}
|
|
22
|
+
</div>
|
|
23
|
+
<div class="von-footer"><button class="von-btn" (click)="close.emit()">Close</button></div>
|
|
24
|
+
</div>
|
|
25
|
+
`,
|
|
26
|
+
styles: [`
|
|
27
|
+
.von-shell{display:flex;flex-direction:column;gap:16px;padding:20px}
|
|
28
|
+
.von-header{display:flex;align-items:center;gap:10px}
|
|
29
|
+
.von-title{font-family:'Orbitron',sans-serif;font-size:18px;color:#fff;margin:0}
|
|
30
|
+
.von-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px}
|
|
31
|
+
.von-card{background:rgba(255,255,255,.04);border:1px solid rgba(0,200,255,.12);border-radius:10px;overflow:hidden}
|
|
32
|
+
.von-preview{font-size:48px;display:flex;align-items:center;justify-content:center;height:80px;background:rgba(0,200,255,.05)}
|
|
33
|
+
.von-body{padding:10px 12px}
|
|
34
|
+
.von-name{font-family:'Orbitron',sans-serif;font-size:11px;color:#fff}
|
|
35
|
+
.von-collection{font-size:10px;color:#7a9bbf;margin-top:2px}
|
|
36
|
+
.von-price{font-size:11px;color:#ffb43c;font-weight:700;margin-top:4px}
|
|
37
|
+
.von-footer{display:flex;justify-content:flex-end}
|
|
38
|
+
.von-btn{background:transparent;border:1px solid rgba(0,200,255,.3);border-radius:8px;color:#00c8ff;font-family:'Orbitron',sans-serif;font-size:11px;font-weight:700;padding:9px 22px;cursor:pointer}
|
|
39
|
+
`]
|
|
40
|
+
})
|
|
41
|
+
export class ViewOasisNftComponent {
|
|
42
|
+
@Input() show = false;
|
|
43
|
+
@Output() close = new EventEmitter<void>();
|
|
44
|
+
nfts = signal([
|
|
45
|
+
{ id:1, emoji:'🏛️', name:'OASIS Hub Alpha', collection:'Genesis', price:'0.05 ETH' },
|
|
46
|
+
{ id:2, emoji:'🌌', name:'Cosmic Artifact', collection:'Cosmic', price:'0.12 ETH' },
|
|
47
|
+
{ id:3, emoji:'🐉', name:'Dragon Companion', collection:'Beasts', price:'0.25 ETH' },
|
|
48
|
+
{ id:4, emoji:'💎', name:'Crystal Gem', collection:'Gems', price:'0.08 ETH' },
|
|
49
|
+
{ id:5, emoji:'🚀', name:'Starship', collection:'Vehicles', price:'0.15 ETH' },
|
|
50
|
+
{ id:6, emoji:'🌺', name:'Rare Bloom', collection:'Flora', price:'0.03 ETH' },
|
|
51
|
+
]);
|
|
52
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
|
|
4
|
+
@Component({
|
|
5
|
+
selector: 'oasis-create-oapp',
|
|
6
|
+
standalone: true,
|
|
7
|
+
imports: [CommonModule],
|
|
8
|
+
template: `
|
|
9
|
+
<div class="mf-shell">
|
|
10
|
+
<div class="mf-header"><span>➕</span><h2 class="mf-title">Create OAPP</h2></div>
|
|
11
|
+
<div class="mf-body">
|
|
12
|
+
<div class="mf-field"><label class="mf-lbl">OAPP Name</label><input class="mf-inp" placeholder="OAPP Name..." /></div>
|
|
13
|
+
<div class="mf-field"><label class="mf-lbl">Description</label><input class="mf-inp" placeholder="Description..." /></div>
|
|
14
|
+
<div class="mf-field"><label class="mf-lbl">Version</label><input class="mf-inp" placeholder="Version..." /></div>
|
|
15
|
+
<div class="mf-field"><label class="mf-lbl">License</label><input class="mf-inp" placeholder="License..." /></div>
|
|
16
|
+
<div class="mf-field"><label class="mf-lbl">Category</label><input class="mf-inp" placeholder="Category..." /></div>
|
|
17
|
+
<div class="mf-field"><label class="mf-lbl">Tags</label><input class="mf-inp" placeholder="Tags..." /></div>
|
|
18
|
+
</div>
|
|
19
|
+
<div class="mf-footer">
|
|
20
|
+
<button class="mf-save" (click)="save()">Save</button>
|
|
21
|
+
<button class="mf-cancel" (click)="close.emit()">Cancel</button>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
`,
|
|
25
|
+
styles: [`
|
|
26
|
+
.mf-shell{display:flex;flex-direction:column;gap:18px;padding:20px}
|
|
27
|
+
.mf-header{display:flex;align-items:center;gap:10px}
|
|
28
|
+
.mf-title{font-family:'Orbitron',sans-serif;font-size:18px;color:#fff;margin:0}
|
|
29
|
+
.mf-body{display:flex;flex-direction:column;gap:12px}
|
|
30
|
+
.mf-field{display:flex;flex-direction:column;gap:5px}
|
|
31
|
+
.mf-lbl{font-size:11px;font-weight:700;letter-spacing:.07em;color:#7a9bbf;text-transform:uppercase}
|
|
32
|
+
.mf-inp{background:rgba(255,255,255,.05);border:1px solid rgba(0,200,255,.25);border-radius:8px;color:#fff;font-size:13px;padding:10px 14px;outline:none}
|
|
33
|
+
.mf-inp:focus{border-color:rgba(0,200,255,.6)}
|
|
34
|
+
.mf-footer{display:flex;gap:10px;justify-content:flex-end}
|
|
35
|
+
.mf-save{background:linear-gradient(135deg,#00c8ff,#0080ff);border:none;border-radius:8px;color:#fff;font-family:'Orbitron',sans-serif;font-size:12px;font-weight:700;padding:10px 22px;cursor:pointer}
|
|
36
|
+
.mf-cancel{background:transparent;border:1px solid rgba(0,200,255,.3);border-radius:8px;color:#00c8ff;font-family:'Orbitron',sans-serif;font-size:11px;font-weight:700;padding:10px 18px;cursor:pointer}
|
|
37
|
+
`]
|
|
38
|
+
})
|
|
39
|
+
export class CreateOAPPComponent {
|
|
40
|
+
@Input() show = false;
|
|
41
|
+
@Output() close = new EventEmitter<void>();
|
|
42
|
+
save() { this.close.emit(); }
|
|
43
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
|
|
4
|
+
@Component({
|
|
5
|
+
selector: 'oasis-deploy-oapp',
|
|
6
|
+
standalone: true,
|
|
7
|
+
imports: [CommonModule],
|
|
8
|
+
template: `
|
|
9
|
+
<div class="mf-shell">
|
|
10
|
+
<div class="mf-header"><span>🚀</span><h2 class="mf-title">Deploy OAPP</h2></div>
|
|
11
|
+
<div class="mf-body">
|
|
12
|
+
<div class="mf-field"><label class="mf-lbl">OAPP</label><input class="mf-inp" placeholder="OAPP..." /></div>
|
|
13
|
+
<div class="mf-field"><label class="mf-lbl">Target Environment</label><input class="mf-inp" placeholder="Target Environment..." /></div>
|
|
14
|
+
<div class="mf-field"><label class="mf-lbl">Provider</label><input class="mf-inp" placeholder="Provider..." /></div>
|
|
15
|
+
<div class="mf-field"><label class="mf-lbl">Deploy Key</label><input class="mf-inp" placeholder="Deploy Key..." /></div>
|
|
16
|
+
<div class="mf-field"><label class="mf-lbl">Notes</label><input class="mf-inp" placeholder="Notes..." /></div>
|
|
17
|
+
</div>
|
|
18
|
+
<div class="mf-footer">
|
|
19
|
+
<button class="mf-save" (click)="save()">Save</button>
|
|
20
|
+
<button class="mf-cancel" (click)="close.emit()">Cancel</button>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
`,
|
|
24
|
+
styles: [`
|
|
25
|
+
.mf-shell{display:flex;flex-direction:column;gap:18px;padding:20px}
|
|
26
|
+
.mf-header{display:flex;align-items:center;gap:10px}
|
|
27
|
+
.mf-title{font-family:'Orbitron',sans-serif;font-size:18px;color:#fff;margin:0}
|
|
28
|
+
.mf-body{display:flex;flex-direction:column;gap:12px}
|
|
29
|
+
.mf-field{display:flex;flex-direction:column;gap:5px}
|
|
30
|
+
.mf-lbl{font-size:11px;font-weight:700;letter-spacing:.07em;color:#7a9bbf;text-transform:uppercase}
|
|
31
|
+
.mf-inp{background:rgba(255,255,255,.05);border:1px solid rgba(0,200,255,.25);border-radius:8px;color:#fff;font-size:13px;padding:10px 14px;outline:none}
|
|
32
|
+
.mf-inp:focus{border-color:rgba(0,200,255,.6)}
|
|
33
|
+
.mf-footer{display:flex;gap:10px;justify-content:flex-end}
|
|
34
|
+
.mf-save{background:linear-gradient(135deg,#00c8ff,#0080ff);border:none;border-radius:8px;color:#fff;font-family:'Orbitron',sans-serif;font-size:12px;font-weight:700;padding:10px 22px;cursor:pointer}
|
|
35
|
+
.mf-cancel{background:transparent;border:1px solid rgba(0,200,255,.3);border-radius:8px;color:#00c8ff;font-family:'Orbitron',sans-serif;font-size:11px;font-weight:700;padding:10px 18px;cursor:pointer}
|
|
36
|
+
`]
|
|
37
|
+
})
|
|
38
|
+
export class DeployOAPPComponent {
|
|
39
|
+
@Input() show = false;
|
|
40
|
+
@Output() close = new EventEmitter<void>();
|
|
41
|
+
save() { this.close.emit(); }
|
|
42
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
|
|
4
|
+
@Component({
|
|
5
|
+
selector: 'oasis-oapp-download-our-world',
|
|
6
|
+
standalone: true,
|
|
7
|
+
imports: [CommonModule],
|
|
8
|
+
template: `
|
|
9
|
+
<div class="popup-shell">
|
|
10
|
+
<div class="popup-icon">⬇️</div>
|
|
11
|
+
<h2 class="popup-title">Download Our World</h2>
|
|
12
|
+
<p class="popup-body">UI Coming Soon — access this feature via the OASIS API from the Developer menu.</p>
|
|
13
|
+
<button class="popup-btn" (click)="close.emit()">OK</button>
|
|
14
|
+
</div>
|
|
15
|
+
`,
|
|
16
|
+
styles: [`
|
|
17
|
+
.popup-shell{display:flex;flex-direction:column;align-items:center;gap:16px;padding:24px;text-align:center}
|
|
18
|
+
.popup-icon{font-size:48px}
|
|
19
|
+
.popup-title{font-family:'Orbitron',sans-serif;font-size:18px;color:#fff;margin:0}
|
|
20
|
+
.popup-body{font-size:13px;color:#a8bfd8;line-height:1.6;margin:0;max-width:380px}
|
|
21
|
+
.popup-btn{background:linear-gradient(135deg,#00c8ff,#0080ff);border:none;border-radius:8px;color:#fff;font-family:'Orbitron',sans-serif;font-size:12px;font-weight:700;letter-spacing:.08em;padding:10px 28px;cursor:pointer;transition:opacity .2s}
|
|
22
|
+
.popup-btn:hover{opacity:.85}
|
|
23
|
+
`]
|
|
24
|
+
})
|
|
25
|
+
export class OAPPDownloadOurWorldComponent {
|
|
26
|
+
@Input() show = false;
|
|
27
|
+
@Output() close = new EventEmitter<void>();
|
|
28
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
|
|
4
|
+
@Component({
|
|
5
|
+
selector: 'oasis-edit-oapp',
|
|
6
|
+
standalone: true,
|
|
7
|
+
imports: [CommonModule],
|
|
8
|
+
template: `
|
|
9
|
+
<div class="mf-shell">
|
|
10
|
+
<div class="mf-header"><span>✏️</span><h2 class="mf-title">Edit OAPP</h2></div>
|
|
11
|
+
<div class="mf-body">
|
|
12
|
+
<div class="mf-field"><label class="mf-lbl">OAPP Name</label><input class="mf-inp" placeholder="OAPP Name..." /></div>
|
|
13
|
+
<div class="mf-field"><label class="mf-lbl">Description</label><input class="mf-inp" placeholder="Description..." /></div>
|
|
14
|
+
<div class="mf-field"><label class="mf-lbl">Version</label><input class="mf-inp" placeholder="Version..." /></div>
|
|
15
|
+
<div class="mf-field"><label class="mf-lbl">Category</label><input class="mf-inp" placeholder="Category..." /></div>
|
|
16
|
+
</div>
|
|
17
|
+
<div class="mf-footer">
|
|
18
|
+
<button class="mf-save" (click)="save()">Save</button>
|
|
19
|
+
<button class="mf-cancel" (click)="close.emit()">Cancel</button>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
`,
|
|
23
|
+
styles: [`
|
|
24
|
+
.mf-shell{display:flex;flex-direction:column;gap:18px;padding:20px}
|
|
25
|
+
.mf-header{display:flex;align-items:center;gap:10px}
|
|
26
|
+
.mf-title{font-family:'Orbitron',sans-serif;font-size:18px;color:#fff;margin:0}
|
|
27
|
+
.mf-body{display:flex;flex-direction:column;gap:12px}
|
|
28
|
+
.mf-field{display:flex;flex-direction:column;gap:5px}
|
|
29
|
+
.mf-lbl{font-size:11px;font-weight:700;letter-spacing:.07em;color:#7a9bbf;text-transform:uppercase}
|
|
30
|
+
.mf-inp{background:rgba(255,255,255,.05);border:1px solid rgba(0,200,255,.25);border-radius:8px;color:#fff;font-size:13px;padding:10px 14px;outline:none}
|
|
31
|
+
.mf-inp:focus{border-color:rgba(0,200,255,.6)}
|
|
32
|
+
.mf-footer{display:flex;gap:10px;justify-content:flex-end}
|
|
33
|
+
.mf-save{background:linear-gradient(135deg,#00c8ff,#0080ff);border:none;border-radius:8px;color:#fff;font-family:'Orbitron',sans-serif;font-size:12px;font-weight:700;padding:10px 22px;cursor:pointer}
|
|
34
|
+
.mf-cancel{background:transparent;border:1px solid rgba(0,200,255,.3);border-radius:8px;color:#00c8ff;font-family:'Orbitron',sans-serif;font-size:11px;font-weight:700;padding:10px 18px;cursor:pointer}
|
|
35
|
+
`]
|
|
36
|
+
})
|
|
37
|
+
export class EditOAPPComponent {
|
|
38
|
+
@Input() show = false;
|
|
39
|
+
@Output() close = new EventEmitter<void>();
|
|
40
|
+
save() { this.close.emit(); }
|
|
41
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Component, Input, Output, EventEmitter, signal } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { FormsModule } from '@angular/forms';
|
|
4
|
+
|
|
5
|
+
@Component({
|
|
6
|
+
selector: 'oasis-install-oapp',
|
|
7
|
+
standalone: true,
|
|
8
|
+
imports: [CommonModule, FormsModule],
|
|
9
|
+
template: `
|
|
10
|
+
<div class="sf-shell">
|
|
11
|
+
<div class="sf-header"><span>📦</span><h2 class="sf-title">Install OAPP</h2></div>
|
|
12
|
+
<div class="sf-row"><input class="sf-input" [(ngModel)]="query" placeholder="Search OAPPs to install..." (keyup.enter)="search()" /><button class="sf-btn" (click)="search()">Search</button></div>
|
|
13
|
+
@for (r of results(); track r) { <div class="sf-result">{{ r }}</div> }
|
|
14
|
+
<div class="sf-footer"><button class="sf-cancel" (click)="close.emit()">Close</button></div>
|
|
15
|
+
</div>
|
|
16
|
+
`,
|
|
17
|
+
styles: [`
|
|
18
|
+
.sf-shell{display:flex;flex-direction:column;gap:14px;padding:20px}
|
|
19
|
+
.sf-header{display:flex;align-items:center;gap:10px}
|
|
20
|
+
.sf-title{font-family:'Orbitron',sans-serif;font-size:18px;color:#fff;margin:0}
|
|
21
|
+
.sf-row{display:flex;gap:10px}
|
|
22
|
+
.sf-input{flex:1;background:rgba(255,255,255,.05);border:1px solid rgba(0,200,255,.25);border-radius:8px;color:#fff;font-size:13px;padding:10px 14px;outline:none}
|
|
23
|
+
.sf-input:focus{border-color:rgba(0,200,255,.6)}
|
|
24
|
+
.sf-btn{background:linear-gradient(135deg,#00c8ff,#0080ff);border:none;border-radius:8px;color:#fff;font-family:'Orbitron',sans-serif;font-size:12px;font-weight:700;padding:10px 20px;cursor:pointer;white-space:nowrap}
|
|
25
|
+
.sf-result{background:rgba(255,255,255,.04);border:1px solid rgba(0,200,255,.12);border-radius:8px;color:#c8dff0;font-size:13px;padding:10px 14px}
|
|
26
|
+
.sf-footer{display:flex;justify-content:flex-end}
|
|
27
|
+
.sf-cancel{background:transparent;border:1px solid rgba(0,200,255,.3);border-radius:8px;color:#00c8ff;font-family:'Orbitron',sans-serif;font-size:11px;font-weight:700;padding:8px 20px;cursor:pointer}
|
|
28
|
+
`]
|
|
29
|
+
})
|
|
30
|
+
export class InstallOAPPComponent {
|
|
31
|
+
@Input() show = false;
|
|
32
|
+
@Output() close = new EventEmitter<void>();
|
|
33
|
+
query = '';
|
|
34
|
+
results = signal<string[]>([]);
|
|
35
|
+
search() { if (this.query.trim()) this.results.set(['No results found for "' + this.query + '"']); }
|
|
36
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Component, Input, Output, EventEmitter, signal } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
|
|
4
|
+
@Component({
|
|
5
|
+
selector: 'oasis-launch-oapp',
|
|
6
|
+
standalone: true,
|
|
7
|
+
imports: [CommonModule],
|
|
8
|
+
template: `
|
|
9
|
+
<div class="lo-shell">
|
|
10
|
+
<div class="lo-header"><span>🚀</span><h2 class="lo-title">Launch OAPP</h2></div>
|
|
11
|
+
<div class="lo-list">
|
|
12
|
+
@for (app of oapps(); track app.id) {
|
|
13
|
+
<div class="lo-card" (click)="selected.set(app.id)" [class.lo-card--sel]="selected()===app.id">
|
|
14
|
+
<div class="lo-icon">{{ app.icon }}</div>
|
|
15
|
+
<div class="lo-info"><div class="lo-name">{{ app.name }}</div><div class="lo-version">v{{ app.version }}</div></div>
|
|
16
|
+
<div class="lo-status lo-status--{{ app.status.toLowerCase() }}">{{ app.status }}</div>
|
|
17
|
+
</div>
|
|
18
|
+
}
|
|
19
|
+
</div>
|
|
20
|
+
<div class="lo-footer">
|
|
21
|
+
<button class="lo-launch" [disabled]="!selected()" (click)="launch()">Launch</button>
|
|
22
|
+
<button class="lo-cancel" (click)="close.emit()">Cancel</button>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
`,
|
|
26
|
+
styles: [`
|
|
27
|
+
.lo-shell{display:flex;flex-direction:column;gap:16px;padding:20px}
|
|
28
|
+
.lo-header{display:flex;align-items:center;gap:10px}
|
|
29
|
+
.lo-title{font-family:'Orbitron',sans-serif;font-size:18px;color:#fff;margin:0}
|
|
30
|
+
.lo-list{display:flex;flex-direction:column;gap:8px}
|
|
31
|
+
.lo-card{display:flex;align-items:center;gap:12px;background:rgba(255,255,255,.04);border:1px solid rgba(0,200,255,.12);border-radius:10px;padding:12px 16px;cursor:pointer;transition:border-color .2s}
|
|
32
|
+
.lo-card:hover{border-color:rgba(0,200,255,.3)}
|
|
33
|
+
.lo-card--sel{border-color:#00c8ff;background:rgba(0,200,255,.08)}
|
|
34
|
+
.lo-icon{font-size:28px}
|
|
35
|
+
.lo-info{flex:1}
|
|
36
|
+
.lo-name{font-family:'Orbitron',sans-serif;font-size:13px;color:#fff}
|
|
37
|
+
.lo-version{font-size:11px;color:#7a9bbf;margin-top:2px}
|
|
38
|
+
.lo-status{font-size:10px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;border-radius:999px;padding:2px 9px;border:1px solid currentColor}
|
|
39
|
+
.lo-status--installed{color:#00c864;border-color:rgba(0,200,100,.3)}
|
|
40
|
+
.lo-status--available{color:#5ba8ff;border-color:rgba(91,168,255,.3)}
|
|
41
|
+
.lo-footer{display:flex;gap:10px;justify-content:flex-end}
|
|
42
|
+
.lo-launch{background:linear-gradient(135deg,#00c8ff,#0080ff);border:none;border-radius:8px;color:#fff;font-family:'Orbitron',sans-serif;font-size:12px;font-weight:700;padding:10px 22px;cursor:pointer}
|
|
43
|
+
.lo-launch:disabled{opacity:.4;cursor:not-allowed}
|
|
44
|
+
.lo-cancel{background:transparent;border:1px solid rgba(0,200,255,.3);border-radius:8px;color:#00c8ff;font-family:'Orbitron',sans-serif;font-size:11px;font-weight:700;padding:10px 18px;cursor:pointer}
|
|
45
|
+
`]
|
|
46
|
+
})
|
|
47
|
+
export class LaunchOAPPComponent {
|
|
48
|
+
@Input() show = false;
|
|
49
|
+
@Output() close = new EventEmitter<void>();
|
|
50
|
+
selected = signal<number|null>(null);
|
|
51
|
+
oapps = signal([
|
|
52
|
+
{ id:1, icon:'🎮', name:'OASIS Game Hub', version:'1.4.2', status:'Installed' },
|
|
53
|
+
{ id:2, icon:'🗺️', name:'World Explorer', version:'2.1.0', status:'Installed' },
|
|
54
|
+
{ id:3, icon:'💹', name:'SEEDS Market', version:'1.0.5', status:'Available' },
|
|
55
|
+
{ id:4, icon:'📡', name:'ONET Messenger', version:'3.0.1', status:'Installed' },
|
|
56
|
+
]);
|
|
57
|
+
launch() { this.close.emit(); }
|
|
58
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
|
|
4
|
+
@Component({
|
|
5
|
+
selector: 'oasis-manage-oapp',
|
|
6
|
+
standalone: true,
|
|
7
|
+
imports: [CommonModule],
|
|
8
|
+
template: `
|
|
9
|
+
<div class="mf-shell">
|
|
10
|
+
<div class="mf-header"><span>⚙️</span><h2 class="mf-title">Manage OAPP</h2></div>
|
|
11
|
+
<div class="mf-body">
|
|
12
|
+
<div class="mf-field"><label class="mf-lbl">OAPP Name</label><input class="mf-inp" placeholder="OAPP Name..." /></div>
|
|
13
|
+
<div class="mf-field"><label class="mf-lbl">Version</label><input class="mf-inp" placeholder="Version..." /></div>
|
|
14
|
+
<div class="mf-field"><label class="mf-lbl">Status</label><input class="mf-inp" placeholder="Status..." /></div>
|
|
15
|
+
<div class="mf-field"><label class="mf-lbl">Provider</label><input class="mf-inp" placeholder="Provider..." /></div>
|
|
16
|
+
<div class="mf-field"><label class="mf-lbl">Auto-Update</label><input class="mf-inp" placeholder="Auto-Update..." /></div>
|
|
17
|
+
</div>
|
|
18
|
+
<div class="mf-footer">
|
|
19
|
+
<button class="mf-save" (click)="save()">Save</button>
|
|
20
|
+
<button class="mf-cancel" (click)="close.emit()">Cancel</button>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
`,
|
|
24
|
+
styles: [`
|
|
25
|
+
.mf-shell{display:flex;flex-direction:column;gap:18px;padding:20px}
|
|
26
|
+
.mf-header{display:flex;align-items:center;gap:10px}
|
|
27
|
+
.mf-title{font-family:'Orbitron',sans-serif;font-size:18px;color:#fff;margin:0}
|
|
28
|
+
.mf-body{display:flex;flex-direction:column;gap:12px}
|
|
29
|
+
.mf-field{display:flex;flex-direction:column;gap:5px}
|
|
30
|
+
.mf-lbl{font-size:11px;font-weight:700;letter-spacing:.07em;color:#7a9bbf;text-transform:uppercase}
|
|
31
|
+
.mf-inp{background:rgba(255,255,255,.05);border:1px solid rgba(0,200,255,.25);border-radius:8px;color:#fff;font-size:13px;padding:10px 14px;outline:none}
|
|
32
|
+
.mf-inp:focus{border-color:rgba(0,200,255,.6)}
|
|
33
|
+
.mf-footer{display:flex;gap:10px;justify-content:flex-end}
|
|
34
|
+
.mf-save{background:linear-gradient(135deg,#00c8ff,#0080ff);border:none;border-radius:8px;color:#fff;font-family:'Orbitron',sans-serif;font-size:12px;font-weight:700;padding:10px 22px;cursor:pointer}
|
|
35
|
+
.mf-cancel{background:transparent;border:1px solid rgba(0,200,255,.3);border-radius:8px;color:#00c8ff;font-family:'Orbitron',sans-serif;font-size:11px;font-weight:700;padding:10px 18px;cursor:pointer}
|
|
36
|
+
`]
|
|
37
|
+
})
|
|
38
|
+
export class ManageOAPPComponent {
|
|
39
|
+
@Input() show = false;
|
|
40
|
+
@Output() close = new EventEmitter<void>();
|
|
41
|
+
save() { this.close.emit(); }
|
|
42
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Component, signal } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { FormsModule } from '@angular/forms';
|
|
4
|
+
|
|
5
|
+
interface OApp { id: string; name: string; description: string; category: string; icon: string; karma: number; launched: boolean }
|
|
6
|
+
|
|
7
|
+
@Component({
|
|
8
|
+
selector: 'oasis-oapp',
|
|
9
|
+
standalone: true,
|
|
10
|
+
imports: [CommonModule, FormsModule],
|
|
11
|
+
template: `
|
|
12
|
+
<div class="oapp-shell">
|
|
13
|
+
<div class="oapp-header"><h2 class="oapp-title">📱 OApps</h2><p class="oapp-sub">Decentralised apps built on the OASIS network.</p></div>
|
|
14
|
+
<div class="oapp-search-wrap"><input class="oasis-input" type="text" [(ngModel)]="search" placeholder="Search OApps…" /></div>
|
|
15
|
+
<div class="oapp-grid">
|
|
16
|
+
@for (a of filtered(); track a.id) {
|
|
17
|
+
<div class="oapp-card">
|
|
18
|
+
<div class="oapp-icon">{{ a.icon }}</div>
|
|
19
|
+
<div class="oapp-info">
|
|
20
|
+
<div class="oapp-name">{{ a.name }}</div>
|
|
21
|
+
<div class="oapp-cat">{{ a.category }}</div>
|
|
22
|
+
<div class="oapp-desc">{{ a.description }}</div>
|
|
23
|
+
</div>
|
|
24
|
+
<div class="oapp-footer">
|
|
25
|
+
<div class="oapp-karma">+{{ a.karma }} karma</div>
|
|
26
|
+
<button class="oapp-btn" [class.oapp-btn--launched]="a.launched" (click)="toggle(a)">{{ a.launched ? 'Quit' : 'Launch' }}</button>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
}
|
|
30
|
+
@if (filtered().length === 0) { <div class="oapp-empty">No OApps found.</div> }
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
`,
|
|
34
|
+
styles: [`
|
|
35
|
+
.oapp-shell{display:flex;flex-direction:column;gap:18px}
|
|
36
|
+
.oapp-header{text-align:center}
|
|
37
|
+
.oapp-title{font-family:'Orbitron',sans-serif;font-size:20px;color:#fff;margin:0 0 6px}
|
|
38
|
+
.oapp-sub{font-size:13px;color:#7a9bbf;margin:0}
|
|
39
|
+
.oapp-search-wrap{}
|
|
40
|
+
.oasis-input{width:100%;background:rgba(255,255,255,.05);border:1px solid rgba(0,200,255,.2);border-radius:8px;padding:10px 14px;color:#fff;font-size:14px;outline:none;box-sizing:border-box;transition:border-color .2s;font-family:inherit}
|
|
41
|
+
.oasis-input:focus{border-color:rgba(0,200,255,.5)}
|
|
42
|
+
.oapp-grid{display:flex;flex-direction:column;gap:12px}
|
|
43
|
+
.oapp-card{background:rgba(255,255,255,.04);border:1px solid rgba(0,200,255,.12);border-radius:12px;padding:16px;display:flex;gap:14px;align-items:flex-start;transition:border-color .2s}
|
|
44
|
+
.oapp-card:hover{border-color:rgba(0,200,255,.3)}
|
|
45
|
+
.oapp-icon{font-size:32px;flex-shrink:0}
|
|
46
|
+
.oapp-info{flex:1}
|
|
47
|
+
.oapp-name{font-family:'Orbitron',sans-serif;font-size:13px;color:#fff;margin-bottom:3px}
|
|
48
|
+
.oapp-cat{font-size:11px;color:#5ba8ff;text-transform:uppercase;letter-spacing:.06em;margin-bottom:5px}
|
|
49
|
+
.oapp-desc{font-size:12px;color:#7a9bbf;line-height:1.5}
|
|
50
|
+
.oapp-footer{display:flex;flex-direction:column;align-items:flex-end;gap:8px;flex-shrink:0}
|
|
51
|
+
.oapp-karma{font-size:11px;color:#48dc82;font-weight:600;white-space:nowrap}
|
|
52
|
+
.oapp-btn{background:linear-gradient(135deg,#00c8ff,#0080ff);border:none;border-radius:7px;color:#fff;font-family:'Orbitron',sans-serif;font-size:11px;font-weight:700;letter-spacing:.08em;padding:7px 16px;cursor:pointer;transition:opacity .2s;white-space:nowrap}
|
|
53
|
+
.oapp-btn--launched{background:rgba(255,80,80,.2);border:1px solid rgba(255,80,80,.4);color:#ff6b6b}
|
|
54
|
+
.oapp-empty{text-align:center;color:#4a6a88;font-size:14px;padding:32px}
|
|
55
|
+
`]
|
|
56
|
+
})
|
|
57
|
+
export class OAppComponent {
|
|
58
|
+
search = '';
|
|
59
|
+
oapps = signal<OApp[]>([
|
|
60
|
+
{ id: '1', name: 'OLAND', description: 'Virtual land management and terraforming in the OASIS.', category: 'Metaverse', icon: '🌍', karma: 200, launched: false },
|
|
61
|
+
{ id: '2', name: 'OMARKET', description: 'Decentralised marketplace for NFTs and digital goods.', category: 'Commerce', icon: '🛒', karma: 150, launched: false },
|
|
62
|
+
{ id: '3', name: 'OCHAT', description: 'Encrypted peer-to-peer messaging on the ONET.', category: 'Social', icon: '💬', karma: 80, launched: false },
|
|
63
|
+
{ id: '4', name: 'OQUESTS', description: 'Daily quests and challenges for karma rewards.', category: 'Gaming', icon: '⚔️', karma: 300, launched: false },
|
|
64
|
+
]);
|
|
65
|
+
filtered() {
|
|
66
|
+
const q = this.search.toLowerCase();
|
|
67
|
+
return this.oapps().filter(a => a.name.toLowerCase().includes(q) || a.description.toLowerCase().includes(q));
|
|
68
|
+
}
|
|
69
|
+
toggle(a: OApp) { this.oapps.update(list => list.map(x => x.id === a.id ? { ...x, launched: !x.launched } : x)); }
|
|
70
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Component, Input, Output, EventEmitter, signal } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { FormsModule } from '@angular/forms';
|
|
4
|
+
|
|
5
|
+
@Component({
|
|
6
|
+
selector: 'oasis-search-oapp',
|
|
7
|
+
standalone: true,
|
|
8
|
+
imports: [CommonModule, FormsModule],
|
|
9
|
+
template: `
|
|
10
|
+
<div class="sf-shell">
|
|
11
|
+
<div class="sf-header"><span>🔍</span><h2 class="sf-title">Search OAPPs</h2></div>
|
|
12
|
+
<div class="sf-row"><input class="sf-input" [(ngModel)]="query" placeholder="Search by name, category or developer..." (keyup.enter)="search()" /><button class="sf-btn" (click)="search()">Search</button></div>
|
|
13
|
+
@for (r of results(); track r) { <div class="sf-result">{{ r }}</div> }
|
|
14
|
+
<div class="sf-footer"><button class="sf-cancel" (click)="close.emit()">Close</button></div>
|
|
15
|
+
</div>
|
|
16
|
+
`,
|
|
17
|
+
styles: [`
|
|
18
|
+
.sf-shell{display:flex;flex-direction:column;gap:14px;padding:20px}
|
|
19
|
+
.sf-header{display:flex;align-items:center;gap:10px}
|
|
20
|
+
.sf-title{font-family:'Orbitron',sans-serif;font-size:18px;color:#fff;margin:0}
|
|
21
|
+
.sf-row{display:flex;gap:10px}
|
|
22
|
+
.sf-input{flex:1;background:rgba(255,255,255,.05);border:1px solid rgba(0,200,255,.25);border-radius:8px;color:#fff;font-size:13px;padding:10px 14px;outline:none}
|
|
23
|
+
.sf-input:focus{border-color:rgba(0,200,255,.6)}
|
|
24
|
+
.sf-btn{background:linear-gradient(135deg,#00c8ff,#0080ff);border:none;border-radius:8px;color:#fff;font-family:'Orbitron',sans-serif;font-size:12px;font-weight:700;padding:10px 20px;cursor:pointer;white-space:nowrap}
|
|
25
|
+
.sf-result{background:rgba(255,255,255,.04);border:1px solid rgba(0,200,255,.12);border-radius:8px;color:#c8dff0;font-size:13px;padding:10px 14px}
|
|
26
|
+
.sf-footer{display:flex;justify-content:flex-end}
|
|
27
|
+
.sf-cancel{background:transparent;border:1px solid rgba(0,200,255,.3);border-radius:8px;color:#00c8ff;font-family:'Orbitron',sans-serif;font-size:11px;font-weight:700;padding:8px 20px;cursor:pointer}
|
|
28
|
+
`]
|
|
29
|
+
})
|
|
30
|
+
export class SearchOAPPComponent {
|
|
31
|
+
@Input() show = false;
|
|
32
|
+
@Output() close = new EventEmitter<void>();
|
|
33
|
+
query = '';
|
|
34
|
+
results = signal<string[]>([]);
|
|
35
|
+
search() { if (this.query.trim()) this.results.set(['No results found for "' + this.query + '"']); }
|
|
36
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Component, Input } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
|
|
4
|
+
@Component({
|
|
5
|
+
selector: 'oasis-card',
|
|
6
|
+
standalone: true,
|
|
7
|
+
imports: [CommonModule],
|
|
8
|
+
template: `
|
|
9
|
+
<div class="card" [style.border-color]="borderColor">
|
|
10
|
+
<div class="card-icon" *ngIf="icon">{{ icon }}</div>
|
|
11
|
+
<div class="card-kicker" *ngIf="kicker" [style.color]="accentColor">{{ kicker }}</div>
|
|
12
|
+
<h3 class="card-title" *ngIf="title">{{ title }}</h3>
|
|
13
|
+
<ng-content />
|
|
14
|
+
</div>
|
|
15
|
+
`,
|
|
16
|
+
styles: [`
|
|
17
|
+
.card { background: var(--bg-card, #0e1f44); border: 1px solid rgba(232,121,249,.15); border-radius: 16px; padding: 32px 26px; height: 100%; box-sizing: border-box; transition: transform .3s, border-color .3s; }
|
|
18
|
+
.card:hover { transform: translateY(-4px); }
|
|
19
|
+
.card-icon { font-size: 36px; margin-bottom: 16px; }
|
|
20
|
+
.card-kicker { font-family: 'Orbitron', sans-serif; font-size: 10px; font-weight: 700; letter-spacing: .12em; margin-bottom: 10px; }
|
|
21
|
+
.card-title { font-family: 'Orbitron', sans-serif; font-size: 15px; font-weight: 700; color: #fff; letter-spacing: .06em; margin: 0 0 12px; }
|
|
22
|
+
`]
|
|
23
|
+
})
|
|
24
|
+
export class OasisCardComponent {
|
|
25
|
+
@Input() icon = '';
|
|
26
|
+
@Input() kicker = '';
|
|
27
|
+
@Input() title = '';
|
|
28
|
+
@Input() borderColor = 'rgba(232,121,249,.15)';
|
|
29
|
+
@Input() accentColor = '#e879f9';
|
|
30
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { Component, signal } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
|
|
4
|
+
@Component({
|
|
5
|
+
selector: 'oasis-onet',
|
|
6
|
+
standalone: true,
|
|
7
|
+
imports: [CommonModule],
|
|
8
|
+
template: `
|
|
9
|
+
<div class="onet-shell">
|
|
10
|
+
<div class="onet-header"><h2 class="onet-title">🌐 ONET</h2><p class="onet-sub">The OASIS decentralised internet layer.</p></div>
|
|
11
|
+
<div class="onet-status-card" [class.onet-status--active]="connected()">
|
|
12
|
+
<div class="onet-status-dot" [class.onet-status-dot--active]="connected()"></div>
|
|
13
|
+
<div class="onet-status-info">
|
|
14
|
+
<div class="onet-status-label">ONET Connection</div>
|
|
15
|
+
<div class="onet-status-val">{{ connected() ? 'Connected' : 'Disconnected' }}</div>
|
|
16
|
+
</div>
|
|
17
|
+
<button class="onet-btn" (click)="connected.set(!connected())">{{ connected() ? 'Disconnect' : 'Connect' }}</button>
|
|
18
|
+
</div>
|
|
19
|
+
@if (connected()) {
|
|
20
|
+
<div class="onet-stats">
|
|
21
|
+
@for (s of stats; track s.label) {
|
|
22
|
+
<div class="onet-stat"><div class="onet-stat-val">{{ s.value }}</div><div class="onet-stat-label">{{ s.label }}</div></div>
|
|
23
|
+
}
|
|
24
|
+
</div>
|
|
25
|
+
<div class="onet-peers-header">Active Peers</div>
|
|
26
|
+
<div class="onet-peers">
|
|
27
|
+
@for (p of peers; track p.id) {
|
|
28
|
+
<div class="onet-peer">
|
|
29
|
+
<div class="onet-peer-icon">👤</div>
|
|
30
|
+
<div class="onet-peer-info"><div class="onet-peer-name">{{ p.name }}</div><div class="onet-peer-location">{{ p.location }}</div></div>
|
|
31
|
+
<div class="onet-peer-ping">{{ p.ping }}ms</div>
|
|
32
|
+
</div>
|
|
33
|
+
}
|
|
34
|
+
</div>
|
|
35
|
+
}
|
|
36
|
+
</div>
|
|
37
|
+
`,
|
|
38
|
+
styles: [`
|
|
39
|
+
.onet-shell{display:flex;flex-direction:column;gap:18px}
|
|
40
|
+
.onet-header{text-align:center}
|
|
41
|
+
.onet-title{font-family:'Orbitron',sans-serif;font-size:20px;color:#fff;margin:0 0 6px}
|
|
42
|
+
.onet-sub{font-size:13px;color:#7a9bbf;margin:0}
|
|
43
|
+
.onet-status-card{display:flex;align-items:center;gap:14px;background:rgba(255,255,255,.04);border:1px solid rgba(0,200,255,.12);border-radius:12px;padding:16px}
|
|
44
|
+
.onet-status--active{border-color:rgba(72,220,130,.3)}
|
|
45
|
+
.onet-status-dot{width:12px;height:12px;border-radius:50%;background:#4a6a88;flex-shrink:0;transition:all .3s}
|
|
46
|
+
.onet-status-dot--active{background:#48dc82;box-shadow:0 0 10px #48dc82}
|
|
47
|
+
.onet-status-info{flex:1}
|
|
48
|
+
.onet-status-label{font-size:12px;color:#7a9bbf;text-transform:uppercase;letter-spacing:.06em}
|
|
49
|
+
.onet-status-val{font-family:'Orbitron',sans-serif;font-size:14px;color:#fff;margin-top:3px}
|
|
50
|
+
.onet-btn{background:linear-gradient(135deg,#00c8ff,#0080ff);border:none;border-radius:8px;color:#fff;font-family:'Orbitron',sans-serif;font-size:12px;font-weight:700;letter-spacing:.08em;padding:9px 18px;cursor:pointer}
|
|
51
|
+
.onet-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
|
|
52
|
+
.onet-stat{background:rgba(255,255,255,.04);border:1px solid rgba(0,200,255,.1);border-radius:10px;padding:14px;text-align:center}
|
|
53
|
+
.onet-stat-val{font-family:'Share Tech Mono',monospace;font-size:18px;color:#00c8ff;font-weight:600}
|
|
54
|
+
.onet-stat-label{font-size:11px;color:#7a9bbf;margin-top:4px;text-transform:uppercase;letter-spacing:.06em}
|
|
55
|
+
.onet-peers-header{font-family:'Orbitron',sans-serif;font-size:12px;color:#7a9bbf;letter-spacing:.06em;text-transform:uppercase}
|
|
56
|
+
.onet-peers{display:flex;flex-direction:column;gap:8px}
|
|
57
|
+
.onet-peer{display:flex;align-items:center;gap:12px;padding:10px 14px;background:rgba(255,255,255,.03);border:1px solid rgba(0,200,255,.07);border-radius:8px}
|
|
58
|
+
.onet-peer-icon{font-size:20px}
|
|
59
|
+
.onet-peer-info{flex:1}
|
|
60
|
+
.onet-peer-name{font-size:13px;color:#e0f0ff}
|
|
61
|
+
.onet-peer-location{font-size:11px;color:#4a6a88;margin-top:2px}
|
|
62
|
+
.onet-peer-ping{font-family:'Share Tech Mono',monospace;font-size:12px;color:#48dc82}
|
|
63
|
+
`]
|
|
64
|
+
})
|
|
65
|
+
export class OnetComponent {
|
|
66
|
+
connected = signal(false);
|
|
67
|
+
stats = [
|
|
68
|
+
{ label: 'Peers', value: '2,847' },
|
|
69
|
+
{ label: 'Speed', value: '1.2 Gb/s' },
|
|
70
|
+
{ label: 'Encrypted', value: '100%' },
|
|
71
|
+
];
|
|
72
|
+
peers = [
|
|
73
|
+
{ id: '1', name: 'AvatarX_7291', location: 'New York, US', ping: 14 },
|
|
74
|
+
{ id: '2', name: 'StarKeeper_99', location: 'London, UK', ping: 32 },
|
|
75
|
+
{ id: '3', name: 'NeonRider_404', location: 'Tokyo, JP', ping: 67 },
|
|
76
|
+
];
|
|
77
|
+
}
|