Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kuwait Theme: Activity Check-in component #2562

Merged
merged 45 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
159645c
init: check-in component
FaithDaka Nov 26, 2024
07bcafb
feat: functionality
FaithDaka Nov 26, 2024
ee4368c
feat: progress tracking
FaithDaka Nov 26, 2024
9e14a60
component styling
FaithDaka Nov 26, 2024
9dd342b
rtl config
FaithDaka Nov 26, 2024
f28ac57
language
FaithDaka Nov 26, 2024
4956ce9
Merge branch 'master' into feature-kw-check-in-component
esmeetewinkel Nov 27, 2024
3270e63
feat: use sheets param for countdown
FaithDaka Nov 27, 2024
5bf2187
style: unlocked image asset
FaithDaka Nov 27, 2024
cb938ff
Merge branch 'feature-kw-check-in-component' of https://github.com/ID…
FaithDaka Nov 27, 2024
2ddffcd
set progress percentage to 16 as the default
FaithDaka Nov 27, 2024
c250894
Merge branch 'master' of https://github.com/IDEMSInternational/open-a…
FaithDaka Nov 28, 2024
3ee0a20
Merge branch 'master' of https://github.com/IDEMSInternational/open-a…
FaithDaka Nov 28, 2024
6f3d529
Merge branch 'master' of https://github.com/IDEMSInternational/open-a…
FaithDaka Dec 2, 2024
d001f8c
Merge branch 'master' of https://github.com/IDEMSInternational/open-a…
FaithDaka Dec 4, 2024
88254d3
add click event
FaithDaka Dec 4, 2024
a247343
Merge branch 'master' into feature-kw-check-in-component
esmeetewinkel Dec 4, 2024
d8d5b7d
Merge branch 'master' into feature-kw-check-in-component
jfmcquade Dec 11, 2024
53702cc
feat: add countdown logic to plh-activity-check-in component
jfmcquade Dec 11, 2024
975b091
refactor: use signals
jfmcquade Dec 11, 2024
f9d57e1
chore: finish signals integration
jfmcquade Dec 12, 2024
e0824a2
chore: tidy html and css
jfmcquade Dec 12, 2024
1c9e805
chore: move styling to component stylesheet
jfmcquade Dec 12, 2024
032eee8
fix: countdown logic
jfmcquade Dec 12, 2024
a4533c1
chore: remove unused param
jfmcquade Dec 12, 2024
76e9687
chore: fix progres bar styling on default theme
jfmcquade Dec 12, 2024
8376129
Merge branch 'master' into feature-kw-check-in-component
esmeetewinkel Dec 16, 2024
3feac89
Merge branch 'master' into feature-kw-check-in-component
esmeetewinkel Dec 17, 2024
1ae460d
Merge branch 'feature-kw-check-in-component' of https://github.com/ID…
FaithDaka Dec 18, 2024
64e8d5c
feat: max height for images and rtl support
FaithDaka Dec 18, 2024
20bdbe8
Merge branch 'master' into feature-kw-check-in-component
esmeetewinkel Dec 19, 2024
3e35c87
Merge branch 'master' into feature-kw-check-in-component
esmeetewinkel Dec 20, 2024
d1c019b
Merge branch 'master' into feature-kw-check-in-component
esmeetewinkel Dec 20, 2024
82f8d01
Merge branch 'master' into feature-kw-check-in-component
esmeetewinkel Dec 21, 2024
ec7bd1a
chore: activity should be locked when now countdown start date is pro…
jfmcquade Dec 23, 2024
0544020
Merge branch 'master' into feature-kw-check-in-component
jfmcquade Dec 23, 2024
9d7d98e
Merge branch 'master' into feature-kw-check-in-component
esmeetewinkel Dec 30, 2024
a244d07
Merge branch 'master' into feature-kw-check-in-component
esmeetewinkel Dec 31, 2024
38101f7
Merge branch 'master' into feature-kw-check-in-component
esmeetewinkel Dec 31, 2024
69411aa
Merge branch 'master' into feature-kw-check-in-component
esmeetewinkel Jan 2, 2025
1f02c83
fix: handle undefined countdown_start_date input
jfmcquade Jan 2, 2025
c7e2043
style: fix activity check-in component styling
jfmcquade Jan 2, 2025
a6a4437
Merge branch 'master' into feature-kw-check-in-component
esmeetewinkel Jan 2, 2025
2360e17
Merge branch 'master' into feature-kw-check-in-component
esmeetewinkel Jan 2, 2025
2f7d62f
Merge branch 'master' of https://github.com/IDEMSInternational/open-a…
FaithDaka Jan 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion packages/components/plh/index.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
import { PlhParentPointCounterComponent } from "./parent-point-counter/parent-point-counter.component";
import { PlhParentPointBoxComponent } from "./parent-point-box/parent-point-box.component";
import { PlhModuleListItemComponent } from "./plh-kids-kw/components/module-list-item/module-list-item.component";
import { PlhActivityCheckInComponent } from "./plh-kids-kw/components/activity-check-in/activity-check-in.component";

export { PlhParentPointCounterComponent, PlhParentPointBoxComponent, PlhModuleListItemComponent };
export {
PlhParentPointCounterComponent,
PlhParentPointBoxComponent,
PlhModuleListItemComponent,
PlhActivityCheckInComponent,
};

export const PLH_COMPONENTS = [
PlhParentPointCounterComponent,
PlhParentPointBoxComponent,
PlhModuleListItemComponent,
PlhActivityCheckInComponent,
];

export const PLH_COMPONENT_MAPPING = {
parent_point_counter: PlhParentPointCounterComponent,
parent_point_box: PlhParentPointBoxComponent,
plh_module_list_item: PlhModuleListItemComponent,
plh_activity_check_in: PlhActivityCheckInComponent,
};

export type PLHComponentName = keyof typeof PLH_COMPONENT_MAPPING;
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
@if (daysLeft >= 1) {
<div
class="activity-container"
[attr.data-language-direction]="templateTranslateService.languageDirection()"
>
<div class="wrapper">
<div class="progress-tracker">
<div class="wrapper">
<div class="progress-bar-container">
<div
class="progress-bar"
[ngStyle]="{
width: progressPercentage + '%'
}"
></div>
</div>
</div>
<div class="countdown-text">In {{ daysLeft }} day{{ daysLeft > 1 ? "s" : "" }}</div>
</div>

<div class="image">
<img [src]="params.lockedImageAsset | plhAsset" />
</div>
<div class="details">
<div class="title">
<h4>{{ params.title }}</h4>
</div>
<div class="icon">
<img [src]="params.lockedIconAsset | plhAsset" />
</div>
</div>
</div>
</div>
} @else {
<div class="activity-container">
<div class="wrapper">
<div class="image">
<img [src]="params.unlockedImageAsset | plhAsset" />
</div>
<div class="details">
<div class="title">
<h4>{{ params.title }}</h4>
</div>
<div class="icon">
<img [src]="params.unlockedIconAsset | plhAsset" />
</div>
</div>
</div>
</div>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing";
import { IonicModule } from "@ionic/angular";

import { PlhActivityCheckInComponent } from "./activity-check-in.component";

describe("ActivityCheckInComponent", () => {
let component: PlhActivityCheckInComponent;
let fixture: ComponentFixture<PlhActivityCheckInComponent>;

beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [PlhActivityCheckInComponent],
imports: [IonicModule.forRoot()],
}).compileComponents();

fixture = TestBed.createComponent(PlhActivityCheckInComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));

it("should create", () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { Component, OnInit } from "@angular/core";
import { TemplateBaseComponent } from "src/app/shared/components/template/components/base";
import { TemplateTranslateService } from "src/app/shared/components/template/services/template-translate.service";
import { getStringParamFromTemplateRow } from "src/app/shared/utils";

interface IActivityCheckInParams {
id: string;
/* TEMPLATE PARAMETER: "title". The title attached at the bottom of the component */
title?: string;
/* TEMPLATE PARAMETER: "locked_icon_asset". The icon that shows when the activity is locked */
lockedIconAsset?: string;
/* TEMPLATE PARAMETER: "locked_image_asset". The illustration that shows when the activity is locked */
lockedImageAsset?: string;
/* TEMPLATE PARAMETER: "unlocked_icon_asset". The icon that shows when the activity is unlocked */
unlockedIconAsset?: string;
/* TEMPLATE PARAMETER: "unlocked_image_asset". The illustration that shows when the activity is locked */
unlockedImageAsset?: string;
}

@Component({
selector: "plh-activity-check-in",
templateUrl: "./activity-check-in.component.html",
styleUrls: ["./activity-check-in.component.scss"],
})
export class PlhActivityCheckInComponent extends TemplateBaseComponent implements OnInit {
params: Partial<IActivityCheckInParams> = {};

countDownDays: number = 6; // Number of days being counted down
daysLeft: number = 6; // Days until unlock
progressPercentage: number = 16; // Initial progress

private unlockDate: Date;

constructor(public templateTranslateService: TemplateTranslateService) {
super();
}

ngOnInit() {
this.getParams();
if (this._row.value) {
this.checkInTimer();
}
}

private getParams() {
this.params.id = getStringParamFromTemplateRow(this._row, "id", null);
this.params.title = getStringParamFromTemplateRow(this._row, "title", null);
this.params.lockedIconAsset = getStringParamFromTemplateRow(
this._row,
"locked_icon_asset",
null
);
this.params.lockedImageAsset = getStringParamFromTemplateRow(
this._row,
"locked_image_asset",
null
);
this.params.unlockedIconAsset = getStringParamFromTemplateRow(
this._row,
"unlocked_icon_asset",
null
);
this.params.unlockedImageAsset = getStringParamFromTemplateRow(
this._row,
"unlocked_image_asset",
null
);
}

private getLocalStorageKey(): string {
return `activity_${this.params.id}`;
}

// Calculates the days until check in
private checkInTimer() {
const localStorageKey = this.getLocalStorageKey();
const storedDate = localStorage.getItem(localStorageKey);
if (storedDate) {
this.unlockDate = new Date(storedDate);
} else {
this.unlockDate = new Date();
this.unlockDate.setDate(this.unlockDate.getDate() + this.countDownDays);
localStorage.setItem(localStorageKey, this.unlockDate.toISOString());
}
const dailyInterval = 24 * 60 * 60 * 1000; // 1 day
setInterval(() => this.updateProgress(), dailyInterval);
this.calculateUnlockDate();
}

// Calculates the exact unlock date
private calculateUnlockDate(): void {
const now = new Date();
this.unlockDate = new Date(now.getTime() + this.countDownDays * 24 * 60 * 60 * 1000);
}

// Update the progress bar and unlock state
private updateProgress(): void {
const now = new Date();
this.daysLeft = this.unlockDate.getTime() - now.getTime();

if (this.daysLeft > 0) {
this.daysLeft = Math.ceil(this.daysLeft / (24 * 60 * 60 * 1000));
this.progressPercentage = ((this.countDownDays - this.daysLeft) / this.countDownDays) * 100;
} else {
this.progressPercentage = 0;
localStorage.removeItem(this.getLocalStorageKey());
}
}
}
73 changes: 73 additions & 0 deletions src/theme/themes/plh_kids_kw/_overrides.scss
Original file line number Diff line number Diff line change
Expand Up @@ -326,4 +326,77 @@ body[data-theme="plh_kids_kw"] {
}
}
}

// activity-check-in
plh-activity-check-in {
.activity-container {
width: 45%;
.wrapper {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.progress-tracker {
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
.wrapper {
width: 46%;
}
.progress-bar-container {
background-color: var(--ion-color-gray-200);
height: 14px;
border-radius: var(--ion-border-radius-rounded);
margin-right: 8px;
overflow: hidden;
width: 100%;
}
.progress-bar {
border-radius: var(--ion-border-radius-rounded);
height: 100%;
background-color: #e0b160;
transition:
width 0.5s ease,
background-color 0.5s ease;
}
.countdown-text {
color: var(--ion-color-gray-600);
font-weight: var(--font-weight-medium);
}
}
.image {
img {
width: 140px;
}
}
.details {
display: flex;
flex-direction: row;
align-items: center;
margin-top: -5px;
.title h4 {
color: var(--ion-color-gray-600);
font-weight: var(--font-weight-bold);
}
.icon {
display: flex;
align-items: center;
img {
width: 28px;
}
}
}
}
.activity-container[data-language-direction~="rtl"] {
.progress-tracker {
.progress-bar-container {
margin-right: 0;
margin-left: 6px;
}
}
}
}
}
Loading