From 49e1bcac811f68b1948a9b977eade496bf90ff13 Mon Sep 17 00:00:00 2001 From: Alexis Bruneteau Date: Wed, 4 Jun 2025 21:52:54 +0200 Subject: [PATCH] working good --- .../dashboard/dashboard.component.html | 52 ++--- .../components/landing/landing.component.html | 31 +-- .../components/landing/landing.component.ts | 31 ++- src/app/models/portfolio.model.ts | 1 + src/app/services/api.ts | 209 +++++++++--------- src/app/services/portfolio.service.ts | 5 + 6 files changed, 171 insertions(+), 158 deletions(-) diff --git a/src/app/components/dashboard/dashboard.component.html b/src/app/components/dashboard/dashboard.component.html index d7c1704..ca16d02 100644 --- a/src/app/components/dashboard/dashboard.component.html +++ b/src/app/components/dashboard/dashboard.component.html @@ -13,43 +13,45 @@

{{ p.name }}

- {{ p.path ? 'Uploaded' : 'Pending Upload' }} - + [ngClass]="!p.active ? 'bg-red-100 text-red-600' : + p.path ? 'bg-green-100 text-green-600' : + 'bg-yellow-100 text-yellow-600'"> + {{ !p.active ? 'Pending Payment' : (p.path ? 'Uploaded' : 'Pending Upload') }} +
- {{ p.domain }}.portfolio-host.com + {{ p.domain }} -
+
- - + /> - - @if (p.path) { - - } -
+ > + 🚀 Deploy + + } +
- - @if (uploading[p.id]) { -

Uploading...

- } + + @if (uploading[p.id]) { +

Uploading...

+ } } diff --git a/src/app/components/landing/landing.component.html b/src/app/components/landing/landing.component.html index 81e6a8b..8e14d4e 100644 --- a/src/app/components/landing/landing.component.html +++ b/src/app/components/landing/landing.component.html @@ -1,7 +1,7 @@
+ class="bg-white py-20 px-6 text-center md:text-left md:px-20 flex flex-col flex items-center justify-between">

Host Your Portfolio. Impress the World. @@ -13,15 +13,13 @@ -

-
- Portfolio Illustration -
+ @@ -29,26 +27,21 @@

Why Choose PortfolioHost?

-
+
-
+

Blazing Fast Hosting

-

NVMe servers & global CDN ensure speed and uptime.

+

NVMe servers & lightning fast deployment pipeline.

-
🌐
-

Custom Domains

-

Use your own domain or get a .portfoliohost.dev address.

+
🌐
+

Free Domains

+

Get a free .portfolio-host.com address.

-
🚀
+
🚀

1-Click Deploy

-

Integrate with GitHub or push manually in seconds.

-
-
-
📱
-

Fully Responsive

-

Mobile-first designs that look great everywhere.

+

Integrate with GitHub (COMING SOON) or push manually in seconds.

@@ -56,7 +49,7 @@

Ready to impress recruiters and clients?

-

Create your portfolio in minutes — no coding required.

+

Host your portfolio in seconds.

diff --git a/src/app/components/landing/landing.component.ts b/src/app/components/landing/landing.component.ts index 7fa642c..8500b74 100644 --- a/src/app/components/landing/landing.component.ts +++ b/src/app/components/landing/landing.component.ts @@ -1,6 +1,7 @@ -import { Component } from '@angular/core'; -import { Router } from '@angular/router'; +import {Component} from '@angular/core'; +import {Router} from '@angular/router'; import {ApiService} from '../../services/api'; +import {PortfolioService} from '../../services/portfolio.service'; @Component({ selector: 'app-root', @@ -8,14 +9,24 @@ import {ApiService} from '../../services/api'; }) export class LandingComponent { - constructor( - private apiService: ApiService, - private router: Router, - ) { - } - - signUp(): void{ - this.router.navigate(['/register']); + constructor( + private apiService: ApiService, + private portfolioService: PortfolioService, + private router: Router, + ) { } + signUp(): void { + this.router.navigate(['/register']); + } + + exemple() { + this.portfolioService.getRandomPortfolio().subscribe({ + next: (res) => { + window.location.href = 'https://' + res.data.host; + } + + } + ) + } } diff --git a/src/app/models/portfolio.model.ts b/src/app/models/portfolio.model.ts index c022cc4..dbd3296 100644 --- a/src/app/models/portfolio.model.ts +++ b/src/app/models/portfolio.model.ts @@ -1,4 +1,5 @@ export interface Portfolio { + active: boolean; id: number; name: string; domain: string; diff --git a/src/app/services/api.ts b/src/app/services/api.ts index abd90b9..917410d 100644 --- a/src/app/services/api.ts +++ b/src/app/services/api.ts @@ -1,8 +1,9 @@ -import { Injectable } from '@angular/core'; -import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http'; -import { Observable, throwError, BehaviorSubject } from 'rxjs'; -import { catchError, tap } from 'rxjs/operators'; -import { environmentProd as env } from '../../environments/environment' ; +import {Injectable} from '@angular/core'; +import {HttpClient, HttpErrorResponse, HttpHeaders} from '@angular/common/http'; +import {BehaviorSubject, Observable, throwError} from 'rxjs'; +import {catchError, tap} from 'rxjs/operators'; +import {environmentProd as env} from '../../environments/environment'; +import {Router} from '@angular/router'; export interface LoginCredentials { email: string; @@ -37,32 +38,7 @@ export class ApiService { private tokenSubject = new BehaviorSubject(this.getStoredToken()); public token$ = this.tokenSubject.asObservable(); - constructor(protected http: HttpClient) {} - - // Get stored token from localStorage - private getStoredToken(): string | null { - if (typeof window !== 'undefined') { - return localStorage.getItem('auth_token'); - } - return null; - } - - // Set token in localStorage and update subject - private setToken(token: string): void { - if (typeof window !== 'undefined') { - localStorage.setItem('auth_token', token); - } - this.tokenSubject.next(token); - } - - // Remove token from localStorage and update subject - private removeToken(): void { - if (typeof window !== 'undefined') { - console.log('?? ?? ??') - localStorage.removeItem('auth_token'); - } - this.tokenSubject.next(null); - } + constructor(protected http: HttpClient, private router: Router) {} // Get current token value get currentToken(): string | null { @@ -74,79 +50,6 @@ export class ApiService { return !!this.currentToken; } - // Get HTTP headers with auth token - private getHeaders(): HttpHeaders { - let headers = new HttpHeaders({ - //'Content-Type': 'application/json', - //'Accept': 'application/json' - }); - - const token = this.currentToken; - if (token) { - headers = headers.set('Authorization', `Bearer ${token}`); - } - - return headers; - } - - // Handle HTTP errors - private handleError(error: HttpErrorResponse): Observable { - let errorMessage = 'An unknown error occurred'; - - if (error.error instanceof ErrorEvent) { - // Client-side error - errorMessage = error.error.message; - } else { - // Server-side error - if (error.status === 401) { - //this.removeToken(); - errorMessage = 'Unauthorized. Please login again.'; - } else if (error.status === 422) { - errorMessage = 'Validation error'; - } else if (error.error?.message) { - errorMessage = error.error.message; - } else { - errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`; - } - } - - console.error('API Error:', error); - return throwError(() => ({ ...error, userMessage: errorMessage })); - } - - // Generic HTTP methods - protected get(endpoint: string): Observable { - return this.http.get(`${this.baseUrl}${endpoint}`, { - headers: this.getHeaders() - }).pipe( - catchError(this.handleError.bind(this)) - ); - } - - protected post(endpoint: string, data: any): Observable { - return this.http.post(`${this.baseUrl}${endpoint}`, data, { - headers: this.getHeaders() - }).pipe( - catchError(this.handleError.bind(this)) - ); - } - - private put(endpoint: string, data: any): Observable { - return this.http.put(`${this.baseUrl}${endpoint}`, data, { - headers: this.getHeaders() - }).pipe( - catchError(this.handleError.bind(this)) - ); - } - - private delete(endpoint: string): Observable { - return this.http.delete(`${this.baseUrl}${endpoint}`, { - headers: this.getHeaders() - }).pipe( - catchError(this.handleError.bind(this)) - ); - } - // Authentication methods register(userData: RegisterData): Observable> { return this.post>('/auth/register', userData).pipe( @@ -207,4 +110,102 @@ export class ApiService { deleteData(endpoint: string): Observable { return this.delete(endpoint); } + + // Generic HTTP methods + protected get(endpoint: string): Observable { + return this.http.get(`${this.baseUrl}${endpoint}`, { + headers: this.getHeaders() + }).pipe( + catchError(this.handleError.bind(this)) + ); + } + + protected post(endpoint: string, data: any): Observable { + return this.http.post(`${this.baseUrl}${endpoint}`, data, { + headers: this.getHeaders() + }).pipe( + catchError(this.handleError.bind(this)) + ); + } + + // Get stored token from localStorage + private getStoredToken(): string | null { + if (typeof window !== 'undefined') { + return localStorage.getItem('auth_token'); + } + return null; + } + + // Set token in localStorage and update subject + private setToken(token: string): void { + if (typeof window !== 'undefined') { + localStorage.setItem('auth_token', token); + } + this.tokenSubject.next(token); + } + + // Remove token from localStorage and update subject + private removeToken(): void { + if (typeof window !== 'undefined') { + console.log('?? ?? ??') + localStorage.removeItem('auth_token'); + } + this.tokenSubject.next(null); + } + + // Get HTTP headers with auth token + private getHeaders(): HttpHeaders { + let headers = new HttpHeaders({ + //'Content-Type': 'application/json', + //'Accept': 'application/json' + }); + + const token = this.currentToken; + if (token) { + headers = headers.set('Authorization', `Bearer ${token}`); + } + + return headers; + } + + // Handle HTTP errors + private handleError(error: HttpErrorResponse): Observable { + let errorMessage = 'An unknown error occurred'; + + if (error.error instanceof ErrorEvent) { + // Client-side error + errorMessage = error.error.message; + } else { + // Server-side error + if (error.status === 401) { + this.removeToken(); + this.router.navigate(['/login']) + } else if (error.status === 422) { + errorMessage = 'Validation error'; + } else if (error.error?.message) { + errorMessage = error.error.message; + } else { + errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`; + } + } + + console.error('API Error:', error); + return throwError(() => ({...error, userMessage: errorMessage})); + } + + private put(endpoint: string, data: any): Observable { + return this.http.put(`${this.baseUrl}${endpoint}`, data, { + headers: this.getHeaders() + }).pipe( + catchError(this.handleError.bind(this)) + ); + } + + private delete(endpoint: string): Observable { + return this.http.delete(`${this.baseUrl}${endpoint}`, { + headers: this.getHeaders() + }).pipe( + catchError(this.handleError.bind(this)) + ); + } } diff --git a/src/app/services/portfolio.service.ts b/src/app/services/portfolio.service.ts index 6fa2fd5..870607c 100644 --- a/src/app/services/portfolio.service.ts +++ b/src/app/services/portfolio.service.ts @@ -27,4 +27,9 @@ export class PortfolioService extends ApiService{ console.log('Deploying portfolio with ID:', portfolioId); return this.http.post(this.baseUrl + `/portfolios/${portfolioId}/deploy`, {}); } + + getRandomPortfolio() : Observable + { + return this.http.get(this.baseUrl + `/portfolio/random`, {}); + } }