Skip to content

Commit

Permalink
add optional membership for mobile
Browse files Browse the repository at this point in the history
  • Loading branch information
Syrex-o committed Jan 3, 2024
1 parent 60966b5 commit de5a29e
Show file tree
Hide file tree
Showing 8 changed files with 286 additions and 84 deletions.
2 changes: 2 additions & 0 deletions libs/pages/src/lib/rights/support/support.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ <h2 class="size-d-app color-a-app no-margin">{{'PAGES.RIGHTS.SUPPORT.HEAD' | tra

<p class="size-e-app color-a-app bold">3. {{'PAGES.RIGHTS.SUPPORT.3.HEAD' | translate}}</p>
<p class="size-e-app color-b-app">{{'PAGES.RIGHTS.SUPPORT.3.1' | translate}}</p>
<p class="size-e-app color-b-app no-margin">Apple: <a target="_blank" href="https://support.apple.com/de-de/HT202039">Link</a></p>
<p class="size-e-app color-b-app no-margin">Google: <a target="_blank" href="https://support.google.com/googleplay/answer/7018481?hl=de&co=GENIE.Platform%3DAndroid&oco=1">Link</a></p>

<p class="size-e-app color-a-app bold">4. {{'PAGES.RIGHTS.SUPPORT.4.HEAD' | translate}}</p>
<p class="size-e-app color-b-app">4.1 {{'PAGES.RIGHTS.SUPPORT.4.1' | translate}}</p>
Expand Down
4 changes: 2 additions & 2 deletions libs/pages/src/lib/rights/support/support.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ import { TranslateModule } from "@ngx-translate/core";
]
})
export class RightsSupportComponent{
version = '1.0';
versionDate = 'April 2023';
version = '1.1';
versionDate = 'Januar 2024';
}
90 changes: 57 additions & 33 deletions libs/pages/src/lib/settings/support/support.page.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,42 +10,66 @@ <h2 class="page-header size-c-app color-a-app">{{'PAGES.MEMBER.HEAD' | translate
<h3 class="size-d-app color-b-app">{{'PAGES.MEMBER.INFO' | translate}}</h3>
<p class="size-e-app color-a-app mb-2-5">{{'PAGES.MEMBER.TEXT' | translate}}</p>

<button *ngIf="!showSupport" class="app-button type-a spacing-a-app bold ion-activatable w-100" (click)="showSupport = true">
{{'PAGES.MEMBER.BUTTONS.HELP' | translate}}
<ion-ripple-effect></ion-ripple-effect>
</button>
@if ((ownedItems$ | async)?.length){
<h3 class="size-d-app color-a-app center">{{'PAGES.MEMBER.ACTIVE' | translate}}:</h3>
@for (item of ownedItems$ | async; track item.id; let idx = $index){
<div class="active-membership-container mb-0-5 background-b-app">
<div class="info-container">
<p class="size-d-app color-a-app no-margin">{{item.title}}</p>
<p class="size-e-app color-b-app no-margin">{{item.description}}</p>
</div>
<div class="price-detail-container">
<p class="color-a-app size-d-app no-margin"><span class="bold">{{item.pricing?.price}}</span>/{{'PAGES.MEMBER.FREQUENCY.MONTH' | translate }}</p>
</div>
</div>
}
}
@else {
@if (availableItems$ | async; as availableItems){
<h3 class="size-d-app color-a-app center">{{'PAGES.MEMBER.CHOOSE_AMOUNT' | translate}}:</h3>
<div class="price-container background-b-app">
@if (availableItems.length){
<div class="amount-container">
@for (item of availableItems; track item.id; let idx = $index){
@if (item.canPurchase && item.pricing){
<div class="amount-select-container" [class.active]="idx === selectedItem" (click)="selectedItem = idx">
<div class="inner">
<p class="color-a-app bold size-d-app no-margin">{{item.pricing.price}}</p>
<p class="currency color-b-app no-margin">{{item.pricing.currency}}</p>
</div>
</div>
}
}
</div>
<p class="color-a-app size-f-app center spacing-a mt-0-5 mb-0-5">{{'PAGES.MEMBER.FREQUENCY.MONTHLY' | translate | uppercase}}</p>
<div class="mt-0-5 mb-1-5">
<fhem-native-switch
[(ngModel)]="termsAccepted" [showInfoBubble]="false"
[label]="''" [info]="'PAGES.MEMBER.TERMS_SWITCH' | translate">
</fhem-native-switch>

<ng-container *ngIf="showSupport">
<h3 class="size-d-app color-a-app center">{{'PAGES.MEMBER.CHOOSE_AMOUNT' | translate}}:</h3>
<div class="price-container background-b-app">
<div class="amount-container">
<ng-container *ngFor="let amount of availableAmounts">
<div class="amount-select-container" [class.active]="amount === selectedAmount" (click)="selectedAmount = amount">
<div class="inner">
<p class="color-a-app bold size-d-app no-margin">{{amount}},<span class="decimals">00</span></p>
<p class="currency color-b-app no-margin">EURO</p>
</div>
<a class="size-f-app btn-color-b-app" (click)="showGuidelines = !showGuidelines">{{'PAGES.MEMBER.LINKS.TERMS' | translate}}</a> <br>
<a class="size-f-app btn-color-b-app" target="_blank" href="https://fhemnative.de/rights/datenschutz">{{'PAGES.MEMBER.LINKS.PRIVACY' | translate}}</a>

<button class="app-button pay-btn type-a spacing-a-app bold ion-activatable w-100 mt-2-5"
[class.disabled]="!termsAccepted || !availableItems[selectedItem]"
(click)="subscribeToProduct(availableItems[selectedItem])">
<ion-icon name="lock-closed-outline"></ion-icon> {{'PAGES.MEMBER.BUTTONS.PAY' | translate}}
<ion-ripple-effect></ion-ripple-effect>
</button>
</div>
</ng-container>
}
@else{
<p class="color-a-app size-f-app center spacing-a mt-0-5 mb-0-5">{{'PAGES.MEMBER.NO_ITEMS' | translate}}</p>
}
</div>
<p class="color-a-app size-f-app center spacing-a mt-0-5 mb-0-5">{{'PAGES.MEMBER.FREQUENCY.MONTH' | translate | uppercase}}</p>
</div>

<div class="mt-0-5 mb-1-5">
<fhem-native-switch
[(ngModel)]="termsAccepted" [showInfoBubble]="false"
[label]="''" [info]="'PAGES.MEMBER.TERMS_SWITCH' | translate">
</fhem-native-switch>
<a class="size-f-app btn-color-b-app" (click)="showGuidelines = !showGuidelines">{{'PAGES.MEMBER.LINKS.TERMS' | translate}}</a>

<button class="app-button pay-btn type-a spacing-a-app bold ion-activatable w-100 mt-2-5"
[class.disabled]="!termsAccepted"
(click)="showSupport = true">
<ion-icon name="lock-closed-outline"></ion-icon> {{'PAGES.MEMBER.BUTTONS.PAY' | translate}}
<ion-ripple-effect></ion-ripple-effect>
</button>
</div>
</ng-container>
}
}
<!-- restore -->
<button class="app-button type-c spacing-a-app bold ion-activatable w-100 mt-2-5" (click)="store.restorePurchases()">
{{'PAGES.MEMBER.BUTTONS.RESTORE' | translate}}
<ion-ripple-effect></ion-ripple-effect>
</button>
</div>
</ion-content>

Expand Down
32 changes: 25 additions & 7 deletions libs/pages/src/lib/settings/support/support.page.scss
Original file line number Diff line number Diff line change
@@ -1,15 +1,36 @@
:host{
.price-container{
padding-bottom: 0.5rem;
padding: 1rem
}
.active-membership-container{
padding: .5rem;
display: flex;
gap: 1.5rem;
align-items: center;
justify-content: space-between;
.info-container{
display: flex;
flex-direction: column;
}
.price-detail-container{
display: flex;
align-items: center;
}
}
.amount-container{
display: flex;
gap: 1.5rem;
padding: 1.5rem;
flex-wrap: nowrap;
white-space: nowrap;
overflow-x: auto;
border-radius: 8px;
justify-content: center;
padding: 1.5rem .5rem;
user-select: none;
.amount-select-container:first-child{
margin-left: auto;
}
.amount-select-container:last-child{
margin-right: auto;
}
.amount-select-container{
border-radius: 12px;
border: 1px solid var(--tertiary);
Expand All @@ -18,9 +39,6 @@
transition: box-shadow .15s ease-out, transform .15s ease-out, background-color .15s ease-out;
.inner{
text-align: center;
.decimals{
font-size: 0.7rem;
}
.currency{
margin-top: 0px;
font-size: 0.7rem;
Expand Down
22 changes: 15 additions & 7 deletions libs/pages/src/lib/settings/support/support.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import { ScrollHeaderModule } from "@fhem-native/directives";

import { CloseBtnContainerModule, PickerComponent, SwitchModule } from "@fhem-native/components";

import { BackButtonService, StoreService } from "@fhem-native/services";
import { BackButtonService, Product, StoreService } from "@fhem-native/services";

import { getUID } from "@fhem-native/utils";
import { RightsSupportComponent } from "../../rights";
import { Observable, map } from "rxjs";

@Component({
standalone: true,
Expand All @@ -34,16 +35,15 @@ import { RightsSupportComponent } from "../../rights";
export class SupportPageComponent implements OnInit, OnDestroy{
private handleID = getUID();

showSupport = true;
termsAccepted = false;

selectedAmount = 3;
readonly availableAmounts = [1, 3, 5, 10];

showGuidelines = false;

selectedItem = 1;
ownedItems$: Observable<Product[]> = this.store.getProducts().pipe( map(x=> x.filter(y=> y.owned)) );
availableItems$: Observable<Product[]> = this.store.getProducts().pipe( map(x=> x.filter(y=> !y.owned)) );

constructor(
private store: StoreService,
public store: StoreService,
private navCtrl: NavController,
private backBtn: BackButtonService){
}
Expand All @@ -52,6 +52,14 @@ export class SupportPageComponent implements OnInit, OnDestroy{
this.backBtn.handle(this.handleID, ()=> this.closePage());
}

async subscribeToProduct(product: CdvPurchase.Product){
const success = await this.store.purchaseProduct(product);
if(success){
this.selectedItem = -1;
this.closePage();
}
}

closePage(): void{
this.navCtrl.back();
}
Expand Down
49 changes: 40 additions & 9 deletions libs/services/src/lib/store/products.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,46 @@
import 'cordova-plugin-purchase';
import { ProductEntry } from "./store.service";

export interface Product {
id: string,
type: CdvPurchase.ProductType,
platform: CdvPurchase.Platform
}

export const PRODUCTS: Product[] = [
export const PRODUCTS: ProductEntry[] = [
// PlayStore
{
id: 'membership_monthly_1',
type: CdvPurchase.ProductType.PAID_SUBSCRIPTION,
platform: CdvPurchase.Platform.GOOGLE_PLAY
}
},
{
id: 'membership_monthly_2',
type: CdvPurchase.ProductType.PAID_SUBSCRIPTION,
platform: CdvPurchase.Platform.GOOGLE_PLAY
},
{
id: 'membership_monthly_5',
type: CdvPurchase.ProductType.PAID_SUBSCRIPTION,
platform: CdvPurchase.Platform.GOOGLE_PLAY
},
{
id: 'membership_monthly_10',
type: CdvPurchase.ProductType.PAID_SUBSCRIPTION,
platform: CdvPurchase.Platform.GOOGLE_PLAY
},
// AppStore
{
id: 'membership_monthly_1',
type: CdvPurchase.ProductType.PAID_SUBSCRIPTION,
platform: CdvPurchase.Platform.APPLE_APPSTORE
},
{
id: 'membership_monthly_2',
type: CdvPurchase.ProductType.PAID_SUBSCRIPTION,
platform: CdvPurchase.Platform.APPLE_APPSTORE
},
{
id: 'membership_monthly_5',
type: CdvPurchase.ProductType.PAID_SUBSCRIPTION,
platform: CdvPurchase.Platform.APPLE_APPSTORE
},
{
id: 'membership_monthly_10',
type: CdvPurchase.ProductType.PAID_SUBSCRIPTION,
platform: CdvPurchase.Platform.APPLE_APPSTORE
},
];
Loading

0 comments on commit de5a29e

Please sign in to comment.