@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.
Files changed (118) hide show
  1. package/package.json +37 -0
  2. package/src/components/avatar/avatar-wallet.component.ts +49 -0
  3. package/src/components/avatar/edit-avatar.component.ts +28 -0
  4. package/src/components/avatar/search-avatar.component.ts +45 -0
  5. package/src/components/avatar/view-avatar.component.ts +49 -0
  6. package/src/components/avatar-connect/avatar-connect.component.ts +78 -0
  7. package/src/components/avatar-profile/avatar-profile.component.ts +146 -0
  8. package/src/components/coming-soon/coming-soon.component.ts +27 -0
  9. package/src/components/confirmation/confirmation.component.ts +38 -0
  10. package/src/components/contact/contact.component.ts +64 -0
  11. package/src/components/data-screen/add-data.component.ts +50 -0
  12. package/src/components/data-screen/cross-chain-management.component.ts +28 -0
  13. package/src/components/data-screen/load-data.component.ts +28 -0
  14. package/src/components/data-screen/manage-data.component.ts +50 -0
  15. package/src/components/data-screen/off-chain-management.component.ts +28 -0
  16. package/src/components/data-screen/search-data.component.ts +40 -0
  17. package/src/components/eggs/eggs.component.ts +76 -0
  18. package/src/components/eggs/manage-eggs.component.ts +50 -0
  19. package/src/components/eggs/search-eggs.component.ts +40 -0
  20. package/src/components/eggs/view-eggs.component.ts +49 -0
  21. package/src/components/forgot-password/forgot-password.component.ts +80 -0
  22. package/src/components/game/game.component.ts +58 -0
  23. package/src/components/game/search-profiles.component.ts +36 -0
  24. package/src/components/game/view-achievements.component.ts +48 -0
  25. package/src/components/game/view-leagues.component.ts +48 -0
  26. package/src/components/game/view-tournaments.component.ts +49 -0
  27. package/src/components/hyperdrive/hyperdrive.component.ts +81 -0
  28. package/src/components/karma/search-karma.component.ts +36 -0
  29. package/src/components/karma/view-avatar-karma.component.ts +51 -0
  30. package/src/components/karma/view-karma.component.ts +46 -0
  31. package/src/components/karma/vote-karma.component.ts +48 -0
  32. package/src/components/karma-panel/karma-panel.component.ts +87 -0
  33. package/src/components/karma-toast/karma-toast.component.ts +33 -0
  34. package/src/components/login/login.component.ts +95 -0
  35. package/src/components/map/add-2d-object-map.component.ts +42 -0
  36. package/src/components/map/add-3d-object-map.component.ts +43 -0
  37. package/src/components/map/add-quest-to-map.component.ts +42 -0
  38. package/src/components/map/download-our-world.component.ts +28 -0
  39. package/src/components/map/manage-map.component.ts +28 -0
  40. package/src/components/map/map.component.ts +70 -0
  41. package/src/components/map/plot-route-on-map.component.ts +42 -0
  42. package/src/components/map/search-map.component.ts +44 -0
  43. package/src/components/map/view-global-3d-map.component.ts +28 -0
  44. package/src/components/map/view-halons-on-map.component.ts +28 -0
  45. package/src/components/map/view-oapp-on-map.component.ts +28 -0
  46. package/src/components/map/view-quest-on-map.component.ts +28 -0
  47. package/src/components/menu-message/menu-message.component.ts +69 -0
  48. package/src/components/messages/message.component.ts +59 -0
  49. package/src/components/messaging/messaging.component.ts +89 -0
  50. package/src/components/mission/manage-mission.component.ts +43 -0
  51. package/src/components/mission/mission.component.ts +63 -0
  52. package/src/components/mission/search-mission.component.ts +36 -0
  53. package/src/components/mission/view-mission.component.ts +49 -0
  54. package/src/components/modal/modal.component.ts +28 -0
  55. package/src/components/navbar/navbar.component.ts +64 -0
  56. package/src/components/nft/contact-popup.component.ts +41 -0
  57. package/src/components/nft/manage-oasis-nft.component.ts +43 -0
  58. package/src/components/nft/nft.component.ts +70 -0
  59. package/src/components/nft/purchase-oasis-nft.component.ts +53 -0
  60. package/src/components/nft/purchase-oasis-virtual-land-nft.component.ts +28 -0
  61. package/src/components/nft/search-oasis-nft.component.ts +36 -0
  62. package/src/components/nft/solana.component.ts +28 -0
  63. package/src/components/nft/view-oasis-nft.component.ts +52 -0
  64. package/src/components/oapp/create-oapp.component.ts +43 -0
  65. package/src/components/oapp/deploy-oapp.component.ts +42 -0
  66. package/src/components/oapp/download-our-world.component.ts +28 -0
  67. package/src/components/oapp/edit-oapp.component.ts +41 -0
  68. package/src/components/oapp/install-oapp.component.ts +36 -0
  69. package/src/components/oapp/launch-oapp.component.ts +58 -0
  70. package/src/components/oapp/manage-oapp.component.ts +42 -0
  71. package/src/components/oapp/oapp.component.ts +70 -0
  72. package/src/components/oapp/search-oapp.component.ts +36 -0
  73. package/src/components/oasis-card/oasis-card.component.ts +30 -0
  74. package/src/components/onet/onet.component.ts +77 -0
  75. package/src/components/onode/onode.component.ts +73 -0
  76. package/src/components/provider/activity-pub.component.ts +44 -0
  77. package/src/components/provider/compare-provider-speeds.component.ts +48 -0
  78. package/src/components/provider/eosio.component.ts +44 -0
  79. package/src/components/provider/ethereum.component.ts +44 -0
  80. package/src/components/provider/holochain.component.ts +44 -0
  81. package/src/components/provider/ipfs.component.ts +44 -0
  82. package/src/components/provider/manage-auto-fail-over.component.ts +42 -0
  83. package/src/components/provider/manage-auto-replicaton.component.ts +42 -0
  84. package/src/components/provider/manage-load-balancing.component.ts +42 -0
  85. package/src/components/provider/manage-providers.component.ts +28 -0
  86. package/src/components/provider/mongo-db.component.ts +44 -0
  87. package/src/components/provider/neo4j.component.ts +44 -0
  88. package/src/components/provider/search-providers.component.ts +36 -0
  89. package/src/components/provider/seeds-provider.component.ts +42 -0
  90. package/src/components/provider/solid.component.ts +44 -0
  91. package/src/components/provider/sql-lite.component.ts +44 -0
  92. package/src/components/provider/three-fold.component.ts +44 -0
  93. package/src/components/provider/view-provider-stats.component.ts +61 -0
  94. package/src/components/provider/view-providers.component.ts +54 -0
  95. package/src/components/provider-dropdown/provider-dropdown.component.ts +64 -0
  96. package/src/components/providers/providers.component.ts +60 -0
  97. package/src/components/quest/manage-quest.component.ts +43 -0
  98. package/src/components/quest/quest.component.ts +65 -0
  99. package/src/components/quest/search-quest.component.ts +36 -0
  100. package/src/components/quest/view-quest.component.ts +49 -0
  101. package/src/components/reset-password/reset-password.component.ts +68 -0
  102. package/src/components/search-avatars/search-avatars.component.ts +80 -0
  103. package/src/components/seeds/accept-invite.component.ts +44 -0
  104. package/src/components/seeds/donate-seeds.component.ts +42 -0
  105. package/src/components/seeds/manage-seeds.component.ts +42 -0
  106. package/src/components/seeds/pay-with-seeds.component.ts +41 -0
  107. package/src/components/seeds/reward-seeds.component.ts +41 -0
  108. package/src/components/seeds/search-seeds.component.ts +36 -0
  109. package/src/components/seeds/seeds.component.ts +75 -0
  110. package/src/components/seeds/send-invite.component.ts +41 -0
  111. package/src/components/seeds/view-organizations.component.ts +55 -0
  112. package/src/components/seeds/view-seeds.component.ts +78 -0
  113. package/src/components/settings/settings.component.ts +96 -0
  114. package/src/components/signup/signup.component.ts +118 -0
  115. package/src/components/star-field/star-field.component.ts +44 -0
  116. package/src/components/verify-email/verify-email.component.ts +48 -0
  117. package/src/components/wallet/wallet.component.ts +83 -0
  118. 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
+ }