Last active
October 3, 2016 23:27
-
-
Save akestner/4432b59bfe5a6b8512e8a41807b3e074 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"), | |
]; | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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