+ {anthology
+ .getAuthors()
+ .map((a) => a.name)
+ .join(', ') || 'Author Name'}
+
{isExpanded
diff --git a/apps/frontend/src/types.ts b/apps/frontend/src/types.ts
deleted file mode 100644
index 2b60a394a..000000000
--- a/apps/frontend/src/types.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-export enum AnthologyStatus {
- ARCHIVED = 'Archived',
- NOT_STARTED = 'NotStarted',
- DRAFTING = 'Drafting',
- CAN_BE_SHARED = 'CanBeShared',
-}
-
-export enum AnthologyPubLevel {
- ZINE = 'Zine',
- CHAPBOOK = 'Chapbook',
- PERFECT_BOUND = 'PerfectBound',
- SIGNATURE = 'Signature',
-}
-
-export interface Anthology {
- id: number;
- title: string;
- description: string;
- published_year: number;
- programs?: string[] | string;
- inventory?: number;
- status: AnthologyStatus;
- pub_level: AnthologyPubLevel;
- photo_url?: string;
- genre?: string;
- theme?: string;
- isbn?: string;
- shopify_url?: string;
-
- // Missing from backend
- subtitle?: string;
- byline?: string;
- praise_quotes?: string;
- foreword_author?: string;
- age_category?: string;
- dimensions?: string;
- binding_type?: string;
- page_count?: number;
- print_run?: number;
- printed_by?: string;
- number_of_students?: number;
- printing_cost?: string;
- weight?: string;
- // Inventory breakdown locations
- inventory_locations?: Record;
-}
diff --git a/apps/frontend/src/types/anthology.ts b/apps/frontend/src/types/anthology.ts
new file mode 100644
index 000000000..0cc8c4fa3
--- /dev/null
+++ b/apps/frontend/src/types/anthology.ts
@@ -0,0 +1,90 @@
+import { Author } from './author';
+import { Genre } from './genre';
+import { InventoryLocation } from './inventory-location';
+import { Theme } from './theme';
+import { Story } from './story';
+
+export enum AnthologyStatus {
+ ARCHIVED = 'Archived',
+ NOT_STARTED = 'NotStarted',
+ DRAFTING = 'Drafting',
+ CAN_BE_SHARED = 'CanBeShared',
+}
+
+export enum AnthologyPubLevel {
+ ZINE = 'Zine',
+ CHAPBOOK = 'Chapbook',
+ PERFECT_BOUND = 'PerfectBound',
+ SIGNATURE = 'Signature',
+}
+
+export class Anthology {
+ constructor(
+ public id: number,
+ public title: string,
+ public published_year: number,
+ public status: AnthologyStatus,
+ public stories?: Story[],
+ public subtitle?: string,
+ public byline?: string,
+ public description?: string,
+ public updated_at?: string,
+ public photo_url?: string,
+
+ // Additional fields from metadata
+ public foreword_author?: string,
+ public praise_quotes?: string,
+ public age_category?: string,
+ public isbn?: string,
+ public shopify_url?: string,
+ public binding_type?: string,
+ public dimensions?: string,
+ public printing_cost?: string,
+ public print_run?: number,
+ public weight?: string,
+ public page_count?: number,
+ public printed_by?: string,
+ public pub_level?: AnthologyPubLevel,
+ public publishing_permission?: string,
+ public programs?: string[],
+ public sponsors?: string[],
+ public number_of_students?: number,
+ public total_inventory?: number,
+ public inventory_locations?: InventoryLocation[],
+
+ // cached aggregated data from stories
+ private _authors?: Author[],
+ private _genres?: Genre[],
+ private _themes?: Theme[],
+ ) {}
+
+ getAuthors(): Author[] {
+ if (this._authors !== undefined) {
+ return this._authors;
+ }
+
+ const authors = this.stories?.flatMap((story) => story.authors) ?? [];
+ this._authors = authors;
+ return authors;
+ }
+
+ getGenres(): Genre[] {
+ if (this._genres !== undefined) {
+ return this._genres;
+ }
+
+ const genres = this.stories?.flatMap((story) => story.genres ?? []) ?? [];
+ this._genres = genres;
+ return genres;
+ }
+
+ getThemes(): Theme[] {
+ if (this._themes !== undefined) {
+ return this._themes;
+ }
+
+ const themes = this.stories?.flatMap((story) => story.themes ?? []) ?? [];
+ this._themes = themes;
+ return themes;
+ }
+}
diff --git a/apps/frontend/src/types/author.ts b/apps/frontend/src/types/author.ts
new file mode 100644
index 000000000..23729b3fd
--- /dev/null
+++ b/apps/frontend/src/types/author.ts
@@ -0,0 +1,6 @@
+export interface Author {
+ id: number;
+ name: string;
+ bio?: string;
+ grade?: number;
+}
diff --git a/apps/frontend/src/types/genre.ts b/apps/frontend/src/types/genre.ts
new file mode 100644
index 000000000..21d0eb3ed
--- /dev/null
+++ b/apps/frontend/src/types/genre.ts
@@ -0,0 +1,4 @@
+export interface Genre {
+ id: number;
+ name: string;
+}
diff --git a/apps/frontend/src/types/inventory-location.ts b/apps/frontend/src/types/inventory-location.ts
new file mode 100644
index 000000000..120358d88
--- /dev/null
+++ b/apps/frontend/src/types/inventory-location.ts
@@ -0,0 +1,5 @@
+export interface InventoryLocation {
+ id: number;
+ name: string;
+ num_copies: number;
+}
diff --git a/apps/frontend/src/types/library.ts b/apps/frontend/src/types/library.ts
new file mode 100644
index 000000000..f2e8941a3
--- /dev/null
+++ b/apps/frontend/src/types/library.ts
@@ -0,0 +1,122 @@
+import { Anthology, AnthologyStatus } from './anthology';
+import { Genre } from './genre';
+import { InventoryLocation } from './inventory-location';
+import { Theme } from './theme';
+
+export class Library {
+ anthologies: Anthology[];
+
+ constructor(anthologies: Anthology[]) {
+ this.anthologies = anthologies;
+ }
+
+ getById(id: number): Anthology | undefined {
+ return this.anthologies.find((anthology) => anthology.id === id);
+ }
+
+ filterByGenreId(id: number): Anthology[] {
+ const anthologies = this.anthologies.filter((anthology) =>
+ anthology.getGenres().filter((genre) => genre.id === id),
+ );
+
+ return anthologies;
+ }
+
+ filterByThemeId(id: number): Anthology[] {
+ const anthologies = this.anthologies.filter((anthology) =>
+ anthology.getThemes().filter((theme) => theme.id === id),
+ );
+
+ return anthologies;
+ }
+
+ filterByAuthorId(id: number): Anthology[] {
+ const anthologies = this.anthologies.filter((anthology) =>
+ anthology.getAuthors().filter((author) => author.id === id),
+ );
+
+ return anthologies;
+ }
+
+ filterByInventoryId(id: number): Anthology[] {
+ const anthologies = this.anthologies.filter((anthology) =>
+ anthology.inventory_locations?.filter((inventory) => inventory.id === id),
+ );
+
+ return anthologies;
+ }
+
+ filterByYear(year: number): Anthology[] {
+ const anthologies = this.anthologies.filter(
+ (anthology) => anthology.published_year === year,
+ );
+
+ return anthologies;
+ }
+
+ filterByStatus(status: AnthologyStatus): Anthology[] {
+ const anthologies = this.anthologies.filter(
+ (anthology) => anthology.status === status,
+ );
+
+ return anthologies;
+ }
+
+ getAllGenres(): Set {
+ const genres = new Set();
+ this.anthologies.forEach((anthology) =>
+ anthology.getGenres().forEach((genre) => genres.add(genre)),
+ );
+
+ return genres;
+ }
+
+ getAllThemes(): Set {
+ const themes = new Set();
+ this.anthologies.forEach((anthology) =>
+ anthology.getThemes().forEach((theme) => themes.add(theme)),
+ );
+
+ return themes;
+ }
+
+ getAllInventories(): Set {
+ const inventories = new Set();
+ this.anthologies.forEach((anthology) =>
+ anthology.inventory_locations?.forEach((inventory) =>
+ inventories.add(inventory),
+ ),
+ );
+
+ return inventories;
+ }
+
+ searchByTitle(title: string): Anthology[] {
+ const keywords = title.toLowerCase().split(' ');
+ const anthologies = this.anthologies.filter((anthology) => {
+ const titleNormalized = anthology.title.toLowerCase();
+ // check if it matches exactly; this would be ideal
+ // and allow us to short circuit checking every keyword
+ const searchTermDoesMatchTitleExactly = titleNormalized === title;
+
+ // thunked check for every keyword individually
+ const titleContainsEveryKeyword = () => {
+ keywords.every((keyword) => titleNormalized.includes(keyword));
+ };
+
+ return searchTermDoesMatchTitleExactly || titleContainsEveryKeyword();
+ });
+
+ return anthologies;
+ }
+
+ searchByAuthor(author: string): Anthology[] {
+ const authorNormalized = author.toLowerCase();
+ const anthologies = this.anthologies.filter((anthology) => {
+ const authors = anthology.getAuthors()?.map(String.prototype.toLowerCase);
+ return authors?.includes(authorNormalized);
+ });
+
+ return anthologies;
+ }
+}
diff --git a/apps/frontend/src/types/story.ts b/apps/frontend/src/types/story.ts
new file mode 100644
index 000000000..7d6e34927
--- /dev/null
+++ b/apps/frontend/src/types/story.ts
@@ -0,0 +1,12 @@
+import { Author } from './author';
+import { Genre } from './genre';
+import { Theme } from './theme';
+
+export interface Story {
+ id: number;
+ title: string;
+ anthology_id: number;
+ authors: Author[];
+ genres?: Genre[];
+ themes?: Theme[];
+}
diff --git a/apps/frontend/src/types/theme.ts b/apps/frontend/src/types/theme.ts
new file mode 100644
index 000000000..e636324b0
--- /dev/null
+++ b/apps/frontend/src/types/theme.ts
@@ -0,0 +1,4 @@
+export interface Theme {
+ id: number;
+ name: string;
+}
diff --git a/apps/frontend/src/utils/mock-data.ts b/apps/frontend/src/utils/mock-data.ts
index a60d779d6..333e6d11d 100644
--- a/apps/frontend/src/utils/mock-data.ts
+++ b/apps/frontend/src/utils/mock-data.ts
@@ -1,233 +1,535 @@
-export interface Anthology {
- id: number;
- title: string;
- subtitle?: string;
- byline?: string;
- description?: string;
- published_year: number;
- status: string;
- updated_at?: string;
- authors?: string[];
- photo_url?: string;
+import {
+ Anthology,
+ AnthologyPubLevel,
+ AnthologyStatus,
+} from '../types/anthology';
+import { Genre } from 'types/genre';
- // Additional fields from metadata
- foreword_author?: string;
- praise_quotes?: string;
- age_category?: string;
- genre?: string;
- theme?: string;
- isbn?: string;
- shopify_url?: string;
- binding_type?: string;
- dimensions?: string;
- printing_cost?: string;
- print_run?: number;
- weight?: string;
- page_count?: number;
- printed_by?: string;
- pub_level?: string;
- publishing_permission?: string;
- program?: string;
- sponsors?: string[];
- number_of_students?: number;
- inventory?: number;
- inventory_locations?: {
- [location: string]: number;
- };
+// both structures below are local to this file
+enum GenreType {
+ ADVICE,
+ SCIENCE_FICTION,
+ FANTASY,
+ RECIPES,
+ HUMOR,
+ POETRY,
+ SHORT_STORIES,
+ FICTION,
+ NON_FICTION,
+ ESSAYS,
+ CIVIC_ENGAGEMENT,
+ POLITICS,
+ SPEECHES,
}
+const STATIC_GENRES: Record = {
+ [GenreType.ADVICE]: { id: 2, name: 'Advice' },
+ [GenreType.SCIENCE_FICTION]: { id: 3, name: 'Science Fiction' },
+ [GenreType.FANTASY]: { id: 4, name: 'Fantasy' },
+ [GenreType.RECIPES]: { id: 5, name: 'Recipes' },
+ [GenreType.HUMOR]: { id: 6, name: 'Humor' },
+ [GenreType.POETRY]: { id: 7, name: 'Poetry' },
+ [GenreType.SHORT_STORIES]: { id: 8, name: 'Short Stories' },
+ [GenreType.FICTION]: { id: 9, name: 'Fiction' },
+ [GenreType.NON_FICTION]: { id: 10, name: 'Non-Fiction' },
+ [GenreType.ESSAYS]: { id: 11, name: 'Essays' },
+ [GenreType.CIVIC_ENGAGEMENT]: { id: 12, name: 'Fiction' },
+ [GenreType.POLITICS]: { id: 13, name: 'Non-Fiction' },
+ [GenreType.SPEECHES]: { id: 14, name: 'Essays' },
+};
+
export const STATIC_ARCHIVED: Anthology[] = [
- {
- id: 1,
- title: 'What if the World Needs You?',
- subtitle: 'Advice and Life Lessons',
- byline: 'from 826 Boston Students',
- description:
- "Discover a world where wisdom and whimsy collide in this captivating anthology from 826 Boston. Each story offers a unique piece of advice, from reimagined Greek myths to thought-provoking advice columns. Get ready to be challenged, moved, and inspired by these young voices' raw creativity and fearless storytelling!",
- published_year: 2024,
- status: 'archived',
- authors: ['826 Boston Students'],
- photo_url: '/src/assets/images/covers/Whatiftheworld_2024.jpg',
- foreword_author: 'Meredith Goldstein',
- praise_quotes:
- "\"I will cherish this collection by 826 Boston students who have crafted a range of work, from poetry to narratives to essays. Every piece is wisdom. Every short story, diary, comedy, and drama is embedded with advice, even if it's not obvious. Now, when I think, 'What should I do next?' I have a new place to turn.\" - Meredith Goldstein, author, longtime advice columnist, and associate editor at The Boston Globe",
- age_category:
- 'Chapter Books (Ages 6–10), Early Reader Books (Ages 5–8), Middle Grade Books (Ages 8–13), Young Adult Books (Ages 13–18)',
- genre:
- 'Advice, Science Fiction, Fantasy, Recipes, Humor, Poetry, Short Stories, Fiction, Non-Fiction, Essays',
- theme: 'Creative Writing, Short Stories',
- isbn: '979-8-88694-056-5',
- shopify_url: 'https://826boston.org',
- binding_type: 'Perfect Bound',
- dimensions: '11" x 8.5"',
- printing_cost: '$8,548.28',
- print_run: 600,
- weight: '28.11 oz / 827 g',
- page_count: 245,
- printed_by: 'PaperGraphics',
- pub_level: 'Signature Publication (Level 3)',
- publishing_permission: 'All',
- program: 'YABP',
- sponsors: [
+ new Anthology(
+ /*id:*/ 1,
+ /*title:*/ 'What if the World Needs You?',
+ /*published_year:*/ 2024,
+ /*status:*/ AnthologyStatus.ARCHIVED,
+ /*stories:*/ [
+ {
+ id: 1,
+ title: 'Lorem Ipsum',
+ anthology_id: 1,
+ authors: [
+ {
+ id: 1,
+ name: '826 Boston Students',
+ },
+ ],
+ genres: [
+ STATIC_GENRES[GenreType.ADVICE],
+ STATIC_GENRES[GenreType.SCIENCE_FICTION],
+ STATIC_GENRES[GenreType.FANTASY],
+ STATIC_GENRES[GenreType.RECIPES],
+ STATIC_GENRES[GenreType.HUMOR],
+ STATIC_GENRES[GenreType.POETRY],
+ STATIC_GENRES[GenreType.SHORT_STORIES],
+ STATIC_GENRES[GenreType.FICTION],
+ STATIC_GENRES[GenreType.NON_FICTION],
+ STATIC_GENRES[GenreType.ESSAYS],
+ ],
+ themes: [
+ { id: 1, name: 'Creative Writing' },
+ { id: 2, name: 'Short Stories' },
+ ],
+ },
+ ],
+ /*subtitle:*/ 'Advice and Life Lessons',
+ /*byline:*/ 'from 826 Boston Students',
+ /*description:*/
+ "Discover a world where wisdom and whimsy collide in this captivating anthology from 826 Boston. Each story offers a unique piece of advice, from reimagined Greek myths to thought-provoking advice columns. Get ready to be challenged, moved, and inspired by these young voices' raw creativity and fearless storytelling!",
+ /*updated_at:*/ 'Jan 1, 1960',
+ /*authors: [],*/
+ /*photo_url:*/ '/src/assets/images/covers/Whatiftheworld_2024.jpg',
+ /*foreword_author:*/ 'Meredith Goldstein',
+ /*praise_quotes:*/
+ "\"I will cherish this collection by 826 Boston students who have crafted a range of work, from poetry to narratives to essays. Every piece is wisdom. Every short story, diary, comedy, and drama is embedded with advice, even if it's not obvious. Now, when I think, 'What should I do next?' I have a new place to turn.\" - Meredith Goldstein, author, longtime advice columnist, and associate editor at The Boston Globe",
+ /*age_category:*/
+ 'Chapter Books (Ages 6–10), Early Reader Books (Ages 5–8), Middle Grade Books (Ages 8–13), Young Adult Books (Ages 13–18)',
+ /*isbn:*/ '979-8-88694-056-5',
+ /*shopify_url:*/ 'https://826boston.org',
+ /*binding_type:*/ 'Perfect Bound',
+ /*dimensions:*/ '11" x 8.5"',
+ /*printing_cost:*/ '$8,548.28',
+ /*print_run:*/ 600,
+ /*weight:*/ '28.11 oz / 827 g',
+ /*page_count:*/ 245,
+ /*printed_by:*/ 'PaperGraphics',
+ /*pub_level:*/ AnthologyPubLevel.SIGNATURE,
+ /*publishing_permission:*/ 'All',
+ /*programs:*/ ['YABP'],
+ /*sponsors:*/ [
'Boston Globe',
'Grub Street',
'Nosy Crow Inc.',
'Tiny Tiger Foundation',
],
- number_of_students: 91,
- inventory: 313,
- inventory_locations: {
- "BINcA Writers' Room": 3,
- "BTU Writers' Room": 1,
- 'Dev/Comms Office (1865 Columbus)': 2,
- "Holland Writers' Room": 2,
- Library: 1,
- 'The Hub (1989 Columbus)': 250,
- "O'Bryant Writers' Room": 3,
- "Muñiz Writers' Room": 5,
- "New Mission Writers' Room": 32,
- 'Tutoring Center (3035 Office)': 313,
- },
- },
- {
- id: 2,
- title: 'I Was Meant For This',
- subtitle: "Mayoral Speeches By Boston's Young Leaders",
- byline: 'from 826 Boston Students',
- description:
- "Boston's 2021 mayoral election was a competitive race with more ethnically and racially diverse candidates than ever before. In I Was Meant for This students of all ages give their own inaugural addresses as Boston's mayor-elect. These speeches—simultaneously playful, imaginative, and keenly observed—speak to an evolving city, as told through the eyes of tomorrow's leaders.",
- published_year: 2022,
- status: 'archived',
- authors: ['826 Boston Students'],
- photo_url: '/src/assets/images/covers/IwasMeantforthis_2022.jpg',
- foreword_author: 'Adrian Walker',
- praise_quotes:
- '"These are the speeches—and the voices—of young people who know that they matter, and that their thoughts and dreams matter. We should want that for all young people in every neighborhood of our city. I hope you enjoy their writing, and their thinking, as much as I did. We need their voices more than ever. And to our young mayoral candidates and essayists I say: Please keep writing. And please keep dreaming." - Adrian Walker, Columnist/Associate Editor, The Boston Globe',
- age_category:
- 'Chapter Books (Ages 6–10), Middle Grade Books (Ages 8–13), Young Adult Books (Ages 13–18)',
- genre: 'Civic Engagement, Politics, Speeches',
- theme: 'Leadership, Neighborhood, The Future',
- isbn: '978-1-948644-89-1',
- shopify_url: 'https://826boston.org/publications/i-was-meant-for-this/',
- binding_type: 'Perfect Bound',
- dimensions: '6" x 9.5"',
- printing_cost: '$4,315.58',
- print_run: 500,
- weight: '10.8 oz / 306 g',
- page_count: 146,
- printed_by: 'PaperGraphics',
- pub_level: 'Signature Publication (Level 3)',
- publishing_permission: 'All',
- program: 'YABP',
- sponsors: ['Richard K. Lubin Family Foundation'],
- number_of_students: 40,
- inventory: 62,
- inventory_locations: {
- "BINcA Writers' Room": 2,
- 'Dev/Comms Office (1865 Columbus)': 0,
- "Holland Writers' Room": 0,
- "O'Bryant Writers' Room": 9,
- Library: 0,
- 'The Hub (1989 Columbus)': 54,
- "Muñiz Writers' Room": 0,
- "New Mission Writers' Room": 0,
- 'Tutoring Center (3035 Office)': 1,
- },
- },
- {
- id: 3,
- title: 'Student Voices Vol. 1',
- published_year: 2022,
- status: 'archived',
- authors: ['A. Lee', 'M. Torres'],
- genre:
- 'Advice, Science Fiction, Fantasy, Recipes, Humor, Poetry, Short Stories, Fiction, Non-Fiction, Essays',
- },
- {
- id: 4,
- title: '826 Boston Anthology 2023',
- published_year: 2023,
- status: 'archived',
- authors: ['Jamal Wright'],
- genre:
- 'Advice, Science Fiction, Fantasy, Recipes, Humor, Poetry, Short Stories, Fiction, Non-Fiction, Essays',
- },
- {
- id: 5,
- title: 'Neighborhood Stories',
- published_year: 2021,
- status: 'archived',
- authors: ['A. Lee'],
- genre:
- 'Advice, Science Fiction, Fantasy, Recipes, Humor, Poetry, Short Stories, Fiction, Non-Fiction, Essays',
- },
- {
- id: 6,
- title: 'Poetry from the Classroom',
- published_year: 2020,
- status: 'archived',
- authors: ['Student Contributors'],
- genre:
- 'Advice, Science Fiction, Fantasy, Recipes, Humor, Poetry, Short Stories, Fiction, Non-Fiction, Essays',
- },
- {
- id: 7,
- title: 'Young Writers Showcase',
- published_year: 2019,
- status: 'archived',
- authors: ['K. Chen', 'R. Patel', 'S. Johnson'],
- genre:
- 'Advice, Science Fiction, Fantasy, Recipes, Humor, Poetry, Short Stories, Fiction, Non-Fiction, Essays',
- },
- {
- id: 8,
- title: 'Stories from Roxbury',
- published_year: 2021,
- status: 'archived',
- authors: ['Community Writers'],
- genre:
- 'Advice, Science Fiction, Fantasy, Recipes, Humor, Poetry, Short Stories, Fiction, Non-Fiction, Essays',
- },
- {
- id: 9,
- title: 'Creative Expressions 2022',
- published_year: 2022,
- status: 'archived',
- authors: ['M. Williams', 'D. Brown'],
- genre:
- 'Advice, Science Fiction, Fantasy, Recipes, Humor, Poetry, Short Stories, Fiction, Non-Fiction, Essays',
- },
- {
- id: 10,
- title: 'Voices of Tomorrow',
- published_year: 2023,
- status: 'archived',
- authors: ['826 Boston Students'],
- genre:
- 'Advice, Science Fiction, Fantasy, Recipes, Humor, Poetry, Short Stories, Fiction, Non-Fiction, Essays',
- },
+ /*number_of_students:*/ 91,
+ /*inventory:*/ 313,
+ /*inventory_locations:*/ [
+ { id: 1, name: "BINcA Writers' Room", num_copies: 1 },
+ { id: 2, name: 'Dev/Comms Office (1865 Columbus)', num_copies: 2 },
+ { id: 3, name: "Holland Writers' Room", num_copies: 2 },
+ { id: 4, name: 'Library', num_copies: 1 },
+ { id: 5, name: 'The Hub (1989 Columbus)', num_copies: 250 },
+ { id: 6, name: "O'Bryant Writers' Room", num_copies: 3 },
+ { id: 7, name: "Muñiz Writers' Room", num_copies: 5 },
+ { id: 8, name: "New Mission Writers' Room", num_copies: 32 },
+ { id: 9, name: 'Tutoring Center (3035 Office)', num_copies: 313 },
+ ],
+ ),
+ new Anthology(
+ /*id:*/ 2,
+ /*title:*/ 'I Was Meant For This',
+ /*published_year:*/ 2022,
+ /*status:*/ AnthologyStatus.ARCHIVED,
+ /*stories:*/ [
+ {
+ id: 2,
+ title: 'Story 1',
+ anthology_id: 2,
+ authors: [
+ {
+ id: 1,
+ name: '826 Boston Students',
+ },
+ ],
+ genres: [
+ STATIC_GENRES[GenreType.CIVIC_ENGAGEMENT],
+ STATIC_GENRES[GenreType.POLITICS],
+ STATIC_GENRES[GenreType.SPEECHES],
+ ],
+ themes: [
+ { id: 1, name: 'Leadership' },
+ { id: 2, name: 'Neighborhood' },
+ { id: 3, name: 'The Future' },
+ ],
+ },
+ ],
+ /*subtitle:*/ "Mayoral Speeches By Boston's Young Leaders",
+ /*byline:*/ 'from 826 Boston Students',
+ /*description:*/
+ "Boston's 2021 mayoral election was a competitive race with more ethnically and racially diverse candidates than ever before. In I Was Meant for This students of all ages give their own inaugural addresses as Boston's mayor-elect. These speeches—simultaneously playful, imaginative, and keenly observed—speak to an evolving city, as told through the eyes of tomorrow's leaders.",
+ /*updated_at:*/ 'Jan 1, 1960',
+ /*photo_url:*/ '/src/assets/images/covers/IwasMeantforthis_2022.jpg',
+ /*foreword_author:*/ 'Adrian Walker',
+ /*praise_quotes:*/
+ '"These are the speeches—and the voices—of young people who know that they matter, and that their thoughts and dreams matter. We should want that for all young people in every neighborhood of our city. I hope you enjoy their writing, and their thinking, as much as I did. We need their voices more than ever. And to our young mayoral candidates and essayists I say: Please keep writing. And please keep dreaming." - Adrian Walker, Columnist/Associate Editor, The Boston Globe',
+ /*age_category:*/
+ 'Chapter Books (Ages 6–10), Middle Grade Books (Ages 8–13), Young Adult Books (Ages 13–18)',
+ /*isbn:*/ '978-1-948644-89-1',
+ /*shopify_url:*/ 'https://826boston.org/publications/i-was-meant-for-this/',
+ /*binding_type:*/ 'Perfect Bound',
+ /*dimensions:*/ '6" x 9.5"',
+ /*printing_cost:*/ '$4,315.58',
+ /*print_run:*/ 500,
+ /*weight:*/ '10.8 oz / 306 g',
+ /*page_count:*/ 146,
+ /*printed_by:*/ 'PaperGraphics',
+ /*pub_level:*/ AnthologyPubLevel.SIGNATURE,
+ /*publishing_permission:*/ 'All',
+ /*program:*/ ['YABP'],
+ /*sponsors:*/ ['Richard K. Lubin Family Foundation'],
+ /*number_of_students:*/ 40,
+ /*inventory:*/ 62,
+ /*inventory_locations:*/ [
+ { id: 1, name: "BINcA Writers' Room", num_copies: 2 },
+ { id: 2, name: 'Dev/Comms Office (1865 Columbus)', num_copies: 0 },
+ { id: 3, name: "Holland Writers' Room", num_copies: 9 },
+ { id: 4, name: 'Library', num_copies: 0 },
+ { id: 5, name: 'The Hub (1989 Columbus)', num_copies: 54 },
+ { id: 6, name: "O'Bryant Writers' Room", num_copies: 0 },
+ { id: 7, name: "Muñiz Writers' Room", num_copies: 0 },
+ { id: 8, name: "New Mission Writers' Room", num_copies: 1 },
+ { id: 9, name: 'Tutoring Center (3035 Office)', num_copies: 16 },
+ ],
+ ),
+ new Anthology(
+ /*id:*/ 3,
+ /*title:*/ 'Student Voices Vol. 1',
+ /*published_year:*/ 2022,
+ /*status:*/ AnthologyStatus.ARCHIVED,
+ /*stories:*/ [
+ {
+ id: 2,
+ title: 'Story 1',
+ anthology_id: 2,
+ authors: [
+ {
+ id: 2,
+ name: 'A. Lee',
+ },
+ ],
+ genres: [
+ STATIC_GENRES[GenreType.ADVICE],
+ STATIC_GENRES[GenreType.SCIENCE_FICTION],
+ STATIC_GENRES[GenreType.FANTASY],
+ STATIC_GENRES[GenreType.RECIPES],
+ STATIC_GENRES[GenreType.HUMOR],
+ STATIC_GENRES[GenreType.POETRY],
+ ],
+ themes: [
+ { id: 1, name: 'Leadership' },
+ { id: 2, name: 'Neighborhood' },
+ { id: 3, name: 'The Future' },
+ ],
+ },
+ {
+ id: 3,
+ title: 'Story 2',
+ anthology_id: 2,
+ authors: [
+ {
+ id: 3,
+ name: 'M. Torres',
+ },
+ ],
+ genres: [
+ STATIC_GENRES[GenreType.SHORT_STORIES],
+ STATIC_GENRES[GenreType.FICTION],
+ STATIC_GENRES[GenreType.NON_FICTION],
+ STATIC_GENRES[GenreType.ESSAYS],
+ ],
+ themes: [
+ { id: 1, name: 'Leadership' },
+ { id: 2, name: 'Neighborhood' },
+ { id: 3, name: 'The Future' },
+ ],
+ },
+ ],
+ ),
+ new Anthology(
+ /*id:*/ 4,
+ /*title:*/ '826 Boston Anthology 2023',
+ /*published_year:*/ 2023,
+ /*status:*/ AnthologyStatus.ARCHIVED,
+ ),
+ new Anthology(
+ /*id:*/ 5,
+ /*title:*/ 'Neighborhood Stories',
+ /*published_year:*/ 2021,
+ /*status:*/ AnthologyStatus.ARCHIVED,
+ /*stories:*/ [
+ {
+ id: 3,
+ title: 'Story 3',
+ anthology_id: 5,
+ authors: [
+ {
+ id: 2,
+ name: 'A. Lee',
+ },
+ ],
+ genres: [
+ STATIC_GENRES[GenreType.ADVICE],
+ STATIC_GENRES[GenreType.SCIENCE_FICTION],
+ STATIC_GENRES[GenreType.FANTASY],
+ STATIC_GENRES[GenreType.RECIPES],
+ STATIC_GENRES[GenreType.HUMOR],
+ STATIC_GENRES[GenreType.POETRY],
+ STATIC_GENRES[GenreType.SHORT_STORIES],
+ STATIC_GENRES[GenreType.FICTION],
+ STATIC_GENRES[GenreType.NON_FICTION],
+ STATIC_GENRES[GenreType.ESSAYS],
+ ],
+ themes: [
+ { id: 1, name: 'Leadership' },
+ { id: 2, name: 'Neighborhood' },
+ { id: 3, name: 'The Future' },
+ ],
+ },
+ ],
+ ),
+ new Anthology(
+ /*id:*/ 6,
+ /*title:*/ 'Poetry from the Classroom',
+ /*published_year:*/ 2020,
+ /*status:*/ AnthologyStatus.ARCHIVED,
+ /*stories:*/ [
+ {
+ id: 4,
+ title: 'Story 4',
+ anthology_id: 6,
+ authors: [
+ {
+ id: 4,
+ name: 'Students Contributors',
+ },
+ ],
+ genres: [
+ STATIC_GENRES[GenreType.ADVICE],
+ STATIC_GENRES[GenreType.SCIENCE_FICTION],
+ STATIC_GENRES[GenreType.FANTASY],
+ STATIC_GENRES[GenreType.RECIPES],
+ STATIC_GENRES[GenreType.HUMOR],
+ STATIC_GENRES[GenreType.POETRY],
+ STATIC_GENRES[GenreType.SHORT_STORIES],
+ STATIC_GENRES[GenreType.FICTION],
+ STATIC_GENRES[GenreType.NON_FICTION],
+ STATIC_GENRES[GenreType.ESSAYS],
+ ],
+ themes: [
+ { id: 1, name: 'Leadership' },
+ { id: 2, name: 'Neighborhood' },
+ { id: 4, name: 'Lorem Ipsum' },
+ ],
+ },
+ ],
+ ),
+ new Anthology(
+ /*id:*/ 7,
+ /*title:*/ 'Young Writers Showcase',
+ /*published_year:*/ 2019,
+ /*status:*/ AnthologyStatus.ARCHIVED,
+ /*stories:*/ [
+ {
+ id: 4,
+ title: 'Story 4',
+ anthology_id: 7,
+ authors: [
+ {
+ id: 4,
+ name: 'R. Patel',
+ },
+ ],
+ genres: [
+ STATIC_GENRES[GenreType.ADVICE],
+ STATIC_GENRES[GenreType.SCIENCE_FICTION],
+ STATIC_GENRES[GenreType.FANTASY],
+ STATIC_GENRES[GenreType.RECIPES],
+ ],
+ themes: [
+ { id: 1, name: 'Leadership' },
+ { id: 2, name: 'Neighborhood' },
+ { id: 4, name: 'Lorem Ipsum' },
+ ],
+ },
+ {
+ id: 5,
+ title: 'Story 5',
+ anthology_id: 7,
+ authors: [
+ {
+ id: 6,
+ name: 'K. Chen',
+ },
+ ],
+ genres: [
+ STATIC_GENRES[GenreType.HUMOR],
+ STATIC_GENRES[GenreType.POETRY],
+ STATIC_GENRES[GenreType.SHORT_STORIES],
+ ],
+ themes: [
+ { id: 1, name: 'Leadership' },
+ { id: 2, name: 'Neighborhood' },
+ { id: 4, name: 'Lorem Ipsum' },
+ ],
+ },
+ {
+ id: 6,
+ title: 'Story 6',
+ anthology_id: 7,
+ authors: [
+ {
+ id: 7,
+ name: 'S. Johnson',
+ },
+ ],
+ genres: [
+ STATIC_GENRES[GenreType.FICTION],
+ STATIC_GENRES[GenreType.NON_FICTION],
+ STATIC_GENRES[GenreType.ESSAYS],
+ ],
+ themes: [
+ { id: 1, name: 'Leadership' },
+ { id: 2, name: 'Neighborhood' },
+ { id: 4, name: 'Lorem Ipsum' },
+ ],
+ },
+ ],
+ ),
+ new Anthology(
+ /*id:*/ 8,
+ /*title:*/ 'Stories from Roxbury',
+ /*published_year:*/ 2021,
+ /*status:*/ AnthologyStatus.ARCHIVED,
+ /*stories:*/ [
+ {
+ id: 8,
+ title: 'Story 7',
+ anthology_id: 8,
+ authors: [
+ {
+ id: 8,
+ name: 'Community Writers',
+ },
+ ],
+ genres: [
+ STATIC_GENRES[GenreType.ADVICE],
+ STATIC_GENRES[GenreType.SCIENCE_FICTION],
+ STATIC_GENRES[GenreType.FANTASY],
+ STATIC_GENRES[GenreType.RECIPES],
+ STATIC_GENRES[GenreType.HUMOR],
+ STATIC_GENRES[GenreType.POETRY],
+ STATIC_GENRES[GenreType.SHORT_STORIES],
+ STATIC_GENRES[GenreType.FICTION],
+ STATIC_GENRES[GenreType.NON_FICTION],
+ STATIC_GENRES[GenreType.ESSAYS],
+ ],
+ themes: [
+ { id: 1, name: 'Leadership' },
+ { id: 2, name: 'Neighborhood' },
+ { id: 4, name: 'Lorem Ipsum' },
+ ],
+ },
+ ],
+ ),
+ new Anthology(
+ /*id:*/ 9,
+ /*title:*/ 'Creative Expressions 2022',
+ /*published_year:*/ 2022,
+ /*status:*/ AnthologyStatus.ARCHIVED,
+ /*stories:*/ [
+ {
+ id: 8,
+ title: 'Story 7',
+ anthology_id: 9,
+ authors: [
+ {
+ id: 9,
+ name: 'D. Brown',
+ },
+ ],
+ genres: [
+ STATIC_GENRES[GenreType.ADVICE],
+ STATIC_GENRES[GenreType.SCIENCE_FICTION],
+ STATIC_GENRES[GenreType.FANTASY],
+ STATIC_GENRES[GenreType.RECIPES],
+ STATIC_GENRES[GenreType.HUMOR],
+ ],
+ themes: [
+ { id: 1, name: 'Leadership' },
+ { id: 2, name: 'Neighborhood' },
+ { id: 4, name: 'Lorem Ipsum' },
+ ],
+ },
+ {
+ id: 8,
+ title: 'Story 7',
+ anthology_id: 9,
+ authors: [
+ {
+ id: 8,
+ name: 'M. Williams',
+ },
+ {
+ id: 10,
+ name: '826 Boston Students',
+ },
+ ],
+ genres: [
+ STATIC_GENRES[GenreType.POETRY],
+ STATIC_GENRES[GenreType.SHORT_STORIES],
+ STATIC_GENRES[GenreType.FICTION],
+ STATIC_GENRES[GenreType.NON_FICTION],
+ STATIC_GENRES[GenreType.ESSAYS],
+ ],
+ themes: [{ id: 4, name: 'Lorem Ipsum' }],
+ },
+ ],
+ ),
+ new Anthology(
+ /*id:*/ 10,
+ /*title:*/ 'Voices of Tomorrow',
+ /*published_year:*/ 2023,
+ /*status:*/ AnthologyStatus.ARCHIVED,
+ /*stories:*/ [
+ {
+ id: 10,
+ title: 'Story 10',
+ anthology_id: 10,
+ authors: [
+ {
+ id: 1,
+ name: '826 Boston Students',
+ },
+ ],
+ genres: [
+ STATIC_GENRES[GenreType.ADVICE],
+ STATIC_GENRES[GenreType.SCIENCE_FICTION],
+ STATIC_GENRES[GenreType.FANTASY],
+ STATIC_GENRES[GenreType.RECIPES],
+ STATIC_GENRES[GenreType.HUMOR],
+ STATIC_GENRES[GenreType.POETRY],
+ STATIC_GENRES[GenreType.SHORT_STORIES],
+ STATIC_GENRES[GenreType.FICTION],
+ STATIC_GENRES[GenreType.NON_FICTION],
+ STATIC_GENRES[GenreType.ESSAYS],
+ ],
+ themes: [{ id: 4, name: 'Lorem Ipsum' }],
+ },
+ ],
+ ),
];
export const RECENTLY_EDITED: Anthology[] = [
- {
- id: 101,
- title: 'Untitled Publication',
- published_year: 2025,
- status: 'archived',
- },
- {
- id: 102,
- title: 'Untitled Publication',
- published_year: 2025,
- status: 'archived',
- },
- {
- id: 103,
- title: 'Untitled Publication',
- published_year: 2025,
- status: 'archived',
- authors: ['Student Contributors'],
- },
+ new Anthology(
+ /*id:*/ 101,
+ /*title:*/ 'Untitled Publication',
+ /*published_year:*/ 2025,
+ /*status:*/ AnthologyStatus.ARCHIVED,
+ ),
+ new Anthology(
+ /*id:*/ 102,
+ /*title:*/ 'Untitled Publication',
+ /*published_year:*/ 2025,
+ /*status:*/ AnthologyStatus.ARCHIVED,
+ ),
+ new Anthology(
+ /*id:*/ 103,
+ /*title:*/ 'Untitled Publication',
+ /*published_year:*/ 2025,
+ /*status:*/ AnthologyStatus.ARCHIVED,
+ ),
];
export const MOCK_LAST_MODIFIED = 'October 15, 2025';