diff --git a/.gitignore b/.gitignore index 0d634a8e1..dee8c505e 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ .firebaserc dist/ **/ui-debug.log +.next diff --git a/dataconnect/.gitignore b/dataconnect/.gitignore new file mode 100644 index 000000000..a431356d1 --- /dev/null +++ b/dataconnect/.gitignore @@ -0,0 +1,70 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +firebase-debug.log* +firebase-debug.*.log* + +# Firebase cache +.firebase/ + +# Firebase config + +# Uncomment this if you'd like others to create their own Firebase project. +# For a team working on the same Firebase project(s), it is recommended to leave +# it commented so all members can deploy to the same project(s) in .firebaserc. +# .firebaserc + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.next +.dataconnect +movie/lib/dataconnect-sdk +movie/package-lock.json diff --git a/dataconnect/README.md b/dataconnect/README.md new file mode 100644 index 000000000..708390df9 --- /dev/null +++ b/dataconnect/README.md @@ -0,0 +1,41 @@ +Firebase DataConnect Quickstart +======================================= + +Introduction +------------ + +This is a sample app for the preview version of the Firebase DataConnect. +This will not work if you don't have access to the preview. + + + +Getting Started +--------------- + +1. Sign up for early access [here](https://firebase.google.com/products/data-connect) and receive an invitation. +2. Upgrade your Firebase project billing to the Blaze plan, you will not be charged for the duration of gated preview. +3. Initialize DataConnect in the [Firebase Console](https://console.firebase.google.com/u/0/). +4. Clone this repository to your local machine. +5. Update `firebase-tools` with `npm install -g firebase-tools`. +6. Enable the DataConnect CLI with `firebase experiments:enable dataconnect`. +7. Initialize your Firebase project in the `dataconnect` folder with `firebase init` and select DataConnect. Do not overwrite the dataconnect files when prompted. +8. Replace variables in `.env.local` with your project-specific values. +9. Allow domains for Firebase Auth (e.g., http://localhost or http://127.0.0.1). +10. Deploy DataConnect with `firebase deploy --only dataconnect` (this unlocks hidden vectors search). +11. Start the DateConnect emulators. +12. Run `firebase dataconnect:sdk:generate` to generate the SDK +13. Navigate to the `movie` directory and install dependencies with `npm i` and start the development server with `npm run dev`. +14. Run the four `_insert.gql` files in the `./dataconnect` directory in order. + + + +License +------- + +© Google, 2024. Licensed under an [Apache-2](../LICENSE) license. diff --git a/dataconnect/dataconnect/1_movie_insert.gql b/dataconnect/dataconnect/1_movie_insert.gql new file mode 100644 index 000000000..5f312db4e --- /dev/null +++ b/dataconnect/dataconnect/1_movie_insert.gql @@ -0,0 +1,241 @@ +mutation { + movie1: movie_insert(data: { + id: "550e8400-e29b-41d4-a716-446655440000", + title: "Inception", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Finception.jpg?alt=media&token=07b09781-b302-4623-a5c3-1956d0143168", + releaseYear: 2010, + genre: "sci-fi", + rating: 8.8, + description: "Dom Cobb (Leonardo DiCaprio) is a thief with the rare ability to enter people's dreams and steal their secrets from their subconscious. His skill has made him a valuable player in the world of corporate espionage but has also cost him everything he loves. Cobb gets a chance at redemption when he is offered a seemingly impossible task: plant an idea in someone's mind. If he succeeds, it will be the perfect crime, but a dangerous enemy anticipates Cobb's every move.", + tags: ["thriller", "action"], + descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: "Dom Cobb (Leonardo DiCaprio) is a thief with the rare ability to enter people's dreams and steal their secrets from their subconscious. His skill has made him a valuable player in the world of corporate espionage but has also cost him everything he loves. Cobb gets a chance at redemption when he is offered a seemingly impossible task: plant an idea in someone's mind. If he succeeds, it will be the perfect crime, but a dangerous enemy anticipates Cobb's every move."} + }) + + movie2: movie_insert(data: { + id: "550e8400-e29b-41d4-a716-446655440001", + title: "The Matrix", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Fthe_matrix.jpg?alt=media&token=4975645d-fef8-409e-84a5-bcc1046e2059", + releaseYear: 1999, + genre: "action", + rating: 8.7, + description: "Thomas Anderson, a computer programmer, discovers that the world is actually a simulation controlled by malevolent machines in a dystopian future. Known as Neo, he joins a group of underground rebels led by Morpheus to fight the machines and free humanity. Along the way, Neo learns to manipulate the simulated reality, uncovering his true destiny.", + tags: ["sci-fi", "adventure"], + descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: "Thomas Anderson, a computer programmer, discovers that the world is actually a simulation controlled by malevolent machines in a dystopian future. Known as Neo, he joins a group of underground rebels led by Morpheus to fight the machines and free humanity. Along the way, Neo learns to manipulate the simulated reality, uncovering his true destiny."} + }) + + movie3: movie_insert(data: { + id: "550e8400-e29b-41d4-a716-446655440002", + title: "John Wick 4", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Fjohn_wick_4.jpg?alt=media&token=463ed467-9daa-4281-965d-44e7cc4172d5", + releaseYear: 2023, + genre: "action", + rating: 8.1, + description: "John Wick (Keanu Reeves) uncovers a path to defeating The High Table, but before he can earn his freedom, he must face off against a new enemy with powerful alliances across the globe. The film follows Wick as he battles through various international locations, facing relentless adversaries and forming new alliances.", + tags: ["action", "thriller"], + descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: "John Wick (Keanu Reeves) uncovers a path to defeating The High Table, but before he can earn his freedom, he must face off against a new enemy with powerful alliances across the globe. The film follows Wick as he battles through various international locations, facing relentless adversaries and forming new alliances."} + }) + + movie4: movie_insert(data: { + id: "550e8400-e29b-41d4-a716-446655440003", + title: "The Dark Knight", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Fthe_dark_knight.jpg?alt=media&token=a9803c59-40d5-4758-a6f4-9a7c274a1218", + releaseYear: 2008, + genre: "action", + rating: 9.0, + description: "When the menace known as the Joker (Heath Ledger) emerges from his mysterious past, he wreaks havoc and chaos on the people of Gotham. The Dark Knight (Christian Bale) must accept one of the greatest psychological and physical tests of his ability to fight injustice.", + tags: ["action", "drama"], + descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: "When the menace known as the Joker (Heath Ledger) emerges from his mysterious past, he wreaks havoc and chaos on the people of Gotham. The Dark Knight (Christian Bale) must accept one of the greatest psychological and physical tests of his ability to fight injustice."} + }) + + movie5: movie_insert(data: { + id: "550e8400-e29b-41d4-a716-446655440004", + title: "Fight Club", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Ffight_club.jpg?alt=media&token=a4bc1933-2607-42cd-a860-e44c4587fd9c", + releaseYear: 1999, + genre: "drama", + rating: 8.8, + description: "An insomniac office worker (Edward Norton) and a devil-may-care soapmaker (Brad Pitt) form an underground fight club that evolves into something much more. The story explores themes of consumerism, masculinity, and the search for identity.", + tags: ["drama", "thriller"], + descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: "An insomniac office worker (Edward Norton) and a devil-may-care soapmaker (Brad Pitt) form an underground fight club that evolves into something much more. The story explores themes of consumerism, masculinity, and the search for identity."} + }) + + movie6: movie_insert(data: { + id: "550e8400-e29b-41d4-a716-446655440005", + title: "Pulp Fiction", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Fpulp_fiction.jpg?alt=media&token=0df86e18-5cb1-45b3-a6d9-3f41563c3465", + releaseYear: 1994, + genre: "crime", + rating: 8.9, + description: "The lives of two mob hitmen, a boxer, a gangster and his wife, and a pair of diner bandits intertwine in four tales of violence and redemption. The film is known for its eclectic dialogue, ironic mix of humor and violence, and a host of cinematic allusions and pop culture references.", + tags: ["crime", "drama"], + descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: "The lives of two mob hitmen, a boxer, a gangster and his wife, and a pair of diner bandits intertwine in four tales of violence and redemption. The film is known for its eclectic dialogue, ironic mix of humor and violence, and a host of cinematic allusions and pop culture references."} + }) + + movie7: movie_insert(data: { + id: "550e8400-e29b-41d4-a716-446655440006", + title: "The Lord of the Rings: The Fellowship of the Ring", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Flotr_fellowship.jpg?alt=media&token=92641d2d-6c52-4172-bd66-95fb86b4b96b", + releaseYear: 2001, + genre: "fantasy", + rating: 8.8, + description: "A meek Hobbit from the Shire, Frodo Baggins, and eight companions set out on a journey to destroy the powerful One Ring and save Middle-earth from the Dark Lord Sauron. The epic adventure begins the quest that will test their courage and bond.", + tags: ["fantasy", "adventure"], + descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: "A meek Hobbit from the Shire, Frodo Baggins, and eight companions set out on a journey to destroy the powerful One Ring and save Middle-earth from the Dark Lord Sauron. The epic adventure begins the quest that will test their courage and bond."} + }) + + movie8: movie_insert(data: { + id: "550e8400-e29b-41d4-a716-446655440007", + title: "The Shawshank Redemption", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Fthe_shawshanks_redemption.jpg?alt=media&token=f67b5ab2-a435-48b2-8251-5bf866b183e9", + releaseYear: 1994, + genre: "drama", + rating: 9.3, + description: "Two imprisoned men bond over a number of years, finding solace and eventual redemption through acts of common decency. The film follows Andy Dufresne (Tim Robbins), a banker sentenced to life in Shawshank State Penitentiary, and his friendship with Red (Morgan Freeman).", + tags: ["drama", "crime"], + descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: "Two imprisoned men bond over a number of years, finding solace and eventual redemption through acts of common decency. The film follows Andy Dufresne (Tim Robbins), a banker sentenced to life in Shawshank State Penitentiary, and his friendship with Red (Morgan Freeman)."} + }) + + movie9: movie_insert(data: { + id: "550e8400-e29b-41d4-a716-446655440008", + title: "Forrest Gump", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Fforrest_gump.jpeg?alt=media&token=f21e88ce-6fab-4218-aa55-94738acc9b8f", + releaseYear: 1994, + genre: "drama", + rating: 8.8, + description: "The presidencies of Kennedy and Johnson, the events of Vietnam, Watergate, and other historical moments unfold from the perspective of an Alabama man with a low IQ. Forrest Gump (Tom Hanks) becomes an unwitting participant in many key moments of 20th-century U.S. history, all while maintaining his love for his childhood sweetheart Jenny (Robin Wright).", + tags: ["drama", "romance"], + descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: "The presidencies of Kennedy and Johnson, the events of Vietnam, Watergate, and other historical moments unfold from the perspective of an Alabama man with a low IQ. Forrest Gump (Tom Hanks) becomes an unwitting participant in many key moments of 20th-century U.S. history, all while maintaining his love for his childhood sweetheart Jenny (Robin Wright)."} + }) + + movie10: movie_insert(data: { + id: "550e8400-e29b-41d4-a716-446655440009", + title: "The Godfather", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Fthe_godfather.jpg?alt=media&token=5297fd94-ae87-4995-9de5-3755232bad52", + releaseYear: 1972, + genre: "crime", + rating: 9.2, + description: "The aging patriarch of an organized crime dynasty transfers control of his clandestine empire to his reluctant son. The story follows the powerful Corleone family as they navigate power, loyalty, and betrayal.", + tags: ["crime", "drama"], + descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: "The aging patriarch of an organized crime dynasty transfers control of his clandestine empire to his reluctant son. The story follows the powerful Corleone family as they navigate power, loyalty, and betrayal."} + }) + + movie11: movie_insert(data: { + id: "550e8400-e29b-41d4-a716-446655440010", + title: "The Silence of the Lambs", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Fthe_silence_of_the_lambs.jpg?alt=media&token=7ca6abeb-b15c-4f5e-9280-5a590e89fe54", + releaseYear: 1991, + genre: "thriller", + rating: 8.6, + description: "A young F.B.I. cadet must receive the help of an incarcerated and manipulative cannibal killer to help catch another serial killer. Clarice Starling (Jodie Foster) seeks the assistance of Hannibal Lecter (Anthony Hopkins) to understand the mind of a killer.", + tags: ["thriller", "crime"], + descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: "A young F.B.I. cadet must receive the help of an incarcerated and manipulative cannibal killer to help catch another serial killer. Clarice Starling (Jodie Foster) seeks the assistance of Hannibal Lecter (Anthony Hopkins) to understand the mind of a killer."} + }) + + movie12: movie_insert(data: { + id: "550e8400-e29b-41d4-a716-446655440011", + title: "Saving Private Ryan", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Fsaving_private_ryan.jpg?alt=media&token=58ed877e-7ae0-4e30-9aee-d45c2deb7a00", + releaseYear: 1998, + genre: "war", + rating: 8.6, + description: "Following the Normandy Landings, a group of U.S. soldiers go behind enemy lines to retrieve a paratrooper whose brothers have been killed in action. The harrowing journey of Captain John H. Miller (Tom Hanks) and his men highlights the brutal reality of war.", + tags: ["war", "drama"], + descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: "Following the Normandy Landings, a group of U.S. soldiers go behind enemy lines to retrieve a paratrooper whose brothers have been killed in action. The harrowing journey of Captain John H. Miller (Tom Hanks) and his men highlights the brutal reality of war."} + }) + + movie13: movie_insert(data: { + id: "550e8400-e29b-41d4-a716-446655440012", + title: "The Avengers", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Fthe_avengers.jpg?alt=media&token=3d68ccad-2fa1-48da-a83e-7941e246c9f9", + releaseYear: 2012, + genre: "action", + rating: 8.0, + description: "Earth's mightiest heroes, including Iron Man, Captain America, Thor, Hulk, Black Widow, and Hawkeye, must come together to stop Loki and his alien army from enslaving humanity. Directed by Joss Whedon, the film is known for its witty dialogue, intense action sequences, and the chemistry among its ensemble cast.", + tags: ["action", "sci-fi"], + descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: "Earth's mightiest heroes, including Iron Man, Captain America, Thor, Hulk, Black Widow, and Hawkeye, must come together to stop Loki and his alien army from enslaving humanity. Directed by Joss Whedon, the film is known for its witty dialogue, intense action sequences, and the chemistry among its ensemble cast."} + }) + + movie14: movie_insert(data: { + id: "550e8400-e29b-41d4-a716-446655440013", + title: "Gladiator", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Fgladiator.jpg?alt=media&token=61d75825-b79f-4add-afdb-7da5eed53407", + releaseYear: 2000, + genre: "action", + rating: 8.5, + description: "A former Roman General, Maximus Decimus Meridius, seeks vengeance against the corrupt emperor Commodus who murdered his family and sent him into slavery. Directed by Ridley Scott, the film is known for its epic scale, intense battle scenes, and Russell Crowe's powerful performance.", + tags: ["action", "drama"], + descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: "A former Roman General, Maximus Decimus Meridius, seeks vengeance against the corrupt emperor Commodus who murdered his family and sent him into slavery. Directed by Ridley Scott, the film is known for its epic scale, intense battle scenes, and Russell Crowe's powerful performance."} + }) + + movie15: movie_insert(data: { + id: "550e8400-e29b-41d4-a716-446655440014", + title: "Titanic", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Ftitanic.png?alt=media&token=dd03dc83-486e-4b03-9b03-2f9ed83fd9d0", + releaseYear: 1997, + genre: "romance", + rating: 7.8, + description: "A romantic drama recounting the ill-fated voyage of the R.M.S. Titanic through the eyes of Jack Dawson, a poor artist, and Rose DeWitt Bukater, a wealthy aristocrat. Their forbidden romance unfolds aboard the luxurious ship, which tragically sinks after striking an iceberg. Directed by James Cameron, the film is known for its epic scale, emotional depth, and stunning visuals.", + tags: ["romance", "drama"], + descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: "A romantic drama recounting the ill-fated voyage of the R.M.S. Titanic through the eyes of Jack Dawson, a poor artist, and Rose DeWitt Bukater, a wealthy aristocrat. Their forbidden romance unfolds aboard the luxurious ship, which tragically sinks after striking an iceberg. Directed by James Cameron, the film is known for its epic scale, emotional depth, and stunning visuals."} + }) + + movie16: movie_insert(data: { + id: "550e8400-e29b-41d4-a716-446655440015", + title: "Avatar", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Favatar.jpg?alt=media&token=1c75b09d-7c7a-44bf-b7ad-e7da4d0b7193", + releaseYear: 2009, + genre: "sci-fi", + rating: 7.8, + description: "A paraplegic Marine named Jake Sully is sent on a unique mission to Pandora, an alien world, to bridge relations with the native Na'vi people. Torn between following his orders and protecting the world he feels is his home, Jake's journey becomes a battle for survival. Directed by James Cameron, 'Avatar' is renowned for its groundbreaking special effects and immersive 3D experience.", + tags: ["sci-fi", "adventure"], + descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: "A paraplegic Marine named Jake Sully is sent on a unique mission to Pandora, an alien world, to bridge relations with the native Na'vi people. Torn between following his orders and protecting the world he feels is his home, Jake's journey becomes a battle for survival. Directed by James Cameron, 'Avatar' is renowned for its groundbreaking special effects and immersive 3D experience."} + }) + + movie17: movie_insert(data: { + id: "550e8400-e29b-41d4-a716-446655440016", + title: "Jurassic Park", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Fjurassic_park.jpg?alt=media&token=1731ce71-3384-4435-8a5b-821d4fd286d3", + releaseYear: 1993, + genre: "adventure", + rating: 8.1, + description: "During a preview tour, a theme park suffers a major power breakdown that allows its cloned dinosaur exhibits to run amok. Directed by Steven Spielberg, 'Jurassic Park' is known for its groundbreaking special effects, thrilling storyline, and the suspenseful chaos unleashed by its prehistoric creatures.", + tags: ["adventure", "sci-fi"], + descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: "During a preview tour, a theme park suffers a major power breakdown that allows its cloned dinosaur exhibits to run amok. Directed by Steven Spielberg, 'Jurassic Park' is known for its groundbreaking special effects, thrilling storyline, and the suspenseful chaos unleashed by its prehistoric creatures."} + }) + + movie18: movie_insert(data: { + id: "550e8400-e29b-41d4-a716-446655440017", + title: "The Lion King", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Fthe_lion_king.jpg?alt=media&token=3e4e4265-6ae7-47d6-a5ba-584de126ef00", + releaseYear: 1994, + genre: "animation", + rating: 8.5, + description: "A young lion prince, Simba, must overcome betrayal and tragedy to reclaim his rightful place as king. 'The Lion King' is a beloved animated musical known for its memorable songs, stunning animation, and a timeless tale of courage, loyalty, and redemption.", + tags: ["animation", "drama"], + descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: "A young lion prince, Simba, must overcome betrayal and tragedy to reclaim his rightful place as king. 'The Lion King' is a beloved animated musical known for its memorable songs, stunning animation, and a timeless tale of courage, loyalty, and redemption."} + }) + + movie19: movie_insert(data: { + id: "550e8400-e29b-41d4-a716-446655440018", + title: "Star Wars: Episode IV - A New Hope", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Fstar_wars_4.jpg?alt=media&token=b4ea7e0c-707f-43dd-8633-9d962e77b5a4", + releaseYear: 1977, + genre: "sci-fi", + rating: 8.6, + description: "Luke Skywalker joins forces with a Jedi Knight, a cocky pilot, a Wookiee, and two droids to save the galaxy from the Empire's world-destroying battle station, the Death Star. Directed by George Lucas, 'A New Hope' revolutionized the sci-fi genre with its groundbreaking special effects and unforgettable characters.", + tags: ["sci-fi", "adventure"], + descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: "Luke Skywalker joins forces with a Jedi Knight, a cocky pilot, a Wookiee, and two droids to save the galaxy from the Empire's world-destroying battle station, the Death Star. Directed by George Lucas, 'A New Hope' revolutionized the sci-fi genre with its groundbreaking special effects and unforgettable characters."} + }) + + movie20: movie_insert(data: { + id: "550e8400-e29b-41d4-a716-446655440019", + title: "Blade Runner", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/movies%2Fblade_runner.jpg?alt=media&token=d8e94bdd-1477-49f3-b244-dd7a9c059fc1", + releaseYear: 1982, + genre: "sci-fi", + rating: 8.1, + description: "In a dystopian future, synthetic humans known as replicants are created by powerful corporations. A blade runner named Rick Deckard is tasked with hunting down and 'retiring' four replicants who have escaped to Earth. Directed by Ridley Scott, 'Blade Runner' is a seminal sci-fi thriller that explores themes of humanity and identity.", + tags: ["sci-fi", "thriller"], + descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: "In a dystopian future, synthetic humans known as replicants are created by powerful corporations. A blade runner named Rick Deckard is tasked with hunting down and 'retiring' four replicants who have escaped to Earth. Directed by Ridley Scott, 'Blade Runner' is a seminal sci-fi thriller that explores themes of humanity and identity."} + }) +} diff --git a/dataconnect/dataconnect/2_actor_insert.gql b/dataconnect/dataconnect/2_actor_insert.gql new file mode 100644 index 000000000..971cb1007 --- /dev/null +++ b/dataconnect/dataconnect/2_actor_insert.gql @@ -0,0 +1,141 @@ +mutation { + actor1: actor_insert(data: { + id: "123e4567-e89b-12d3-a456-426614174000", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/actors%2Fdicaprio.jpeg?alt=media&token=452e030a-efa5-4ef4-bb81-502b23241316", + name: "Leonardo DiCaprio", + biography: "Leonardo DiCaprio is an American actor and producer. He has received numerous awards, including an Academy Award and three Golden Globe Awards. DiCaprio is known for his roles in Titanic, Inception, and The Revenant." + }) + + actor2: actor_insert(data: { + id: "123e4567-e89b-12d3-a456-426614174001", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/actors%2Fkeanu.jpg?alt=media&token=6056520c-ef3e-4823-aad0-108aab163115", + name: "Keanu Reeves", + biography: "Keanu Reeves is a Canadian actor known for his roles in The Matrix and John Wick series. He has gained acclaim for his versatility and has also directed and produced several films." + }) + + actor3: actor_insert(data: { + id: "123e4567-e89b-12d3-a456-426614174002", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/actors%2Fmcconaoghey.jpg?alt=media&token=d340ca18-ef51-44ac-a160-08e45b242cd7", + name: "Matthew McConaughey", + biography: "Matthew McConaughey is an American actor and producer. He gained fame with his breakout role in Dazed and Confused and has won an Academy Award for his performance in Dallas Buyers Club." + }) + + actor4: actor_insert(data: { + id: "123e4567-e89b-12d3-a456-426614174003", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/actors%2Fbale.jpg?alt=media&token=666f1690-a550-458f-a1cf-9505b7d1af7d", + name: "Christian Bale", + biography: "Christian Bale is an English actor known for his versatility and physical transformations for roles. He has starred in The Dark Knight Trilogy and won an Academy Award for The Fighter." + }) + + actor5: actor_insert(data: { + id: "123e4567-e89b-12d3-a456-426614174004", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/actors%2Fpitt.jpeg?alt=media&token=3a5283d4-f85c-4ba7-be72-51bc87ca4133", + name: "Brad Pitt", + biography: "Brad Pitt is an American actor and producer. He has won two Academy Awards and is known for his roles in Fight Club, Ocean's Eleven, and Once Upon a Time in Hollywood." + }) + + actor6: actor_insert(data: { + id: "123e4567-e89b-12d3-a456-426614174005", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/actors%2Fjackson.jpg?alt=media&token=07be0601-19fe-4b5d-b111-84fa71f32139", + name: "Samuel L. Jackson", + biography: "Samuel L. Jackson is an American actor and producer. He is one of the most widely recognized actors of his generation, known for his roles in Pulp Fiction, the Marvel Cinematic Universe, and Jurassic Park." + }) + + actor7: actor_insert(data: { + id: "123e4567-e89b-12d3-a456-426614174006", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/actors%2Fmortensen.jpeg?alt=media&token=e3d1ec99-b8e7-42e9-9d1c-03f56f61ecf7", + name: "Viggo Mortensen", + biography: "Viggo Mortensen is an American actor, author, and musician. He is best known for his role as Aragorn in The Lord of the Rings trilogy and has been nominated for three Academy Awards." + }) + + actor8: actor_insert(data: { + id: "123e4567-e89b-12d3-a456-426614174007", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/actors%2Ffreeman.jpg?alt=media&token=94bc6227-119e-4ab0-b350-55fac7aeb062", + name: "Morgan Freeman", + biography: "Morgan Freeman is an American actor, director, and narrator. He is known for his distinctive voice and has won an Academy Award for his role in Million Dollar Baby." + }) + + actor9: actor_insert(data: { + id: "123e4567-e89b-12d3-a456-426614174008", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/actors%2Fhanks.jpeg?alt=media&token=d92979ce-da62-4b28-afbe-b8740bbb9d32", + name: "Tom Hanks", + biography: "Tom Hanks is an American actor and filmmaker. He is known for his roles in Forrest Gump, Saving Private Ryan, and Toy Story, and has won two Academy Awards for Best Actor." + }) + + actor10: actor_insert(data: { + id: "123e4567-e89b-12d3-a456-426614174009", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/actors%2Fpacino.jpg?alt=media&token=9c0c54b1-6913-48b5-8e5e-d6551dd2f182", + name: "Al Pacino", + biography: "Al Pacino is an American actor and filmmaker. He has won an Academy Award, two Tony Awards, and two Primetime Emmy Awards. He is known for his roles in The Godfather series, Scarface, and Scent of a Woman." + }) + + actor11: actor_insert(data: { + id: "123e4567-e89b-12d3-a456-426614174010", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/actors%2Ffoster.jpg?alt=media&token=b429734c-0f2d-4840-b75b-6857eac7bb4f", + name: "Jodie Foster", + biography: "Jodie Foster is an American actress and director. She has won two Academy Awards for Best Actress for her roles in The Accused and The Silence of the Lambs." + }) + + actor12: actor_insert(data: { + id: "123e4567-e89b-12d3-a456-426614174011", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/actors%2Fcruise.jpg?alt=media&token=d34b0326-a8d1-4f01-86e5-f3f094594e5a", + name: "Tom Cruise", + biography: "Tom Cruise is an American actor and producer. He is one of the highest-paid actors in the world and is known for his roles in Top Gun, the Mission: Impossible series, and Jerry Maguire." + }) + + actor13: actor_insert(data: { + id: "123e4567-e89b-12d3-a456-426614174012", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/actors%2Fdowney.jpg?alt=media&token=dd291c96-6ef0-42fc-841c-902c80748b37", + name: "Robert Downey Jr.", + biography: "Robert Downey Jr. is an American actor and producer. He is known for his roles in Iron Man, Sherlock Holmes, and Chaplin, and has been a major figure in the Marvel Cinematic Universe." + }) + + actor14: actor_insert(data: { + id: "123e4567-e89b-12d3-a456-426614174013", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/actors%2Fcrowe.jpg?alt=media&token=46d413d5-ace8-404e-b018-8d7e6fe0d362", + name: "Russell Crowe", + biography: "Russell Crowe is an Australian actor, film producer, and musician. He gained international fame for his role in Gladiator, for which he won the Academy Award for Best Actor." + }) + + actor15: actor_insert(data: { + id: "123e4567-e89b-12d3-a456-426614174014", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/actors%2Fwinslet.jpg?alt=media&token=b675585e-356e-4361-a041-5ac1a6ee5922", + name: "Kate Winslet", + biography: "Kate Winslet is an English actress known for her roles in Titanic, The Reader, and Eternal Sunshine of the Spotless Mind. She has won numerous awards, including an Academy Award and an Emmy." + }) + + actor16: actor_insert(data: { + id: "123e4567-e89b-12d3-a456-426614174015", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/actors%2Fweaver.jpeg?alt=media&token=263b5c3d-e0ee-43c3-854d-9b236c6df391", + name: "Sigourney Weaver", + biography: "Sigourney Weaver is an American actress best known for her roles in the Alien franchise, Ghostbusters, and Avatar. She has been nominated for three Academy Awards and has won two Golden Globe Awards." + }) + + actor17: actor_insert(data: { + id: "123e4567-e89b-12d3-a456-426614174016", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/actors%2Fgoldblume.jpeg?alt=media&token=18277dd1-166c-4934-a02e-19ef141c86e2", + name: "Jeff Goldblum", + biography: "Jeff Goldblum is an American actor and musician known for his roles in Jurassic Park, Independence Day, and The Fly. His unique delivery and eccentric characters have made him a cult icon." + }) + + actor18: actor_insert(data: { + id: "123e4567-e89b-12d3-a456-426614174017", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/actors%2Fjones.jpg?alt=media&token=f7ac9bc4-6e26-4b25-9a73-7a90f699424e", + name: "James Earl Jones", + biography: "James Earl Jones is an American actor known for his deep resonant voice, which has been featured in roles such as Darth Vader in Star Wars and Mufasa in The Lion King. He has won multiple awards, including a Tony, Emmy, and Grammy." + }) + + actor19: actor_insert(data: { + id: "123e4567-e89b-12d3-a456-426614174018", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/actors%2Fford.jpg?alt=media&token=928434c0-d492-4c8e-bdf0-0db585008d87", + name: "Harrison Ford", + biography: "Harrison Ford is an American actor known for his iconic roles as Han Solo in Star Wars and Indiana Jones in the Indiana Jones series. He has been nominated for an Academy Award and has received numerous other accolades." + }) + + actor20: actor_insert(data: { + id: "123e4567-e89b-12d3-a456-426614174019", + imageUrl: "https://firebasestorage.googleapis.com/v0/b/fdc-quickstart-web.appspot.com/o/actors%2Fschwarzenegger.jpeg?alt=media&token=c46fb249-41ef-4084-b4ad-9517bee6ab46", + name: "Arnold Schwarzenegger", + biography: "Arnold Schwarzenegger is an Austrian-American actor, businessman, and former politician. He is best known for his roles in The Terminator series and Total Recall, and for serving as the 38th Governor of California." + }) +} diff --git a/dataconnect/dataconnect/3_movie_actor_insert.gql b/dataconnect/dataconnect/3_movie_actor_insert.gql new file mode 100644 index 000000000..b8a270541 --- /dev/null +++ b/dataconnect/dataconnect/3_movie_actor_insert.gql @@ -0,0 +1,283 @@ +mutation { + metadata1: movieMetadata_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440000", + director: "Christopher Nolan" + }) + + metadata2: movieMetadata_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440001", + director: "Lana Wachowski, Lilly Wachowski" + }) + + metadata3: movieMetadata_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440002", + director: "Chad Stahelski" + }) + + metadata4: movieMetadata_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440003", + director: "Christopher Nolan" + }) + + metadata5: movieMetadata_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440004", + director: "David Fincher" + }) + + metadata6: movieMetadata_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440005", + director: "Quentin Tarantino" + }) + + metadata7: movieMetadata_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440006", + director: "Peter Jackson" + }) + + metadata8: movieMetadata_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440007", + director: "Frank Darabont" + }) + + metadata9: movieMetadata_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440008", + director: "Robert Zemeckis" + }) + + metadata10: movieMetadata_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440009", + director: "Francis Ford Coppola" + }) + + metadata11: movieMetadata_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440010", + director: "Jonathan Demme" + }) + + metadata12: movieMetadata_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440011", + director: "Steven Spielberg" + }) + + metadata13: movieMetadata_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440012", + director: "Joss Whedon" + }) + + metadata14: movieMetadata_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440013", + director: "Ridley Scott" + }) + + metadata15: movieMetadata_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440014", + director: "James Cameron" + }) + + metadata16: movieMetadata_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440015", + director: "James Cameron" + }) + + metadata17: movieMetadata_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440016", + director: "Steven Spielberg" + }) + + metadata18: movieMetadata_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440017", + director: "Roger Allers, Rob Minkoff" + }) + + metadata19: movieMetadata_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440018", + director: "George Lucas" + }) + + metadata20: movieMetadata_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440019", + director: "Ridley Scott" + }) + + movieActor1: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440000", + actorId: "123e4567-e89b-12d3-a456-426614174000", + role: "main" + }) + + movieActor2: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440001", + actorId: "123e4567-e89b-12d3-a456-426614174001", + role: "main" + }) + + movieActor3: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440002", + actorId: "123e4567-e89b-12d3-a456-426614174001", + role: "main" + }) + + movieActor4: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440003", + actorId: "123e4567-e89b-12d3-a456-426614174003", + role: "main" + }) + + movieActor5: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440004", + actorId: "123e4567-e89b-12d3-a456-426614174004", + role: "main" + }) + + movieActor6: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440005", + actorId: "123e4567-e89b-12d3-a456-426614174005", + role: "main" + }) + + movieActor7: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440006", + actorId: "123e4567-e89b-12d3-a456-426614174006", + role: "main" + }) + + movieActor8: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440007", + actorId: "123e4567-e89b-12d3-a456-426614174007", + role: "main" + }) + + movieActor9: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440008", + actorId: "123e4567-e89b-12d3-a456-426614174008", + role: "main" + }) + + movieActor10: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440009", + actorId: "123e4567-e89b-12d3-a456-426614174009", + role: "main" + }) + + movieActor11: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440010", + actorId: "123e4567-e89b-12d3-a456-426614174010", + role: "main" + }) + + movieActor12: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440011", + actorId: "123e4567-e89b-12d3-a456-426614174011", + role: "main" + }) + + movieActor13: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440012", + actorId: "123e4567-e89b-12d3-a456-426614174012", + role: "main" + }) + + movieActor14: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440013", + actorId: "123e4567-e89b-12d3-a456-426614174013", + role: "main" + }) + + movieActor15: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440014", + actorId: "123e4567-e89b-12d3-a456-426614174014", + role: "main" + }) + + movieActor16: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440015", + actorId: "123e4567-e89b-12d3-a456-426614174015", + role: "main" + }) + + movieActor17: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440016", + actorId: "123e4567-e89b-12d3-a456-426614174016", + role: "main" + }) + + movieActor18: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440017", + actorId: "123e4567-e89b-12d3-a456-426614174017", + role: "main" + }) + + movieActor19: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440018", + actorId: "123e4567-e89b-12d3-a456-426614174018", + role: "main" + }) + + movieActor20: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440019", + actorId: "123e4567-e89b-12d3-a456-426614174019", + role: "main" + }) + + # Adding supporting actors + movieActor21: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440000", + actorId: "123e4567-e89b-12d3-a456-426614174001", + role: "supporting" + }) + + movieActor22: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440001", + actorId: "123e4567-e89b-12d3-a456-426614174002", + role: "supporting" + }) + + movieActor23: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440002", + actorId: "123e4567-e89b-12d3-a456-426614174003", + role: "supporting" + }) + + movieActor24: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440003", + actorId: "123e4567-e89b-12d3-a456-426614174004", + role: "supporting" + }) + + movieActor25: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440004", + actorId: "123e4567-e89b-12d3-a456-426614174005", + role: "supporting" + }) + + movieActor26: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440005", + actorId: "123e4567-e89b-12d3-a456-426614174006", + role: "supporting" + }) + + movieActor27: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440006", + actorId: "123e4567-e89b-12d3-a456-426614174007", + role: "supporting" + }) + + movieActor28: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440007", + actorId: "123e4567-e89b-12d3-a456-426614174008", + role: "supporting" + }) + + movieActor29: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440008", + actorId: "123e4567-e89b-12d3-a456-426614174009", + role: "supporting" + }) + + movieActor30: movieActor_insert(data: { + movieId: "550e8400-e29b-41d4-a716-446655440009", + actorId: "123e4567-e89b-12d3-a456-426614174010", + role: "supporting" + }) + +} diff --git a/dataconnect/dataconnect/4_user_favorites_review_insert.gql b/dataconnect/dataconnect/4_user_favorites_review_insert.gql new file mode 100644 index 000000000..70bf8fa23 --- /dev/null +++ b/dataconnect/dataconnect/4_user_favorites_review_insert.gql @@ -0,0 +1,184 @@ +mutation { + user1: user_insert(data: { + id: "SnLgOC3lN4hcIl69s53cW0Q8R1T2", + username: "cynthia_w" + }) + + user2: user_insert(data: { + id: "fep4fXpGWsaRpuphq9CIrBIXQ0S2", + username: "momo_h" + }) + + user3: user_insert(data: { + id: "TBedjwCX0Jf955Uuoxk6k74sY0l1", + username: "siyi_w" + }) + + review1: review_insert(data: { + id: "345e4567-e89b-12d3-a456-426614174000", + + userId: "SnLgOC3lN4hcIl69s53cW0Q8R1T2", + movieId: "550e8400-e29b-41d4-a716-446655440000", + rating: 5, + reviewText: "An incredible movie with a mind-blowing plot!", + reviewDate_date: { today: true } + }) + + review2: review_insert(data: { + id: "345e4567-e89b-12d3-a456-426614174001", + userId: "fep4fXpGWsaRpuphq9CIrBIXQ0S2", + + movieId: "550e8400-e29b-41d4-a716-446655440001", + rating: 5, + reviewText: "A revolutionary film that changed cinema forever.", + reviewDate_date: { today: true } + }) + + review3: review_insert(data: { + id: "345e4567-e89b-12d3-a456-426614174002", + userId: "TBedjwCX0Jf955Uuoxk6k74sY0l1", + + movieId: "550e8400-e29b-41d4-a716-446655440002", + rating: 5, + reviewText: "A visually stunning and emotionally impactful movie.", + reviewDate_date: { today: true } + }) + + review4: review_insert(data: { + id: "345e4567-e89b-12d3-a456-426614174003", + userId: "SnLgOC3lN4hcIl69s53cW0Q8R1T2", + + movieId: "550e8400-e29b-41d4-a716-446655440003", + rating: 4, + reviewText: "A fantastic superhero film with great performances.", + reviewDate_date: { today: true } + }) + + review5: review_insert(data: { + id: "345e4567-e89b-12d3-a456-426614174004", + userId: "fep4fXpGWsaRpuphq9CIrBIXQ0S2", + + movieId: "550e8400-e29b-41d4-a716-446655440004", + rating: 5, + reviewText: "An amazing film that keeps you on the edge of your seat.", + reviewDate_date: { today: true } + }) + + review6: review_insert(data: { + id: "345e4567-e89b-12d3-a456-426614174005", + userId: "TBedjwCX0Jf955Uuoxk6k74sY0l1", + + movieId: "550e8400-e29b-41d4-a716-446655440005", + rating: 5, + reviewText: "An absolute classic with unforgettable dialogue.", + reviewDate_date: { today: true } + }) + + favoriteMovie1: favoriteMovie_insert(data: { + userId: "SnLgOC3lN4hcIl69s53cW0Q8R1T2", + + movieId: "550e8400-e29b-41d4-a716-446655440000" + }) + + favoriteMovie2: favoriteMovie_insert(data: { + userId: "fep4fXpGWsaRpuphq9CIrBIXQ0S2", + + movieId: "550e8400-e29b-41d4-a716-446655440001" + }) + + favoriteMovie3: favoriteMovie_insert(data: { + userId: "TBedjwCX0Jf955Uuoxk6k74sY0l1", + + movieId: "550e8400-e29b-41d4-a716-446655440002" + }) + + favoriteMovie4: favoriteMovie_insert(data: { + userId: "SnLgOC3lN4hcIl69s53cW0Q8R1T2", + + movieId: "550e8400-e29b-41d4-a716-446655440003" + }) + + favoriteMovie5: favoriteMovie_insert(data: { + userId: "fep4fXpGWsaRpuphq9CIrBIXQ0S2", + + movieId: "550e8400-e29b-41d4-a716-446655440004" + }) + + favoriteMovie6: favoriteMovie_insert(data: { + userId: "TBedjwCX0Jf955Uuoxk6k74sY0l1", + + movieId: "550e8400-e29b-41d4-a716-446655440005" + }) + + favoriteActor1: favoriteActor_insert(data: { + userId: "SnLgOC3lN4hcIl69s53cW0Q8R1T2", + + actorId: "123e4567-e89b-12d3-a456-426614174000" + }) + + favoriteActor2: favoriteActor_insert(data: { + userId: "fep4fXpGWsaRpuphq9CIrBIXQ0S2", + + actorId: "123e4567-e89b-12d3-a456-426614174001" + }) + + favoriteActor3: favoriteActor_insert(data: { + userId: "TBedjwCX0Jf955Uuoxk6k74sY0l1", + + actorId: "123e4567-e89b-12d3-a456-426614174002" + }) + + favoriteActor4: favoriteActor_insert(data: { + userId: "SnLgOC3lN4hcIl69s53cW0Q8R1T2", + + actorId: "123e4567-e89b-12d3-a456-426614174003" + }) + + favoriteActor5: favoriteActor_insert(data: { + userId: "fep4fXpGWsaRpuphq9CIrBIXQ0S2", + + actorId: "123e4567-e89b-12d3-a456-426614174004" + }) + + favoriteActor6: favoriteActor_insert(data: { + userId: "TBedjwCX0Jf955Uuoxk6k74sY0l1", + + actorId: "123e4567-e89b-12d3-a456-426614174005" + }) + + watchedMovie1: watchedMovie_insert(data: { + userId: "SnLgOC3lN4hcIl69s53cW0Q8R1T2", + + movieId: "550e8400-e29b-41d4-a716-446655440000" + }) + + watchedMovie2: watchedMovie_insert(data: { + userId: "fep4fXpGWsaRpuphq9CIrBIXQ0S2", + + movieId: "550e8400-e29b-41d4-a716-446655440001" + }) + + watchedMovie3: watchedMovie_insert(data: { + userId: "TBedjwCX0Jf955Uuoxk6k74sY0l1", + + movieId: "550e8400-e29b-41d4-a716-446655440002" + }) + + watchedMovie4: watchedMovie_insert(data: { + userId: "SnLgOC3lN4hcIl69s53cW0Q8R1T2", + + movieId: "550e8400-e29b-41d4-a716-446655440003" + }) + + watchedMovie5: watchedMovie_insert(data: { + userId: "fep4fXpGWsaRpuphq9CIrBIXQ0S2", + + movieId: "550e8400-e29b-41d4-a716-446655440004" + }) + + watchedMovie6: watchedMovie_insert(data: { + userId: "TBedjwCX0Jf955Uuoxk6k74sY0l1", + + movieId: "550e8400-e29b-41d4-a716-446655440005" + }) +} diff --git a/dataconnect/dataconnect/connector/connector.yaml b/dataconnect/dataconnect/connector/connector.yaml new file mode 100644 index 000000000..66d17e5e5 --- /dev/null +++ b/dataconnect/dataconnect/connector/connector.yaml @@ -0,0 +1,14 @@ +connectorId: movie-connector +# Required. Accepted values are either "PUBLIC" or "ADMIN" (only "PUBLIC" for gated private +# preview). If "ADMIN", the connector in this directory is an AdminConnector and its operations +# are gated by IAM. +authMode: PUBLIC +generate: + javascriptSdk: + # Create a custom package name for your generated SDK + package: "@movie/sdk" + # Tells Data Connect where to store the generated SDK code, this should be in the same + # directory as your app code + outputDir: "../../movie/lib/dataconnect-sdk" + # This property tells Data Connect what directory to install the generated SDK to + # packageJsonDir: "../../movie/lib/dataconnect-sdk" diff --git a/dataconnect/dataconnect/connector/mutations.gql b/dataconnect/dataconnect/connector/mutations.gql new file mode 100644 index 000000000..57a6920ef --- /dev/null +++ b/dataconnect/dataconnect/connector/mutations.gql @@ -0,0 +1,113 @@ +# Create a movie based on user input +mutation createMovie( + $title: String! + $releaseYear: Int! + $genre: String! + $rating: Float + $description: String + $imageUrl: String! + $tags: [String!] = [] +) { + movie_insert( + data: { + title: $title + releaseYear: $releaseYear + genre: $genre + rating: $rating + description: $description + imageUrl: $imageUrl + tags: $tags + } + ) +} + +# Update movie information based on the provided ID +mutation updateMovie( + $id: UUID! + $title: String + $releaseYear: Int + $genre: String + $rating: Float + $description: String + $imageUrl: String + $tags: [String!] = [] +) { + movie_update( + id: $id + data: { + title: $title + releaseYear: $releaseYear + genre: $genre + rating: $rating + description: $description + imageUrl: $imageUrl + tags: $tags + } + ) +} + +# Delete a movie by its ID +mutation deleteMovie($id: UUID!) { + movie_delete(id: $id) +} + +# Delete movies with a rating lower than the specified minimum rating +mutation deleteUnpopularMovies($minRating: Float!) { + movie_deleteMany(where: { rating: { le: $minRating } }) +} + +# Add a movie to the user's watched list +mutation addWatchedMovie($movieId: UUID!) @auth(level: USER) { + watchedMovie_upsert(data: { userId_expr: "auth.uid", movieId: $movieId }) +} + +# Remove a movie from the user's watched list +mutation deleteWatchedMovie($userId: String!, $movieId: UUID!) @auth(level: USER) { + watchedMovie_delete(key: { userId: $userId, movieId: $movieId }) +} + +# Add a movie to the user's favorites list +mutation addFavoritedMovie($movieId: UUID!) @auth(level: USER) { + favoriteMovie_upsert(data: { userId_expr: "auth.uid", movieId: $movieId }) +} + +# Remove a movie from the user's favorites list +mutation deleteFavoritedMovie($userId: String!, $movieId: UUID!) @auth(level: USER) { + favoriteMovie_delete(key: { userId: $userId, movieId: $movieId }) +} + +# Add an actor to the user's favorites list +mutation addFavoritedActor($actorId: UUID!) @auth(level: USER) { + favoriteActor_upsert(data: { userId_expr: "auth.uid", actorId: $actorId }) +} + +# Remove an actor from the user's favorites list +mutation deleteFavoriteActor($userId: String!, $actorId: UUID!) @auth(level: USER) { + favoriteActor_delete(key: { userId: $userId, actorId: $actorId }) +} + +# Add a review for a movie +mutation addReview($movieId: UUID!, $rating: Int!, $reviewText: String!) @auth(level: USER) { + review_upsert( + data: { + userId_expr: "auth.uid" + movieId: $movieId + rating: $rating + reviewText: $reviewText + reviewDate_date: { today: true } + } + ) +} + +# Delete a user's review for a movie +mutation deleteReview($movieId: UUID!, $userId: String!) @auth(level: USER) { + review_delete(key: { userId: $userId, movieId: $movieId }) +} + +# Upsert (update or insert) a user based on their username +mutation upsertUser($username: String!) @auth(level: USER) { + user_upsert(data: { + id_expr: "auth.uid", + username: $username + }) +} diff --git a/dataconnect/dataconnect/connector/queries.gql b/dataconnect/dataconnect/connector/queries.gql new file mode 100644 index 000000000..158874ef9 --- /dev/null +++ b/dataconnect/dataconnect/connector/queries.gql @@ -0,0 +1,576 @@ +# List subset of fields for movies +query ListMovies @auth(level: PUBLIC) { + movies { + id + title + imageUrl + releaseYear + genre + rating + tags + description + } +} + + +# List subset of fields for users +query ListUsers @auth(level: PUBLIC) { + users { + id + username + favoriteActors: favoriteActors_on_user { + actor { + id + name + imageUrl + } + } + favoriteMovies: favoriteMovies_on_user { + movie { + id + title + genre + imageUrl + tags + } + } + reviews_on_user { + id + rating + reviewText + reviewDate + movie { + id + title + } + } + watchedMovies_on_user { + movie { + id + title + genre + imageUrl + } + } + } +} + +# List movies of a certain genre +query ListMoviesByGenre($genre: String!) @auth(level: PUBLIC) { + mostPopular: movies( + where: { genre: { eq: $genre } } + orderBy: { rating: DESC } + ) { + id + title + imageUrl + rating + tags + } + mostRecent: movies( + where: { genre: { eq: $genre } } + orderBy: { releaseYear: DESC } + ) { + id + title + imageUrl + rating + tags + } +} + +# List movies by the order of release +query ListMoviesByReleaseYear @auth(level: PUBLIC) { + movies(orderBy: [{ releaseYear: DESC }]) { + id + title + imageUrl + } +} + +# Get movie by id +query GetMovieById($id: UUID!) @auth(level: PUBLIC) { + movie(id: $id) { + id + title + imageUrl + releaseYear + genre + rating + description + tags + metadata: movieMetadatas_on_movie { + director + } + mainActors: actors_via_MovieActor(where: { role: { eq: "main" } }) { + id + name + imageUrl + } + supportingActors: actors_via_MovieActor( + where: { role: { eq: "supporting" } } + ) { + id + name + imageUrl + } + sequelTo { + id + title + imageUrl + } + reviews: reviews_on_movie { + id + reviewText + reviewDate + rating + user { + id + username + } + } + } +} + +# Get actor by id +query GetActorById($id: UUID!) @auth(level: PUBLIC) { + actor(id: $id) { + id + name + imageUrl + biography + mainActors: movies_via_MovieActor(where: { role: { eq: "main" } }) { + id + title + genre + tags + imageUrl + } + supportingActors: movies_via_MovieActor( + where: { role: { eq: "supporting" } } + ) { + id + title + genre + tags + imageUrl + } + } +} + +# User movie preferences +query UserMoviePreferences($username: String!) @auth(level: USER) { + users(where: { username: { eq: $username } }) { + likedMovies: movies_via_Review(where: { rating: { ge: 4 } }) { + title + imageUrl + genre + description + } + dislikedMovies: movies_via_Review(where: { rating: { le: 2 } }) { + title + imageUrl + genre + description + } + } +} + +# Get movie metadata +query GetMovieMetadata($id: UUID!) @auth(level: PUBLIC) { + movie(id: $id) { + movieMetadatas_on_movie { + director + } + } +} + +# Get movie cast and actor roles +query GetMovieCast($movieId: UUID!, $actorId: UUID!) @auth(level: PUBLIC) { + movie(id: $movieId) { + mainActors: actors_via_MovieActor(where: { role: { eq: "main" } }) { + id + name + imageUrl + } + supportingActors: actors_via_MovieActor( + where: { role: { eq: "supporting" } } + ) { + id + name + imageUrl + } + } + actor(id: $actorId) { + mainRoles: movies_via_MovieActor(where: { role: { eq: "main" } }) { + id + title + imageUrl + } + supportingRoles: movies_via_MovieActor( + where: { role: { eq: "supporting" } } + ) { + id + title + imageUrl + } + } +} + +# List movies by partial title match +query ListMoviesByPartialTitle($input: String!) @auth(level: PUBLIC) { + movies(where: { title: { contains: $input } }) { + id + title + genre + rating + imageUrl + } +} + +# Fetch a single movie using key scalars (same as get movie by id) +query MovieByKey($key: Movie_Key!) @auth(level: PUBLIC) { + movie(key: $key) { + title + imageUrl + } +} + +# Fetch movies by title +query MovieByTitle($title: String!) @auth(level: PUBLIC) { + movies(where: { title: { eq: $title } }) { + id + title + imageUrl + genre + rating + } +} + +# Fetch top-rated movies by genre +query MovieByTopRating($genre: String) @auth(level: PUBLIC) { + mostPopular: movies( + where: { genre: { eq: $genre } } + orderBy: { rating: DESC } + ) { + id + title + imageUrl + rating + tags + } +} + +# List movies by tag +query ListMoviesByTag($tag: String!) @auth(level: PUBLIC) { + movies(where: { tags: { includes: $tag } }) { + id + title + imageUrl + genre + rating + } +} + +# List top 10 movies +query MoviesTop10 @auth(level: PUBLIC) { + movies(orderBy: [{ rating: DESC }], limit: 10) { + id + title + imageUrl + rating + genre + tags + metadata: movieMetadatas_on_movie { + director + } + mainActors: actors_via_MovieActor(where: { role: { eq: "main" } }) { + id + name + imageUrl + } + supportingActors: actors_via_MovieActor(where: { role: { eq: "supporting" } }) { + id + name + imageUrl + } + } +} + +# List movies by release year range +query MoviesByReleaseYear($min: Int, $max: Int) @auth(level: PUBLIC) { + movies( + where: { releaseYear: { le: $max, ge: $min } } + orderBy: [{ releaseYear: ASC }] + ) { + id + rating + title + imageUrl + } +} + +# List recently released movies +query MoviesRecentlyReleased @auth(level: PUBLIC) { + movies(where: { releaseYear: { ge: 2010 } }) { + id + title + rating + imageUrl + genre + tags + } +} + +# List movies with filtering on fields +query ListMoviesFilter($genre: String, $limit: Int) @auth(level: PUBLIC) { + movies(where: { genre: { eq: $genre } }, limit: $limit) { + title + imageUrl + } +} + +# List movies by partial title string match +query ListMoviesByTitleString( + $prefix: String + $suffix: String + $contained: String +) @auth(level: PUBLIC) { + prefixed: movies(where: { description: { startsWith: $prefix } }) { + title + } + suffixed: movies(where: { description: { endsWith: $suffix } }) { + title + } + contained: movies(where: { description: { contains: $contained } }) { + title + } +} + +# List movies by rating and genre with OR/AND filters +query ListMoviesByRatingAndGenre($minRating: Float!, $genre: String) +@auth(level: PUBLIC) { + movies( + where: { _or: [{ rating: { ge: $minRating } }, { genre: { eq: $genre } }] } + ) { + title + imageUrl + } +} + +# Get favorite movies by user ID +query GetFavoriteMoviesById($id: String!) @auth(level: USER) { + user(id: $id) { + favoriteMovies_on_user { + movie { + id + title + genre + imageUrl + releaseYear + rating + description + } + } + } +} + +# Get favorite actors by user ID +query GetFavoriteActorsById($id: String!) @auth(level: USER) { + user(id: $id) { + favoriteActors_on_user { + actor { + id + name + imageUrl + } + } + } +} + +# Get watched movies by user ID +query GetWatchedMoviesByAuthId($id: String!) @auth(level: USER) { + user(id: $id) { + watchedMovies_on_user { + movie { + id + title + genre + imageUrl + releaseYear + rating + description + } + } + } +} + +# Get user by ID +query GetUserById($id: String!) @auth(level: USER) { + user(id: $id) { + id + username + reviews: reviews_on_user { + id + rating + reviewDate + reviewText + movie { + id + title + } + } + watched: watchedMovies_on_user { + movie { + id + title + genre + imageUrl + releaseYear + rating + description + tags + metadata: movieMetadatas_on_movie { + director + } + } + } + favoriteMovies: favoriteMovies_on_user { + movie { + id + title + genre + imageUrl + releaseYear + rating + description + tags + metadata: movieMetadatas_on_movie { + director + } + } + } + favoriteActors: favoriteActors_on_user { + actor { + id + name + imageUrl + } + } + } +} + +# Check if a movie is watched by user +query GetIfWatched($id: String!, $movieId: UUID!) @auth(level: USER) { + watchedMovie(key: { userId: $id, movieId: $movieId }) { + movieId + } +} + +# Check if a movie is favorited by user +query GetIfFavoritedMovie($id: String!, $movieId: UUID!) @auth(level: USER) { + favoriteMovie(key: { userId: $id, movieId: $movieId }) { + movieId + } +} + +# Check if an actor is favorited by user +query GetIfFavoritedActor($id: String!, $actorId: UUID!) @auth(level: USER) { + favoriteActor(key: { userId: $id, actorId: $actorId }) { + actorId + } +} + +# Fuzzy search for movies, actors, and reviews +query fuzzySearch( + $input: String + $minYear: Int! + $maxYear: Int! + $minRating: Float! + $maxRating: Float! + $genre: String! +) @auth(level: PUBLIC) { + moviesMatchingTitle: movies( + where: { + _and: [ + { releaseYear: { ge: $minYear } } + { releaseYear: { le: $maxYear } } + { rating: { ge: $minRating } } + { rating: { le: $maxRating } } + { genre: { contains: $genre } } + { title: { contains: $input } } + ] + } + ) { + id + title + genre + rating + imageUrl + } + moviesMatchingDescription: movies( + where: { + _and: [ + { releaseYear: { ge: $minYear } } + { releaseYear: { le: $maxYear } } + { rating: { ge: $minRating } } + { rating: { le: $maxRating } } + { genre: { contains: $genre } } + { description: { contains: $input } } + ] + } + ) { + id + title + genre + rating + imageUrl + } + actorsMatchingName: actors(where: { name: { contains: $input } }) { + id + name + imageUrl + } + reviewsMatchingText: reviews(where: { reviewText: { contains: $input } }) { + id + rating + reviewText + reviewDate + movie { + id + title + } + user { + id + username + } + } +} + +# Search movie descriptions using L2 similarity with Vertex AI +query searchMovieDescriptionUsingL2Similarity($query: String!) +@auth(level: PUBLIC) { + movies_descriptionEmbedding_similarity( + compare_embed: { model: "textembedding-gecko@003", text: $query } + method: L2 + within: 2 + where: { description: { ne: "" } } + limit: 5 + ) { + id + title + description + tags + rating + imageUrl + } +} + +# Search movie descriptions using L2 similarity with Vertex AI, with custom embeddings +query searchMovieDescriptionUsingL2Similarity1($compare: Vector!, $within: Float, $excludesContent: String, $limit: Int) @auth(level: PUBLIC) { + movies_descriptionEmbedding_similarity(compare: $compare, method: L2, within: $within, where: {description: {ne: $excludesContent}}, limit: $limit) { + id + title + description + } + } diff --git a/dataconnect/dataconnect/dataconnect.yaml b/dataconnect/dataconnect/dataconnect.yaml new file mode 100644 index 000000000..9dd8a336b --- /dev/null +++ b/dataconnect/dataconnect/dataconnect.yaml @@ -0,0 +1,10 @@ +specVersion: "v1alpha" +serviceId: "dataconnect" +schema: + source: "./schema" + datasource: + postgresql: + database: "postgres" + cloudSql: + instanceId: "your-instanceId" +connectorDirs: ["./connector"] diff --git a/dataconnect/dataconnect/schema/schema.gql b/dataconnect/dataconnect/schema/schema.gql new file mode 100644 index 000000000..4cda98395 --- /dev/null +++ b/dataconnect/dataconnect/schema/schema.gql @@ -0,0 +1,101 @@ +# Movies +type Movie + # The below parameter values are generated by default with @table, and can be edited manually. + @table(name: "Movies", singular: "movie", plural: "movies", key: ["id"]) { + # implicitly calls @col to generates a column name. ex: @col(name: "movie_id") + # for UUID fields, @default(expr: "uuidV4()") is implicitly called + id: UUID! + title: String! + imageUrl: String! + releaseYear: Int + genre: String + rating: Float + description: String + tags: [String] + # Vectors + descriptionEmbedding: Vector @col(size:768) # vector + # Self Joins + sequelTo: Movie +} + +# Movie Metadata +# Movie - MovieMetadata is a one-to-one relationship +type MovieMetadata + @table { + # @ref creates a field in the current table (MovieMetadata) that holds the primary key of the referenced type + # In this case, @ref(fields: "id") is implied + movie: Movie! @ref + # movieId: UUID <- this is created by the above @ref + director: String + # TODO: optional other fields +} + +# Actors +# Suppose an actor can participate in multiple movies and movies can have multiple actors +# Movie - Actors (or vice versa) is a many to many relationship +type Actor @table { + id: UUID! + imageUrl: String! + name: String! @col(name: "name", dataType: "varchar(30)") + biography: String +} + +# Join table for many-to-many relationship for movies and actors +# The 'key' param signifies the primary key(s) of this table +# In this case, the keys are [movieId, actorId], the generated fields of the reference types [movie, actor] +type MovieActor @table(key: ["movie", "actor"]) { + # @ref creates a field in the current table (MovieActor) that holds the primary key of the referenced type + # In this case, @ref(fields: "id") is implied + movie: Movie! + # movieId: UUID! <- this is created by the implied @ref, see: implicit.gql + + actor: Actor! + # actorId: UUID! <- this is created by the implied @ref, see: implicit.gql + + role: String! # "main" or "supporting" + # TODO: optional other fields +} + +# Users +# Suppose a user can leave reviews for movies +# user:reviews is a one to many relationship, movie:reviews is a one to many relationship, movie:user is a many to many relationship +type User + @table { + id: String! @col(name: "user_auth") + username: String! @col(name: "username", dataType: "varchar(50)") + # The following are generated from the @ref in the Review table + # reviews_on_user + # movies_via_Review +} + +# Join table for many-to-many relationship for users and favorite movies +type FavoriteMovie + @table(name: "FavoriteMovies", key: ["user", "movie"]) { + # @ref is implicit + user: User! + movie: Movie! +} + +# Join table for many-to-many relationship for users and favorite actors +type FavoriteActor + @table(name: "FavoriteActors", key: ["user", "actor"]) { + user: User! + actor: Actor! +} + +# Join table for many-to-many relationship for users and watched movies +type WatchedMovie + @table(name: "WatchedMovies", key: ["user", "movie"]) { + user: User! + movie: Movie! +} + +# Reviews +type Review @table(name: "Reviews", key: ["movie", "user"]) { + id: UUID! @default(expr: "uuidV4()") + user: User! + movie: Movie! + rating: Int + reviewText: String + reviewDate: Date! @default(expr: "request.time") +} diff --git a/dataconnect/firebase.json b/dataconnect/firebase.json new file mode 100644 index 000000000..d333fb6ea --- /dev/null +++ b/dataconnect/firebase.json @@ -0,0 +1,32 @@ +{ + "dataconnect": { + "source": "./dataconnect", + "location": "us-central1" + }, + "emulators": { + "dataconnect": { + "port": 9399 + }, + "ui": { + "enabled": false + }, + "singleProjectMode": true, + "auth": { + "port": 9099 + }, + "hosting": { + "port": 5000 + } + }, + "hosting": { + "source": "movie", + "ignore": [ + "firebase.json", + "**/.*", + "**/node_modules/**" + ], + "frameworksBackend": { + "region": "us-central1" + } + } +} diff --git a/dataconnect/movie/.env.local b/dataconnect/movie/.env.local new file mode 100644 index 000000000..77171b344 --- /dev/null +++ b/dataconnect/movie/.env.local @@ -0,0 +1,6 @@ +NEXT_PUBLIC_FIREBASE_API_KEY=your-api-key +NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your-auth-domain +NEXT_PUBLIC_FIREBASE_PROJECT_ID=your-project-id +NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your-storage-bucket +NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=your-messaging-sender-id +NEXT_PUBLIC_FIREBASE_APP_ID=your-app-id diff --git a/dataconnect/movie/app/actor/[id]/page.tsx b/dataconnect/movie/app/actor/[id]/page.tsx new file mode 100644 index 000000000..c2e09099b --- /dev/null +++ b/dataconnect/movie/app/actor/[id]/page.tsx @@ -0,0 +1,138 @@ +'use client'; +import { useEffect, useState } from 'react'; +import { useParams, useRouter } from 'next/navigation'; +import Link from 'next/link'; +import { MdFavorite, MdFavoriteBorder } from 'react-icons/md'; +import { getActorById, GetActorByIdResponse, GetActorByIdVariables, addFavoritedActor, deleteFavoriteActor, getIfFavoritedActor } from '@/lib/dataconnect-sdk'; +import { getAuth, onAuthStateChanged, User } from 'firebase/auth'; + +const Page = () => { + const router = useRouter(); + const { id } = useParams() as { id: string }; + const [actor, setActor] = useState(null); + const [loading, setLoading] = useState(true); + const [authUser, setAuthUser] = useState(null); + const [isFavorited, setIsFavorited] = useState(false); + + useEffect(() => { + const auth = getAuth(); + const unsubscribe = onAuthStateChanged(auth, (user) => { + if (user) { + setAuthUser(user); + checkIfFavorited(user.uid); + } + }); + + return () => unsubscribe(); + }, [id]); + + useEffect(() => { + if (id) { + const fetchActor = async () => { + try { + const response = await getActorById({ id }); + setActor(response.data.actor); + } catch (error) { + console.error('Error fetching actor:', error); + } finally { + setLoading(false); + } + }; + + fetchActor(); + } + }, [id]); + + const checkIfFavorited = async (userId: string) => { + try { + const response = await getIfFavoritedActor({ id: userId, actorId: id }); + setIsFavorited(!!response.data.favoriteActor); + } catch (error) { + console.error('Error checking if favorited:', error); + } + }; + + const handleFavoriteToggle = async () => { + if (!authUser) return; + try { + if (isFavorited) { + await deleteFavoriteActor({ userId: authUser.uid, actorId: id }); + } else { + await addFavoritedActor({ actorId: id }); + } + setIsFavorited(!isFavorited); + } catch (error) { + console.error('Error updating favorite status:', error); + } + }; + + if (loading) return

Loading...

; + if (!actor) return

Actor not found.

; + + return ( +
+
+ {actor.name} +
+

{actor.name}

+
+ +
+

{actor.biography}

+
+
+ +
+

Main Roles

+
+ {actor.mainActors.map((movie) => ( + +
+ {movie.title} +
+

{movie.title}

+

{movie.genre}

+
+ {movie.tags.map((tag, index) => ( + {tag} + ))} +
+
+
+ + ))} +
+
+ +
+

Supporting Roles

+
+ {actor.supportingActors.map((movie) => ( + +
+ {movie.title} +
+

{movie.title}

+

{movie.genre}

+
+ {movie.tags.map((tag, index) => ( + {tag} + ))} +
+
+
+ + ))} +
+
+
+ ); +}; + +export default Page; diff --git a/dataconnect/movie/app/advancedsearch/page.tsx b/dataconnect/movie/app/advancedsearch/page.tsx new file mode 100644 index 000000000..06e52d634 --- /dev/null +++ b/dataconnect/movie/app/advancedsearch/page.tsx @@ -0,0 +1,219 @@ +'use client'; +import { useState } from 'react'; +import Link from 'next/link'; +import { FaSearch } from 'react-icons/fa'; +import { MdStar } from 'react-icons/md'; +import { fuzzySearch } from '@/lib/dataconnect-sdk'; + +const genres = ['', 'action', 'crime', 'drama', 'sci-fi', 'thriller', 'adventure']; + +const Page = () => { + const [searchQuery, setSearchQuery] = useState(''); + const [releaseYearRange, setReleaseYearRange] = useState({ min: 1900, max: 2030 }); + const [genre, setGenre] = useState(''); + const [ratingRange, setRatingRange] = useState({ min: 1, max: 10 }); + const [results, setResults] = useState({ + moviesMatchingTitle: [], + moviesMatchingDescription: [], + actors: [], + reviews: [], + }); + + const handleSearch = async (e: React.FormEvent) => { + e.preventDefault(); + try { + const response = await fuzzySearch({ + input: searchQuery, + minYear: releaseYearRange.min, + maxYear: releaseYearRange.max, + minRating: ratingRange.min, + maxRating: ratingRange.max, + genre, + }); + setResults({ + moviesMatchingTitle: response.data.moviesMatchingTitle, + moviesMatchingDescription: response.data.moviesMatchingDescription, + actors: response.data.actorsMatchingName, + reviews: response.data.reviewsMatchingText, + }); + } catch (error) { + console.error('Error fetching search results:', error); + } + }; + + return ( +
+

Advanced Search

+
+
+ + setSearchQuery(e.target.value)} + /> + +
+
+
+ + setReleaseYearRange({ ...releaseYearRange, min: Number(e.target.value) })} + min="1900" + max="2030" + /> + + setReleaseYearRange({ ...releaseYearRange, max: Number(e.target.value) })} + min="1900" + max="2030" + /> +
+
+ + +
+
+ + setRatingRange({ ...ratingRange, min: Number(e.target.value) })} + min="1" + max="10" + /> + + setRatingRange({ ...ratingRange, max: Number(e.target.value) })} + min="1" + max="10" + /> +
+
+
+
+

Results

+
+

Movies Matching Title

+
+ {results.moviesMatchingTitle?.map((movie) => ( + +
+ {movie.title} +
+

{movie.title}

+
+ + {movie.rating} +
+
+ {movie?.tags?.map((tag, index) => ( + {tag} + ))} +
+
+
+ + ))} +
+
+
+

Movies Matching Description

+
+ {results.moviesMatchingDescription?.map((movie) => ( + +
+ {movie.title} +
+

{movie.title}

+
+ + {movie.rating} +
+
+ {movie?.tags?.map((tag, index) => ( + {tag} + ))} +
+
+
+ + ))} +
+
+
+

Actors

+
+ {results.actors?.map((actor) => ( + +
+ {actor.name} +
+

{actor.name}

+
+
+ + ))} +
+
+
+

Reviews

+
+ {results?.reviews?.map((review) => ( +
+

{review?.user?.username}

+

{review.reviewDate}

+

{review.reviewText}

+
+ + {review.rating} +
+ + {review?.movie?.title} + +
+ ))} +
+
+
+
+ ); +}; + +export default Page; diff --git a/dataconnect/movie/app/genre/[genre]/page.tsx b/dataconnect/movie/app/genre/[genre]/page.tsx new file mode 100644 index 000000000..bc38cf7ce --- /dev/null +++ b/dataconnect/movie/app/genre/[genre]/page.tsx @@ -0,0 +1,70 @@ +'use client'; +import { useEffect, useState } from 'react'; +import { useParams } from 'next/navigation'; +import MovieCard from '@/components/moviecard'; +import { ListMoviesByGenreResponse, ListMoviesByGenreVariables, listMoviesByGenre } from '@/lib/dataconnect-sdk'; + +const Page = () => { + const { genre } = useParams() as { genre: string }; + const [mostPopular, setMostPopular] = useState([]); + const [mostRecent, setMostRecent] = useState([]); + const [loading, setLoading] = useState(true); + + useEffect(() => { + const fetchMovies = async () => { + try { + const response = await listMoviesByGenre({ genre }); + setMostPopular(response.data.mostPopular); + setMostRecent(response.data.mostRecent); + } catch (error) { + console.error('Error fetching movies:', error); + } finally { + setLoading(false); + } + }; + + fetchMovies(); + }, [genre]); + + if (loading) return

Loading...

; + + return ( +
+

{genre} Movies

+ +
+

Most Popular

+
+ {mostPopular.map((movie) => ( + + ))} +
+
+ +
+

Most Recent

+
+ {mostRecent.map((movie) => ( + + ))} +
+
+
+ ); +}; + +export default Page; diff --git a/dataconnect/movie/app/layout.tsx b/dataconnect/movie/app/layout.tsx new file mode 100644 index 000000000..c7e9c7a62 --- /dev/null +++ b/dataconnect/movie/app/layout.tsx @@ -0,0 +1,19 @@ +"use client"; +import Navbar from "@/components/navbar"; +import "../styles.css"; +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + + +
+ {children} +
+ + + ); +} diff --git a/dataconnect/movie/app/movie/[id]/page.tsx b/dataconnect/movie/app/movie/[id]/page.tsx new file mode 100644 index 000000000..6e63d7309 --- /dev/null +++ b/dataconnect/movie/app/movie/[id]/page.tsx @@ -0,0 +1,323 @@ +'use client'; +import { useEffect, useState } from 'react'; +import { useParams, useRouter } from 'next/navigation'; +import Link from 'next/link'; +import { MdFavorite, MdFavoriteBorder, MdCheck, MdAdd, MdStar } from 'react-icons/md'; +import { + getMovieById, + GetMovieByIdResponse, + addFavoritedMovie, + deleteFavoritedMovie, + addWatchedMovie, + deleteWatchedMovie, + getIfWatched, + getIfFavoritedMovie, + addReview, + deleteReview, + searchMovieDescriptionUsingL2similarity, + SearchMovieDescriptionUsingL2similarityResponse, +} from '@/lib/dataconnect-sdk'; +import { getAuth, onAuthStateChanged, User } from 'firebase/auth'; + +const Page = () => { + const router = useRouter(); + const { id } = useParams() as { id: string }; + const [movie, setMovie] = useState(null); + const [loading, setLoading] = useState(true); + const [authUser, setAuthUser] = useState(null); + const [isFavorited, setIsFavorited] = useState(false); + const [isWatched, setIsWatched] = useState(false); + const [reviewText, setReviewText] = useState(''); + const [userReview, setUserReview] = useState(null); + const [rating, setRating] = useState(0); + const [similarMovies, setSimilarMovies] = useState([]); + + useEffect(() => { + const auth = getAuth(); + const unsubscribe = onAuthStateChanged(auth, (user) => { + if (user) { + setAuthUser(user); + checkIfFavorited(user.uid); + checkIfWatched(user.uid); + } + }); + + return () => unsubscribe(); + }, [id]); + + useEffect(() => { + if (id) { + const fetchMovie = async () => { + try { + const response = await getMovieById({ id }); + setMovie(response.data.movie); + const userReview = response.data.movie.reviews.find(review => review.user.id === authUser?.uid); + setUserReview(userReview || null); + await fetchSimilarMovies(response.data.movie.description); + } catch (error) { + console.error('Error fetching movie:', error); + } finally { + setLoading(false); + } + }; + + fetchMovie(); + } + }, [id, authUser]); + + const fetchSimilarMovies = async (description: string) => { + try { + const response = await searchMovieDescriptionUsingL2similarity({ query: description }); + setSimilarMovies(response?.data?.movies_descriptionEmbedding_similarity); + } catch (error) { + console.error('Error fetching similar movies:', error); + } + }; + + const checkIfFavorited = async (userId: string) => { + try { + const response = await getIfFavoritedMovie({ id: userId, movieId: id }); + setIsFavorited(!!response.data.favoriteMovie); + } catch (error) { + console.error('Error checking if favorited:', error); + } + }; + + const checkIfWatched = async (userId: string) => { + try { + const response = await getIfWatched({ id: userId, movieId: id }); + setIsWatched(!!response.data.watchedMovie); + } catch (error) { + console.error('Error checking if watched:', error); + } + }; + + const handleFavoriteToggle = async (e: React.MouseEvent) => { + e.stopPropagation(); + e.preventDefault(); + if (!authUser) return; + try { + if (isFavorited) { + await deleteFavoritedMovie({ userId: authUser.uid, movieId: id }); + } else { + await addFavoritedMovie({ movieId: id }); + } + setIsFavorited(!isFavorited); + } catch (error) { + console.error('Error updating favorite status:', error); + } + }; + + const handleWatchedToggle = async (e: React.MouseEvent) => { + e.stopPropagation(); + e.preventDefault(); + if (!authUser) return; + try { + if (isWatched) { + await deleteWatchedMovie({ userId: authUser.uid, movieId: id }); + } else { + await addWatchedMovie({ movieId: id }); + } + setIsWatched(!isWatched); + } catch (error) { + console.error('Error updating watched status:', error); + } + }; + + const handleReviewSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + if (!authUser) return; + try { + const response = await addReview({ movieId: id, rating, reviewText }); + setReviewText(''); + setRating(0); + const updatedMovie = await getMovieById({ id }); + setMovie(updatedMovie.data.movie); + } catch (error) { + console.error('Error adding review:', error); + } + }; + + const handleReviewDelete = async (e: React.MouseEvent) => { + e.stopPropagation(); + e.preventDefault(); + if (!authUser || !userReview) return; + try { + await deleteReview({ movieId: id, userId: authUser.uid }); + setUserReview(null); + const updatedMovie = await getMovieById({ id }); + setMovie(updatedMovie.data.movie); + } catch (error) { + console.error('Error deleting review:', error); + } + }; + + if (loading) return

Loading...

; + if (!movie) return

Movie not found.

; + + return ( +
+
+ {movie.title} +
+

{movie.title}

+
+ + {movie.rating} +
+

{movie.description}

+
+

Genre: {movie.genre}

+

Release Year: {movie.releaseYear}

+

Director: {movie.metadata[0]?.director}

+

Tags: {movie.tags.join(', ')}

+
+
+ +
+
+
+ +
+

Main Actors

+
+ {movie.mainActors.map((actor) => ( + +
+ {actor.name} +
+

{actor.name}

+
+
+ + ))} +
+
+ +
+

Supporting Actors

+
+ {movie.supportingActors.map((actor) => ( + +
+ {actor.name} +
+

{actor.name}

+
+
+ + ))} +
+
+ + {movie.sequelTo && ( +
+

Sequel

+ +
+ {movie.sequelTo.title} + {movie.sequelTo.title} +
+ +
+ )} + +
+

User Reviews

+ {!userReview ? ( +
+

Leave a Review

+