Mail Modul überarbeitet, Korrekturen am PaymentService, neuer customerType seller
This commit is contained in:
parent
b4609d07ba
commit
7a286e3519
|
|
@ -14,7 +14,8 @@
|
||||||
"console": "integratedTerminal",
|
"console": "integratedTerminal",
|
||||||
"env": {
|
"env": {
|
||||||
"HOST_NAME": "localhost"
|
"HOST_NAME": "localhost"
|
||||||
}
|
},
|
||||||
|
"preLaunchTask": "Start Stripe Listener"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "node",
|
"type": "node",
|
||||||
|
|
@ -60,5 +61,30 @@
|
||||||
"sourceMaps": true,
|
"sourceMaps": true,
|
||||||
"smartStep": true
|
"smartStep": true
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "Start Stripe Listener",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "stripe listen -e checkout.session.completed --forward-to http://localhost:3000/bizmatch/payment/webhook",
|
||||||
|
"isBackground": true,
|
||||||
|
"problemMatcher": [
|
||||||
|
{
|
||||||
|
"pattern": [
|
||||||
|
{
|
||||||
|
"regexp": ".",
|
||||||
|
"file": 1,
|
||||||
|
"location": 2,
|
||||||
|
"message": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"background": {
|
||||||
|
"activeOnStart": true,
|
||||||
|
"beginsPattern": ".",
|
||||||
|
"endsPattern": "."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "Start Stripe Listener",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "stripe listen -e checkout.session.completed --forward-to http://localhost:3000/bizmatch/payment/webhook",
|
||||||
|
"problemMatcher": [],
|
||||||
|
"isBackground": true, // Task läuft im Hintergrund
|
||||||
|
"presentation": {
|
||||||
|
"echo": true,
|
||||||
|
"reveal": "always",
|
||||||
|
"focus": false,
|
||||||
|
"panel": "shared"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Start Nest.js",
|
||||||
|
"type": "npm",
|
||||||
|
"script": "start:debug",
|
||||||
|
"isBackground": false,
|
||||||
|
"problemMatcher": [],
|
||||||
|
"presentation": {
|
||||||
|
"echo": true,
|
||||||
|
"reveal": "always",
|
||||||
|
"focus": false,
|
||||||
|
"panel": "shared"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,7 @@ import { boolean, char, doublePrecision, integer, jsonb, pgEnum, pgTable, serial
|
||||||
import { AreasServed, LicensedIn } from '../models/db.model';
|
import { AreasServed, LicensedIn } from '../models/db.model';
|
||||||
export const PG_CONNECTION = 'PG_CONNECTION';
|
export const PG_CONNECTION = 'PG_CONNECTION';
|
||||||
export const genderEnum = pgEnum('gender', ['male', 'female']);
|
export const genderEnum = pgEnum('gender', ['male', 'female']);
|
||||||
export const customerTypeEnum = pgEnum('customerType', ['buyer', 'professional']);
|
export const customerTypeEnum = pgEnum('customerType', ['buyer', 'seller', 'professional']);
|
||||||
export const customerSubTypeEnum = pgEnum('customerSubType', ['broker', 'cpa', 'attorney', 'titleCompany', 'surveyor', 'appraiser']);
|
export const customerSubTypeEnum = pgEnum('customerSubType', ['broker', 'cpa', 'attorney', 'titleCompany', 'surveyor', 'appraiser']);
|
||||||
export const listingsCategoryEnum = pgEnum('listingsCategory', ['commercialProperty', 'business']);
|
export const listingsCategoryEnum = pgEnum('listingsCategory', ['commercialProperty', 'business']);
|
||||||
export const subscriptionTypeEnum = pgEnum('subscriptionType', ['free', 'professional', 'broker']);
|
export const subscriptionTypeEnum = pgEnum('subscriptionType', ['free', 'professional', 'broker']);
|
||||||
|
|
@ -33,8 +33,6 @@ export const users = pgTable('users', {
|
||||||
longitude: doublePrecision('longitude'),
|
longitude: doublePrecision('longitude'),
|
||||||
stripeCustomerId: text('stripeCustomerId'),
|
stripeCustomerId: text('stripeCustomerId'),
|
||||||
subscriptionId: text('subscriptionId'),
|
subscriptionId: text('subscriptionId'),
|
||||||
planActive: boolean('planActive').default(false),
|
|
||||||
planExpires: timestamp('planExpires'),
|
|
||||||
subscriptionPlan: subscriptionTypeEnum('subscriptionType'),
|
subscriptionPlan: subscriptionTypeEnum('subscriptionType'),
|
||||||
// embedding: vector('embedding', { dimensions: 1536 }),
|
// embedding: vector('embedding', { dimensions: 1536 }),
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { registerAs } from '@nestjs/config';
|
||||||
|
|
||||||
|
export default registerAs('mail', () => ({
|
||||||
|
host: 'email-smtp.us-east-2.amazonaws.com',
|
||||||
|
port: 587,
|
||||||
|
secure: false,
|
||||||
|
auth: {
|
||||||
|
user: process.env.AMAZON_USER,
|
||||||
|
pass: process.env.AMAZON_PASSWORD,
|
||||||
|
},
|
||||||
|
defaults: {
|
||||||
|
from: '"No Reply" <noreply@example.com>',
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { Body, Controller, Post } from '@nestjs/common';
|
import { Body, Controller, Post } from '@nestjs/common';
|
||||||
|
import { User } from 'src/models/db.model';
|
||||||
import { ErrorResponse, MailInfo } from '../models/main.model';
|
import { ErrorResponse, MailInfo } from '../models/main.model';
|
||||||
import { MailService } from './mail.service.js';
|
import { MailService } from './mail.service.js';
|
||||||
|
|
||||||
|
|
@ -13,4 +14,8 @@ export class MailController {
|
||||||
return this.mailService.sendRequest(mailInfo);
|
return this.mailService.sendRequest(mailInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@Post('subscriptionConfirmation')
|
||||||
|
sendSubscriptionConfirmation(@Body() user: User): Promise<void | ErrorResponse> {
|
||||||
|
return this.mailService.sendSubscriptionConfirmation(user);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,33 +13,67 @@ import { MailController } from './mail.controller.js';
|
||||||
import { MailService } from './mail.service.js';
|
import { MailService } from './mail.service.js';
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
const __dirname = path.dirname(__filename);
|
const __dirname = path.dirname(__filename);
|
||||||
const user = process.env.amazon_user;
|
const user = process.env.AMAZON_USER;
|
||||||
const password = process.env.amazon_password;
|
const password = process.env.AMAZON_PASSWORD;
|
||||||
|
console.log('Amazon User:', process.env.AMAZON_USER);
|
||||||
|
console.log('Amazon Password:', process.env.AMAZON_PASSWORD);
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
DrizzleModule,
|
DrizzleModule,
|
||||||
UserModule,
|
UserModule,
|
||||||
GeoModule,
|
GeoModule,
|
||||||
MailerModule.forRoot({
|
// ConfigModule.forFeature(mailConfig),
|
||||||
transport: {
|
// MailerModule.forRoot({
|
||||||
host: 'email-smtp.us-east-2.amazonaws.com',
|
// transport: {
|
||||||
secure: false,
|
// host: 'email-smtp.us-east-2.amazonaws.com',
|
||||||
port: 587,
|
// secure: false,
|
||||||
auth: {
|
// port: 587,
|
||||||
user: 'AKIAU6GDWVAQ2QNFLNWN',
|
// auth: {
|
||||||
pass: 'BDE9nZv/ARbpotim1mIOir52WgIbpSi9cv1oJoH8oEf7',
|
// user: user, //'AKIAU6GDWVAQ2QNFLNWN',
|
||||||
|
// pass: password, //'BDE9nZv/ARbpotim1mIOir52WgIbpSi9cv1oJoH8oEf7',
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// defaults: {
|
||||||
|
// from: '"No Reply" <noreply@example.com>',
|
||||||
|
// },
|
||||||
|
// template: {
|
||||||
|
// dir: join(__dirname, 'templates'),
|
||||||
|
// adapter: new HandlebarsAdapter({
|
||||||
|
// eq: function (a, b) {
|
||||||
|
// return a === b;
|
||||||
|
// },
|
||||||
|
// }),
|
||||||
|
// options: {
|
||||||
|
// strict: true,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// }),
|
||||||
|
MailerModule.forRootAsync({
|
||||||
|
useFactory: () => ({
|
||||||
|
transport: {
|
||||||
|
host: 'email-smtp.us-east-2.amazonaws.com',
|
||||||
|
secure: false,
|
||||||
|
port: 587,
|
||||||
|
auth: {
|
||||||
|
user: process.env.AMAZON_USER, //'AKIAU6GDWVAQ2QNFLNWN',
|
||||||
|
pass: process.env.AMAZON_PASSWORD, //'BDE9nZv/ARbpotim1mIOir52WgIbpSi9cv1oJoH8oEf7',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
defaults: {
|
||||||
defaults: {
|
from: '"No Reply" <noreply@example.com>',
|
||||||
from: '"No Reply" <noreply@example.com>',
|
|
||||||
},
|
|
||||||
template: {
|
|
||||||
dir: join(__dirname, 'templates'),
|
|
||||||
adapter: new HandlebarsAdapter(), // or new PugAdapter() or new EjsAdapter()
|
|
||||||
options: {
|
|
||||||
strict: true,
|
|
||||||
},
|
},
|
||||||
},
|
template: {
|
||||||
|
dir: join(__dirname, 'templates'),
|
||||||
|
adapter: new HandlebarsAdapter({
|
||||||
|
eq: function (a, b) {
|
||||||
|
return a === b;
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
options: {
|
||||||
|
strict: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
providers: [MailService, UserService, FileService, GeoService],
|
providers: [MailService, UserService, FileService, GeoService],
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ export class MailService {
|
||||||
}
|
}
|
||||||
async sendSubscriptionConfirmation(user: User): Promise<void> {
|
async sendSubscriptionConfirmation(user: User): Promise<void> {
|
||||||
await this.mailerService.sendMail({
|
await this.mailerService.sendMail({
|
||||||
to: 'support@bizmatch.net',
|
to: user.email,
|
||||||
from: `"Bizmatch Support Team" <info@bizmatch.net>`,
|
from: `"Bizmatch Support Team" <info@bizmatch.net>`,
|
||||||
subject: `Subscription Confirmation`,
|
subject: `Subscription Confirmation`,
|
||||||
//template: './inquiry', // `.hbs` extension is appended automatically
|
//template: './inquiry', // `.hbs` extension is appended automatically
|
||||||
|
|
|
||||||
|
|
@ -17,18 +17,18 @@ export interface UserData {
|
||||||
hasCompanyLogo?: boolean;
|
hasCompanyLogo?: boolean;
|
||||||
licensedIn?: string[];
|
licensedIn?: string[];
|
||||||
gender?: 'male' | 'female';
|
gender?: 'male' | 'female';
|
||||||
customerType?: 'buyer' | 'broker' | 'professional';
|
customerType?: 'buyer' | 'seller' | 'professional';
|
||||||
customerSubType?: 'broker' | 'cpa' | 'attorney' | 'titleCompany' | 'surveyor' | 'appraiser';
|
customerSubType?: 'broker' | 'cpa' | 'attorney' | 'titleCompany' | 'surveyor' | 'appraiser';
|
||||||
created?: Date;
|
created?: Date;
|
||||||
updated?: Date;
|
updated?: Date;
|
||||||
}
|
}
|
||||||
export type Gender = 'male' | 'female';
|
export type Gender = 'male' | 'female';
|
||||||
export type CustomerType = 'buyer' | 'professional';
|
export type CustomerType = 'buyer' | 'seller' | 'professional';
|
||||||
export type CustomerSubType = 'broker' | 'cpa' | 'attorney' | 'titleCompany' | 'surveyor' | 'appraiser';
|
export type CustomerSubType = 'broker' | 'cpa' | 'attorney' | 'titleCompany' | 'surveyor' | 'appraiser';
|
||||||
export type ListingsCategory = 'commercialProperty' | 'business';
|
export type ListingsCategory = 'commercialProperty' | 'business';
|
||||||
|
|
||||||
export const GenderEnum = z.enum(['male', 'female']);
|
export const GenderEnum = z.enum(['male', 'female']);
|
||||||
export const CustomerTypeEnum = z.enum(['buyer', 'professional']);
|
export const CustomerTypeEnum = z.enum(['buyer', 'seller', 'professional']);
|
||||||
export const SubscriptionTypeEnum = z.enum(['free', 'professional', 'broker']);
|
export const SubscriptionTypeEnum = z.enum(['free', 'professional', 'broker']);
|
||||||
export const CustomerSubTypeEnum = z.enum(['broker', 'cpa', 'attorney', 'titleCompany', 'surveyor', 'appraiser']);
|
export const CustomerSubTypeEnum = z.enum(['broker', 'cpa', 'attorney', 'titleCompany', 'surveyor', 'appraiser']);
|
||||||
export const ListingsCategoryEnum = z.enum(['commercialProperty', 'business']);
|
export const ListingsCategoryEnum = z.enum(['commercialProperty', 'business']);
|
||||||
|
|
|
||||||
|
|
@ -58,23 +58,19 @@ export class PaymentService {
|
||||||
quantity: 1,
|
quantity: 1,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
success_url: 'http://localhost:4200/success',
|
success_url: `${process.env.WEB_HOST}/success`,
|
||||||
cancel_url: 'http://localhost:4200/pricing',
|
cancel_url: `${process.env.WEB_HOST}/pricing`,
|
||||||
// customer_email: checkout.email,
|
// customer_email: checkout.email,
|
||||||
customer: customerId,
|
customer: customerId,
|
||||||
// customer_details:{
|
|
||||||
// name: checkout.name, // Hier wird der Name des Kunden übergeben
|
|
||||||
// },
|
|
||||||
shipping_address_collection: {
|
shipping_address_collection: {
|
||||||
allowed_countries: ['US'],
|
allowed_countries: ['US'],
|
||||||
},
|
},
|
||||||
|
client_reference_id: btoa(checkout.name),
|
||||||
client_reference_id: '1234',
|
|
||||||
locale: 'en',
|
locale: 'en',
|
||||||
subscription_data: {
|
subscription_data: {
|
||||||
trial_end: Math.floor(new Date().setMonth(new Date().getMonth() + 3) / 1000),
|
trial_end: Math.floor(new Date().setMonth(new Date().getMonth() + 3) / 1000),
|
||||||
|
metadata: { plan: product.name },
|
||||||
},
|
},
|
||||||
metadata: { plan: product.name },
|
|
||||||
});
|
});
|
||||||
return session;
|
return session;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -100,20 +96,11 @@ export class PaymentService {
|
||||||
});
|
});
|
||||||
user.stripeCustomerId = session.customer as string;
|
user.stripeCustomerId = session.customer as string;
|
||||||
user.subscriptionId = session.subscription as string;
|
user.subscriptionId = session.subscription as string;
|
||||||
user.planActive = true;
|
user.customerType = 'professional';
|
||||||
//session.shipping_details ->
|
if (session.metadata['plan'] === 'Broker Plan') {
|
||||||
// "shipping_details": {
|
user.customerSubType = 'broker';
|
||||||
// "address": {
|
}
|
||||||
// "city": "Springfield",
|
user.subscriptionPlan = session.metadata['plan'] === 'Broker Plan' ? 'broker' : 'professional'; //session.metadata['subscriptionPlan'] as 'free' | 'professional' | 'broker';
|
||||||
// "country": "US",
|
|
||||||
// "line1": "West Maple Avenue South",
|
|
||||||
// "line2": null,
|
|
||||||
// "postal_code": "62704",
|
|
||||||
// "state": "IL"
|
|
||||||
// },
|
|
||||||
// "name": "Johnathan Miller"
|
|
||||||
// }
|
|
||||||
user.subscriptionPlan = session.amount_total === 4900 ? 'broker' : 'professional'; //session.metadata['subscriptionPlan'] as 'free' | 'professional' | 'broker';
|
|
||||||
this.userService.saveUser(user);
|
this.userService.saveUser(user);
|
||||||
this.mailService.sendSubscriptionConfirmation(user);
|
this.mailService.sendSubscriptionConfirmation(user);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ export class SelectOptionsService {
|
||||||
];
|
];
|
||||||
public customerTypes: Array<KeyValue> = [
|
public customerTypes: Array<KeyValue> = [
|
||||||
{ name: 'Buyer', value: 'buyer' },
|
{ name: 'Buyer', value: 'buyer' },
|
||||||
|
{ name: 'Commercial Property Seller', value: 'seller' },
|
||||||
{ name: 'Professional', value: 'professional' },
|
{ name: 'Professional', value: 'professional' },
|
||||||
];
|
];
|
||||||
public customerSubTypes: Array<KeyValue> = [
|
public customerSubTypes: Array<KeyValue> = [
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,15 @@
|
||||||
<app-tooltip id="tooltip-{{ name }}" [text]="validationMessage"></app-tooltip>
|
<app-tooltip id="tooltip-{{ name }}" [text]="validationMessage"></app-tooltip>
|
||||||
}
|
}
|
||||||
</label>
|
</label>
|
||||||
<select [id]="name" [name]="name" [ngModel]="value" (change)="onSelectChange($event)" (blur)="onTouched()" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500">
|
<select
|
||||||
|
[disabled]="disabled"
|
||||||
|
[id]="name"
|
||||||
|
[name]="name"
|
||||||
|
[ngModel]="value"
|
||||||
|
(change)="onSelectChange($event)"
|
||||||
|
(blur)="onTouched()"
|
||||||
|
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500"
|
||||||
|
>
|
||||||
<option value="" disabled selected>Select an option</option>
|
<option value="" disabled selected>Select an option</option>
|
||||||
<option *ngFor="let option of options" [value]="option.value">
|
<option *ngFor="let option of options" [value]="option.value">
|
||||||
{{ option.label }}
|
{{ option.label }}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import { ValidationMessagesService } from '../validation-messages.service';
|
||||||
})
|
})
|
||||||
export class ValidatedSelectComponent extends BaseInputComponent {
|
export class ValidatedSelectComponent extends BaseInputComponent {
|
||||||
@Input() options: Array<{ value: any; label: string }> = [];
|
@Input() options: Array<{ value: any; label: string }> = [];
|
||||||
|
@Input() disabled = false;
|
||||||
@Output() valueChange = new EventEmitter<any>();
|
@Output() valueChange = new EventEmitter<any>();
|
||||||
|
|
||||||
constructor(validationMessagesService: ValidationMessagesService) {
|
constructor(validationMessagesService: ValidationMessagesService) {
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ export class PricingComponent {
|
||||||
await this.userService.save(user);
|
await this.userService.save(user);
|
||||||
this.router.navigate([`/account`]);
|
this.router.navigate([`/account`]);
|
||||||
} else {
|
} else {
|
||||||
this.checkout({ priceId: atob(this.id), email: this.keycloakUser.email, name: `${this.keycloakUser.firstName} ${this.keycloakUser.lastName}` });
|
this.checkout({ priceId: priceId, email: this.keycloakUser.email, name: `${this.keycloakUser.firstName} ${this.keycloakUser.lastName}` });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (priceId) {
|
if (priceId) {
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
}@else{
|
}@else{
|
||||||
<app-validated-select label="Customer Type" name="customerType" [(ngModel)]="user.customerType" [options]="customerTypeOptions"></app-validated-select>
|
<app-validated-select [disabled]="user.customerType === 'professional'" label="Customer Type" name="customerType" [(ngModel)]="user.customerType" [options]="customerTypeOptions"></app-validated-select>
|
||||||
} @if (isProfessional){
|
} @if (isProfessional){
|
||||||
<!-- <div>
|
<!-- <div>
|
||||||
<label for="customerSubType" class="block text-sm font-medium text-gray-700">Professional Type</label>
|
<label for="customerSubType" class="block text-sm font-medium text-gray-700">Professional Type</label>
|
||||||
|
|
@ -86,7 +86,7 @@
|
||||||
<option *ngFor="let subType of customerSubTypes" [value]="subType">{{ subType | titlecase }}</option>
|
<option *ngFor="let subType of customerSubTypes" [value]="subType">{{ subType | titlecase }}</option>
|
||||||
</select>
|
</select>
|
||||||
</div> -->
|
</div> -->
|
||||||
<app-validated-select label="Professional Type" name="customerSubType" [(ngModel)]="user.customerSubType" [options]="customerSubTypeOptions"></app-validated-select>
|
<app-validated-select [disabled]="user.customerSubType === 'broker'" label="Professional Type" name="customerSubType" [(ngModel)]="user.customerSubType" [options]="customerSubTypeOptions"></app-validated-select>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@if (isProfessional){
|
@if (isProfessional){
|
||||||
|
|
@ -246,39 +246,39 @@
|
||||||
<div class="flex justify-start">
|
<div class="flex justify-start">
|
||||||
<button routerLink="/pricing" class="px-4 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">Upgrade Subscription Plan</button>
|
<button routerLink="/pricing" class="px-4 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">Upgrade Subscription Plan</button>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="mt-8 sm:hidden">
|
<div class="mt-8 sm:hidden">
|
||||||
<h3 class="text-lg font-medium text-gray-700 mb-1">Membership Level</h3>
|
<h3 class="text-lg font-medium text-gray-700 mb-1">Membership Level</h3>
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
@for (subscription of userSubscriptions; track userSubscriptions){
|
@for (subscription of subscriptions; track subscriptions; let i=$index){
|
||||||
<div class="bg-white shadow overflow-hidden sm:rounded-lg">
|
<div class="bg-white shadow overflow-hidden sm:rounded-lg">
|
||||||
<div class="px-4 py-5 sm:px-6">
|
<div class="px-4 py-5 sm:px-6">
|
||||||
<dl class="grid grid-cols-1 gap-x-4 gap-y-2 sm:grid-cols-2">
|
<dl class="grid grid-cols-1 gap-x-4 gap-y-2 sm:grid-cols-2">
|
||||||
<div class="sm:col-span-1 flex">
|
<div class="sm:col-span-1 flex">
|
||||||
<dt class="text-sm font-bold text-gray-500 mr-2">Level</dt>
|
<dt class="text-sm font-bold text-gray-500 mr-2">Level</dt>
|
||||||
<dd class="text-sm text-gray-900">{{ level }}</dd>
|
<dd class="text-sm text-gray-900">{{ getLevel(i) }}</dd>
|
||||||
</div>
|
</div>
|
||||||
<div class="sm:col-span-1 flex">
|
<div class="sm:col-span-1 flex">
|
||||||
<dt class="text-sm font-bold text-gray-500 mr-2">Start Date</dt>
|
<dt class="text-sm font-bold text-gray-500 mr-2">Start Date</dt>
|
||||||
<dd class="text-sm text-gray-900">{{ subscription.start | date }}</dd>
|
<dd class="text-sm text-gray-900">{{ getStartDate(i) }}</dd>
|
||||||
</div>
|
|
||||||
<div class="sm:col-span-1 flex">
|
|
||||||
<dt class="text-sm font-bold text-gray-500 mr-2">Date Modified</dt>
|
|
||||||
<dd class="text-sm text-gray-900">{{ subscription.modified | date }}</dd>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="sm:col-span-1 flex">
|
<div class="sm:col-span-1 flex">
|
||||||
<dt class="text-sm font-bold text-gray-500 mr-2">End Date</dt>
|
<dt class="text-sm font-bold text-gray-500 mr-2">End Date</dt>
|
||||||
<dd class="text-sm text-gray-900">{{ subscription.end | date }}</dd>
|
<dd class="text-sm text-gray-900">{{ getEndDate(i) }}</dd>
|
||||||
|
</div>
|
||||||
|
<div class="sm:col-span-1 flex">
|
||||||
|
<dt class="text-sm font-bold text-gray-500 mr-2">Next Settlement</dt>
|
||||||
|
<dd class="text-sm text-gray-900">{{ getNextSettlement(i) }}</dd>
|
||||||
</div>
|
</div>
|
||||||
<div class="sm:col-span-1 flex">
|
<div class="sm:col-span-1 flex">
|
||||||
<dt class="text-sm font-bold text-gray-500 mr-2">Status</dt>
|
<dt class="text-sm font-bold text-gray-500 mr-2">Status</dt>
|
||||||
<dd class="text-sm text-gray-900">{{ subscription.status }}</dd>
|
<dd class="text-sm text-gray-900">{{ getStatus(i) }}</dd>
|
||||||
</div>
|
</div>
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div> -->
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -67,8 +67,6 @@ export class AccountComponent {
|
||||||
editorModules = TOOLBAR_OPTIONS;
|
editorModules = TOOLBAR_OPTIONS;
|
||||||
env = environment;
|
env = environment;
|
||||||
faTrash = faTrash;
|
faTrash = faTrash;
|
||||||
customerTypes = ['buyer', 'professional'];
|
|
||||||
customerSubTypes = ['broker', 'cpa', 'attorney', 'titleCompany', 'surveyor', 'appraiser'];
|
|
||||||
quillModules = {
|
quillModules = {
|
||||||
toolbar: [['bold', 'italic', 'underline', 'strike'], [{ list: 'ordered' }, { list: 'bullet' }], [{ header: [1, 2, 3, 4, 5, 6, false] }], [{ color: [] }, { background: [] }], ['clean']],
|
toolbar: [['bold', 'italic', 'underline', 'strike'], [{ list: 'ordered' }, { list: 'bullet' }], [{ header: [1, 2, 3, 4, 5, 6, false] }], [{ color: [] }, { background: [] }], ['clean']],
|
||||||
};
|
};
|
||||||
|
|
@ -116,15 +114,19 @@ export class AccountComponent {
|
||||||
this.profileUrl = this.user.hasProfile ? `${this.env.imageBaseUrl}/pictures/profile/${emailToDirName(this.user.email)}.avif?_ts=${new Date().getTime()}` : `/assets/images/placeholder.png`;
|
this.profileUrl = this.user.hasProfile ? `${this.env.imageBaseUrl}/pictures/profile/${emailToDirName(this.user.email)}.avif?_ts=${new Date().getTime()}` : `/assets/images/placeholder.png`;
|
||||||
this.companyLogoUrl = this.user.hasCompanyLogo ? `${this.env.imageBaseUrl}/pictures/logo/${emailToDirName(this.user.email)}.avif?_ts=${new Date().getTime()}` : `/assets/images/placeholder.png`;
|
this.companyLogoUrl = this.user.hasCompanyLogo ? `${this.env.imageBaseUrl}/pictures/logo/${emailToDirName(this.user.email)}.avif?_ts=${new Date().getTime()}` : `/assets/images/placeholder.png`;
|
||||||
|
|
||||||
this.customerTypeOptions = this.customerTypes.map(type => ({
|
this.customerTypeOptions = this.selectOptions.customerTypes
|
||||||
value: type,
|
.filter(ct => ct.value === 'buyer' || ct.value === 'seller' || this.user.customerType === 'professional')
|
||||||
label: this.titleCasePipe.transform(type),
|
.map(type => ({
|
||||||
}));
|
value: type.value,
|
||||||
|
label: this.titleCasePipe.transform(type.name),
|
||||||
|
}));
|
||||||
|
|
||||||
this.customerSubTypeOptions = this.customerSubTypes.map(type => ({
|
this.customerSubTypeOptions = this.selectOptions.customerSubTypes
|
||||||
value: type,
|
.filter(ct => ct.value !== 'broker' || this.user.customerSubType === 'broker')
|
||||||
label: this.titleCasePipe.transform(type),
|
.map(type => ({
|
||||||
}));
|
value: type.value,
|
||||||
|
label: this.titleCasePipe.transform(type.name),
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
this.validationMessagesService.clearMessages(); // Löschen Sie alle bestehenden Validierungsnachrichten
|
this.validationMessagesService.clearMessages(); // Löschen Sie alle bestehenden Validierungsnachrichten
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ export class SuccessComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
let attempts = 0;
|
let attempts = 0;
|
||||||
const maxAttempts = 5;
|
const maxAttempts = 20;
|
||||||
const interval = 5000; // 5 Sekunden
|
const interval = 5000; // 5 Sekunden
|
||||||
|
|
||||||
const intervalId = setInterval(async () => {
|
const intervalId = setInterval(async () => {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue