Skip to content

Instantly share code, notes, and snippets.

@akestner
Last active October 3, 2016 23:27
Show Gist options
  • Save akestner/4432b59bfe5a6b8512e8a41807b3e074 to your computer and use it in GitHub Desktop.
Save akestner/4432b59bfe5a6b8512e8a41807b3e074 to your computer and use it in GitHub Desktop.
import {observable} from 'mobx';
import {computed} from 'mobx';
import {
Day, IncludableItem, IncludedItem, ActivityType, Activity
} from "./models";
// TODO: inject these?
import {nullIncludableItem, nullIncludedItem} from "./defaults";
interface AppStateInterface {
adults: number;
children: number;
hours: number;
days: Day[];
includableItems: IncludableItem[];
activityTypes: ActivityType[];
activities: Activity[];
selectedActivity: Activity;
}
interface AppStateConstructor {
new(
includableItems: IncludableItem[],
activityTypes: ActivityType[],
activities: Activity[],
days: Day[]
): AppStateInterface;
}
export default class AppState implements AppStateInterface {
constructor(
includableItems: IncludableItem[],
activityTypes: ActivityType[],
activities: Activity[],
days: Day[]
) {
this.includableItems = includableItems;
this.activityTypes = activityTypes;
this.activities = activities;
this.days = days;
this.selectedActivity = this.activities[0];
}
nullIncludedItem:IncludedItem = nullIncludedItem;
nullIncludableItem:IncludableItem = nullIncludableItem;
@observable adults:number = 1;
@observable minAdults:number = 1;
@observable maxAdults:number = 8;
@observable children:number = 1;
@observable minChildren:number = 0;
@observable maxChildren:number = 15;
@observable hours:number = 1;
@observable days:Day[];
@observable includableItems:IncludableItem[];
@observable activityTypes:ActivityType[];
@observable activities:Activity[];
@observable selectedActivity: Activity;
@computed get subTotal() {
return this.selectedActivity.base_price + this.itemSubTotal;
}
@computed get itemSubTotal() {
let result = 0;
this.includableItems.forEach((item) => {
const excess = this.excessFor(item.id);
let includableItem = this.includableItemById(item.id);
if (excess.count > -1) {
result += excess.count * includableItem.price_per_extra;
}
});
return result;
}
chooseActivityAt(index) {
this.selectedActivity = this.activities[index];
}
lessItemsDesired(itemId) {
let includedItem = this.includedItemById(itemId);
let includableItem = this.includableItemById(itemId);
if (includableItem.desired_count < 0) {
includableItem.desired_count = includedItem.count;
}
if (includableItem.desired_count > includableItem.minimum) {
includableItem.desired_count--;
}
}
moreItemsDesired(itemId) {
let includedItem = this.includedItemById(itemId);
let includableItem = this.includableItemById(itemId);
if (includableItem.desired_count < 0) {
includableItem.desired_count = includedItem.count;
}
if (includableItem.desired_count < includableItem.maximum) {
includableItem.desired_count++;
}
}
finalCountFor(itemId) {
let result = this.includedItemById(itemId).count;
const includableItem = this.includableItemById(itemId);
if (includableItem.desired_count > -1) {
result = includableItem.desired_count
}
return result;
}
excessFor(itemId) {
const desiredCount = this.includableItemById(itemId).desired_count;
const count = this.includedItemById(itemId).count;
let result = {
text: "_",
className: "",
count: 0,
};
if (desiredCount > -1) {
const remaining = desiredCount - count;
if (remaining > 0) {
result = {
text: "+ " + remaining.toString() + " extra",
className: "over",
count: remaining,
}
} else if (remaining < 0) {
result = {
text: "+ " + Math.abs(remaining).toString() + " included",
className: "under",
count: remaining,
}
}
}
return result;
}
includedItemById(id) {
const index = this.includedItemIndexById(id);
if (index > -1) {
return this.selectedActivity.included_items[index];
} else {
return this.nullIncludedItem;
}
}
includedItemIndexById(id) {
let result = -1;
this.selectedActivity.included_items.forEach((item, index) => {
if (item.id == id) {
result = index;
}
});
return result;
}
includableItemById(id) {
const index = this.includableItemIndexById(id);
if (index > -1) {
return this.includableItems[index];
} else {
return this.nullIncludableItem;
}
}
includableItemIndexById(id) {
let result = -1;
this.includableItems.forEach((item, index) => {
if (item.id == id) {
result = index;
}
});
return result;
}
}
import {
ActivityType, IncludableItem, IncludedItem, Activity,
Day, Year, Month, Timeslot
} from "./models";
export var includableItems = [
new IncludableItem(1, "Adults", 10, 0, -1),
new IncludableItem(2, "Children", 10, 0, -1),
new IncludableItem(3, "Hours", 2, 1, -1, 3.5),
new IncludableItem(4, "Pizza", 10, 0, -1, 3.5),
new IncludableItem(5, "Pepsi", 10, 0, -1, 10),
];
export var nullIncludedItem = new IncludedItem(0, 0, 0);
export var nullIncludableItem = new IncludableItem(0, "", 0, 10, 0, -1);
export var activities = [
new Activity(
"Gold Package",
"Get carried away with this deluxe offering from our lorem " +
"ipsum etcetera, I don't have the internet so I can't get some proper" +
" text right now but I think you get the feel for it, right?",
100,
true,
[
new IncludedItem(1, 4, 10),
new IncludedItem(2, 2, 10),
new IncludedItem(3, 1, 10),
new IncludedItem(4, 4, 10),
new IncludedItem(5, 4, 10),
]
),
new Activity(
"Silver Package",
"The silver package is perfect for all the tiny babies out" +
" there in the world and it includes hell of chill stuff like party hats" +
" for your little tootsie roll!",
50,
true,
[
new IncludedItem(1, 1, 10),
new IncludedItem(2, 4, 10),
new IncludedItem(3, 1, 10),
]
)
];
var current_year = new Year(new Date().getFullYear());
var september = new Month(9, "September", current_year);
var timeslots = [
new Timeslot("8am", 70, true),
new Timeslot("9am", 70, false)
];
export var days = [
new Day(12, "Wednesday", september, false, timeslots),
new Day(13, "Thursday", september, true, timeslots),
new Day(14, "Friday", september, false, timeslots),
];
export var activityTypes = [
new ActivityType(1, "Bowling", "It's fun"),
new ActivityType(2, "Roller Skating", "Weeee"),
];
interface Identifiable {
id: number;
}
interface Nameable {
name: string;
}
interface Describable {
description: string;
}
export interface IncludableItemInterface extends Identifiable, Nameable {
maximum: number;
minimum: number;
desired_count: number;
price_per_extra: number;
}
interface IncludableItemConstructor {
new(
id: number,
name: string,
maximum: number,
minimum: number,
desired_count: number,
price_per_extra?: number
): IncludableItemInterface;
}
export interface IncludedItemInterface extends Identifiable {
count: number;
price_per_extra: number;
}
interface IncludedItemConstructor {
new(
id: number,
count: number,
price_per_extra: number
): IncludedItemInterface;
}
export interface ActivityTypeInterface extends Identifiable, Nameable, Describable { }
interface ActivityTypeConstructor {
new(
id: number,
name: string,
description: string
): ActivityTypeInterface;
}
export interface ActivityInterface extends Nameable, Describable {
base_price: number;
is_real: boolean;
}
interface ActivityConstructor {
new(
name: string,
description: string,
base_price: number,
is_real: boolean,
included_items: IncludableItemInterface[]
): ActivityInterface;
}
export interface TimeslotInterface extends Nameable {
available: boolean;
base_price: number;
}
interface TimeslotConstructor {
new(
name: string,
base_price: number,
available: boolean
): TimeslotInterface;
}
export interface YearInterface {
number: number;
}
interface YearConstructor {
new(number: number): YearInterface;
}
export interface MonthInterface extends Nameable {
number: number;
year: YearInterface;
}
interface MonthConstructor {
new(
number: number,
name: string,
year: YearInterface
): MonthInterface;
}
export interface DayInterface extends Nameable {
number: number;
month: MonthInterface;
requested: boolean;
timeslots: TimeslotInterface[];
}
interface DayConstructor {
new(
number: number,
name: string,
month: MonthInterface,
requested: boolean,
timeslots: TimeslotInterface[]
): DayInterface;
}
import {
ActivityTypeInterface, ActivityInterface, IncludableItemInterface,
IncludedItemInterface, TimeslotInterface, YearInterface, MonthInterface,
DayInterface
} from './interfaces';
export class IncludableItem implements IncludableItemInterface {
id: number;
name: string;
maximum: number;
minimum: number;
desired_count: number;
price_per_extra: number;
constructor(
id: number,
title: string,
maximum: number,
minimum: number,
desired_count: number,
price_per_extra?: number
) {
this.id = id;
this.name = title;
this.maximum = maximum;
this.minimum = minimum;
this.desired_count = desired_count;
this.price_per_extra = price_per_extra;
}
}
export class IncludedItem implements IncludedItemInterface {
id: number;
count: number;
price_per_extra: number;
constructor(id: number, count: number, price_per_extra: number) {
this.id = id;
this.count = count;
this.price_per_extra = price_per_extra;
}
}
export class ActivityType implements ActivityTypeInterface {
id: number;
name: string;
description: string;
constructor(id: number, name: string, description: string) {
this.id = id;
this.name = name;
this.description = description;
}
}
export class Activity implements ActivityInterface {
base_price: number;
description: string;
name: string;
is_real: boolean;
included_items: IncludedItem[];
constructor(
name: string,
description: string,
base_price: number,
is_real: boolean,
included_items: IncludedItem[]
) {
this.base_price = base_price;
this.description = description;
this.name = name;
this.is_real = is_real;
this.included_items = included_items;
}
}
export class Timeslot implements TimeslotInterface {
name: string;
available: boolean;
base_price: number;
constructor(name: string, base_price: number, available: boolean) {
this.name = name;
this.base_price = base_price;
this.available = available;
}
}
export class Year implements YearInterface {
number: number;
constructor(number: number) {
this.number = number;
}
}
export class Month implements MonthInterface {
number: number;
name: string;
year: YearInterface;
constructor(number: number, name: string, year: Year) {
this.number = number;
this.name = name;
this.year = year;
}
}
export class Day implements DayInterface {
number: number;
name: string;
month: MonthInterface;
requested: boolean;
timeslots: Timeslot[];
constructor(
number: number,
name: string,
month: Month,
requested: boolean,
timeslots: Timeslot[]
) {
this.number = number;
this.name = name;
this.month = month;
this.requested = requested;
this.timeslots = timeslots;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment