Sostituito frontend angular new con frontend angular. Sostituito frontend angular con frontend angular old

This commit is contained in:
Lorenzo Sanesi
2026-08-10 13:10:18 +02:00
parent 3d4eac4ea5
commit 0ed70eaa18
54 changed files with 7685 additions and 12730 deletions
-94
View File
@@ -1,94 +0,0 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"cli": {
"packageManager": "npm",
"schematicCollections": [
"angular-eslint"
]
},
"newProjectRoot": "projects",
"projects": {
"app": {
"projectType": "application",
"schematics": {},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular/build:application",
"options": {
"define": {
"GEMINI_API_KEY": "'YOUR_GEMINI_API_KEY'"
},
"browser": "src/main.ts",
"tsConfig": "tsconfig.app.json",
"assets": [
{
"glob": "**/*",
"input": "public"
}
],
"styles": [
"src/styles.css"
]
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"budgets": [
{
"type": "initial",
"maximumWarning": "500kB",
"maximumError": "1MB"
},
{
"type": "anyComponentStyle",
"maximumWarning": "4kB",
"maximumError": "8kB"
}
],
"outputHashing": "all"
},
"development": {
"optimization": false,
"extractLicenses": false,
"sourceMap": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular/build:dev-server",
"configurations": {
"production": {
"buildTarget": "app:build:production"
},
"development": {
"buildTarget": "app:build:development"
}
},
"defaultConfiguration": "development"
},
"test": {
"builder": "@angular/build:unit-test"
},
"lint": {
"builder": "@angular-eslint/builder:lint",
"options": {
"lintFilePatterns": [
"src/**/*.ts",
"src/**/*.html"
]
}
}
}
}
}
}
-5
View File
@@ -1,5 +0,0 @@
{
"name": "ScommettiApp",
"description": "A social betting and challenge platform to compete with friends and join communities.",
"requestFramePermissions": ["geolocation"]
}
File diff suppressed because it is too large Load Diff
-46
View File
@@ -1,46 +0,0 @@
{
"name": "amici-scommesse",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "ng serve",
"build": "ng build",
"preview": "ng serve --configuration=production"
},
"dependencies": {
"@angular/cdk": "^21.0.0",
"@angular/common": "^21.0.0",
"@angular/compiler": "^21.0.0",
"@angular/core": "^21.0.0",
"@angular/forms": "^21.0.0",
"@angular/material": "^21.0.0",
"@angular/platform-browser": "^21.0.0",
"@angular/platform-server": "^21.0.0",
"@angular/router": "^21.0.0",
"@angular/ssr": "^21.0.0",
"@google/genai": "^1.27.0",
"express": "^5.1.0",
"keycloak-js": "^26.2.3",
"motion": "^12.23.24",
"rxjs": "~7.8.0",
"tslib": "^2.3.0"
},
"devDependencies": {
"@angular/build": "^21.0.0",
"@angular/cli": "^21.0.0",
"@angular/compiler-cli": "^21.0.0",
"@tailwindcss/postcss": "^4.1.12",
"@types/express": "^5.0.1",
"@types/node": "^20.17.19",
"angular-eslint": "21.1.0",
"cross-env": "^10.1.0",
"eslint": "^9.39.1",
"jsdom": "^27.0.0",
"postcss": "^8.5.3",
"tailwindcss": "^4.1.12",
"typescript": "~5.9.2",
"typescript-eslint": "8.47.0",
"vitest": "^4.0.0"
}
}
@@ -1,156 +0,0 @@
<div class="min-h-screen pb-32">
<header class="sticky top-0 z-50 bg-background/80 backdrop-blur-md flex justify-between items-center px-6 py-4">
<div class="flex items-center gap-4">
<button class="w-10 h-10 rounded-full flex items-center justify-center hover:bg-surface-container transition-colors" [routerLink]="['/']">
<mat-icon>arrow_back</mat-icon>
</button>
<h1 class="font-headline font-black tracking-tight text-xl text-primary">The Arena</h1>
</div>
<div class="flex items-center gap-3">
<button (click)="editChallenge()" class="w-10 h-10 rounded-full flex items-center justify-center hover:bg-surface-container transition-colors text-primary">
<mat-icon>edit</mat-icon>
</button>
<mat-icon class="text-on-surface-variant cursor-pointer">search</mat-icon>
<div class="w-8 h-8 rounded-full bg-primary-container overflow-hidden">
<img src="https://picsum.photos/seed/user/100/100" class="w-full h-full object-cover" alt="User Avatar">
</div>
</div>
</header>
<main class="max-w-xl mx-auto px-6 pt-8 space-y-8">
@if (isLoading()) {
<div class="flex flex-col items-center justify-center py-20">
<div class="w-12 h-12 border-4 border-primary border-t-transparent rounded-full animate-spin"></div>
<p class="mt-4 text-on-surface-variant font-medium">Loading arena details...</p>
</div>
} @else if (bet(); as data) {
<!-- Hero Section -->
<section class="space-y-4">
<div class="flex justify-between items-start">
<div class="space-y-1">
<span class="inline-flex items-center px-3 py-1 rounded-full bg-secondary-container text-secondary text-xs font-semibold tracking-wide uppercase">
{{ data.status }}
</span>
<h2 class="text-3xl font-headline font-extrabold">{{ data.title }}</h2>
</div>
<div class="bg-surface-container p-3 rounded-2xl flex flex-col items-center">
<span class="text-[10px] font-bold text-on-surface-variant uppercase tracking-widest">Stake</span>
<span class="text-xl font-headline font-black text-primary">€{{ data.stake }}</span>
</div>
</div>
<p class="text-on-surface-variant text-lg">{{ data.description || 'No description provided.' }}</p>
</section>
<!-- Stats -->
<div class="grid grid-cols-2 gap-4">
<div class="bg-surface-container-low p-6 rounded-2xl flex flex-col gap-1 border border-black/5">
<span class="text-xs font-medium text-on-surface-variant">Start Date</span>
<span class="text-sm font-headline font-bold">{{ data.startDate | date:'mediumDate' }}</span>
</div>
<div class="bg-surface-container-low p-6 rounded-2xl flex flex-col gap-1 border border-black/5">
<span class="text-xs font-medium text-on-surface-variant">Visibility</span>
<span class="text-sm font-headline font-bold">{{ data.isPublic ? 'Public' : 'Private' }}</span>
</div>
</div>
<!-- Participants -->
<section class="space-y-4">
<div class="flex items-center justify-between">
<h3 class="font-headline font-bold">Participants</h3>
<span class="text-sm font-medium text-primary">{{ data.participants.length }} Joined</span>
</div>
<div class="flex flex-wrap gap-3">
@for (p of data.participants; track $index) {
<div class="flex flex-col items-center gap-1">
<div class="relative">
@if ($any(p.user)?.avatarUrl) {
<img [src]="$any(p.user).avatarUrl" class="h-12 w-12 rounded-full ring-2 ring-primary/20 object-cover" [alt]="$any(p.user).name">
} @else {
<div class="h-12 w-12 rounded-full ring-2 ring-primary/20 bg-primary-container/20 flex items-center justify-center">
<mat-icon class="text-primary">person</mat-icon>
</div>
}
@if (p.role === 'OBSERVER') {
<div class="absolute -bottom-1 -right-1 bg-surface-container rounded-full p-0.5 shadow-sm">
<mat-icon class="text-[10px] text-on-surface-variant">visibility</mat-icon>
</div>
}
</div>
<span class="text-[10px] font-medium text-on-surface-variant">{{ $any(p.user)?.name || 'Utente' }}</span>
</div>
}
</div>
</section>
} @else {
<div class="flex flex-col items-center justify-center py-20 text-center">
<mat-icon class="text-6xl text-on-surface-variant/20 mb-4">search_off</mat-icon>
<h3 class="text-xl font-headline font-bold">Challenge Not Found</h3>
<p class="text-on-surface-variant mt-2">The challenge you're looking for doesn't exist or has been removed.</p>
<button class="mt-6 text-primary font-bold" [routerLink]="['/']">Go Back Home</button>
</div>
}
<!-- Live Standings -->
<section class="bg-surface-container p-6 rounded-2xl space-y-6 border border-black/5">
<div class="flex items-center justify-between">
<h3 class="font-headline font-bold">Live Standings</h3>
<mat-icon class="text-primary">leaderboard</mat-icon>
</div>
<div class="space-y-5">
<div class="space-y-2">
<div class="flex justify-between items-end">
<span class="text-sm font-bold">You (Alex)</span>
<span class="text-xs font-medium text-on-surface-variant">16,402 / 20,000</span>
</div>
<div class="h-3 w-full bg-surface-container-highest rounded-full overflow-hidden">
<div class="h-full bg-gradient-to-r from-primary to-primary-container rounded-full" style="width: 82%"></div>
</div>
</div>
<div class="space-y-2">
<div class="flex justify-between items-end">
<span class="text-sm font-medium">Sarah J.</span>
<span class="text-xs font-medium text-on-surface-variant">18,210 / 20,000</span>
</div>
<div class="h-3 w-full bg-surface-container-highest rounded-full overflow-hidden">
<div class="h-full bg-tertiary rounded-full" style="width: 91%"></div>
</div>
</div>
</div>
</section>
<!-- Stats Bento -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="bg-surface-container-low p-6 rounded-2xl flex items-center gap-4 border border-black/5">
<div class="w-12 h-12 rounded-full bg-tertiary-container/20 flex items-center justify-center">
<mat-icon class="text-tertiary">local_fire_department</mat-icon>
</div>
<div>
<p class="text-xs font-medium text-on-surface-variant">Hot Streak</p>
<p class="text-lg font-headline font-bold">3 Wins</p>
</div>
</div>
<div class="bg-surface-container-low p-6 rounded-2xl flex items-center gap-4 border border-black/5">
<div class="w-12 h-12 rounded-full bg-secondary-container/20 flex items-center justify-center">
<mat-icon class="text-secondary">groups</mat-icon>
</div>
<div>
<p class="text-xs font-medium text-on-surface-variant">Activity Level</p>
<p class="text-lg font-headline font-bold">High</p>
</div>
</div>
</div>
</main>
<!-- Action Buttons -->
<div class="fixed bottom-0 left-0 w-full p-6 bg-background/80 backdrop-blur-xl z-40 border-t border-black/5">
<div class="max-w-xl mx-auto flex flex-col gap-3">
<button class="w-full py-4 bg-gradient-to-r from-primary to-primary-container text-white font-headline font-bold rounded-full shadow-lg active:scale-95 transition-transform">
Update Progress
</button>
<button class="w-full py-4 bg-surface-container-highest text-on-surface font-headline font-bold rounded-full active:scale-95 transition-transform flex items-center justify-center gap-2">
<mat-icon>person_add</mat-icon>
Invite Friends
</button>
</div>
</div>
</div>
@@ -1,48 +0,0 @@
import {ChangeDetectionStrategy, Component, inject, signal, OnInit} from '@angular/core';
import {CommonModule} from '@angular/common';
import {MatIconModule} from '@angular/material/icon';
import {RouterModule, Router, ActivatedRoute} from '@angular/router';
import {BetService} from '../../services/bet';
import {Bet} from '../../models/data.models';
@Component({
selector: 'app-challenge-detail',
standalone: true,
imports: [CommonModule, MatIconModule, RouterModule],
templateUrl: './challenge-detail.html',
styleUrl: './challenge-detail.css',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ChallengeDetail implements OnInit {
private router = inject(Router);
private route = inject(ActivatedRoute);
private betService = inject(BetService);
challengeId = this.route.snapshot.paramMap.get('id');
bet = signal<Bet | null>(null);
isLoading = signal(true);
ngOnInit() {
if (this.challengeId) {
this.betService.getBetById(this.challengeId).subscribe({
next: (data) => {
this.bet.set(data);
this.isLoading.set(false);
},
error: (err) => {
console.error('Error loading bet:', err);
this.isLoading.set(false);
}
});
}
}
editChallenge() {
const data = this.bet();
if (data) {
this.router.navigate(['/create-bet'], {
state: { bet: data }
});
}
}
}
@@ -1,7 +0,0 @@
export const environment = {
production: true,
apiUrl: '', // da compilare in produzione
keycloakUrl: '',
keycloakRealm: 'scommettiapp',
keycloakClientId: 'scommetti-frontend',
};
-35
View File
@@ -1,35 +0,0 @@
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
{
"compileOnSave": false,
"compilerOptions": {
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"skipLibCheck": true,
"isolatedModules": true,
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"importHelpers": true,
"target": "ES2022",
"module": "preserve"
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
},
"files": [],
"references": [
{
"path": "./tsconfig.app.json"
},
{
"path": "./tsconfig.spec.json"
}
]
}
@@ -6,7 +6,7 @@
This contains everything you need to run your app locally. This contains everything you need to run your app locally.
View your app in AI Studio: https://ai.studio/apps/7d951078-743c-4db5-ac20-6a2c625411e7 View your app in AI Studio: https://ai.studio/apps/drive/1LXZWZLxW6p8pFAQ_ECq5pcD0utESimfc
## Run Locally ## Run Locally
+52
View File
@@ -0,0 +1,52 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "",
"projects": {
"app": {
"projectType": "application",
"root": "",
"sourceRoot": "./",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular/build:application",
"options": {
"outputPath": {
"base": "./dist",
"browser": "."
},
"browser": "index.tsx",
"tsConfig": "tsconfig.json"
},
"configurations": {
"production": {
"outputHashing": "all"
},
"development": {
"optimization": false,
"extractLicenses": false,
"sourceMap": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular/build:dev-server",
"options": {
"port": 4200
},
"configurations": {
"production": {
"buildTarget": "app:build:production"
},
"development": {
"buildTarget": "app:build:development"
}
},
"defaultConfiguration": "development"
}
}
}
}
}
+5
View File
@@ -0,0 +1,5 @@
{
"name": "Amici Scommesse",
"description": "Un'app per creare e gestire scommesse tra amici. Tieni traccia delle scommesse, crea gruppi, e partecipa a sfide pubbliche per guadagnare punti gloria.",
"requestFramePermissions": []
}
File diff suppressed because it is too large Load Diff
+28
View File
@@ -0,0 +1,28 @@
{
"name": "amici-scommesse",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "ng serve",
"build": "ng build",
"preview": "ng serve --configuration=production"
},
"dependencies": {
"rxjs": "^7.8.2",
"@angular/compiler": "^20.3.0",
"@angular/platform-browser": "^20.3.0",
"@angular/common": "^20.3.0",
"@angular/core": "^20.3.0",
"@angular/build": "^20.3.0",
"@angular/cli": "^20.3.0",
"@angular/compiler-cli": "^20.3.0",
"keycloak-js": "^24.0.0",
"tailwindcss": "latest"
},
"devDependencies": {
"@types/node": "^22.14.0",
"typescript": "~5.8.2",
"vite": "^6.2.0"
}
}
+33
View File
@@ -0,0 +1,33 @@
{
"compilerOptions": {
"target": "ES2022",
"experimentalDecorators": true,
"useDefineForClassFields": false,
"module": "ESNext",
"lib": [
"ES2022",
"DOM",
"DOM.Iterable"
],
"skipLibCheck": true,
"types": [
"node"
],
"moduleResolution": "bundler",
"isolatedModules": true,
"moduleDetection": "force",
"allowJs": true,
"jsx": "react-jsx",
"paths": {
"@/*": [
"./*"
]
}
},
"files": [
"./index.tsx"
],
"angularCompilerOptions": {
"disableTypeScriptVersionCheck": true
}
}