├── .gitignore ├── .prettierrc ├── Code ├── 02 Essentials │ ├── 01 Starting Project │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ └── routes │ │ │ │ └── index.jsx │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── public │ │ │ └── favicon.ico │ │ └── remix.config.js │ ├── 02 Adding Links │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ └── routes │ │ │ │ ├── demo.jsx │ │ │ │ └── index.jsx │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── public │ │ │ └── favicon.ico │ │ └── remix.config.js │ ├── 03 Onwards to Better Project │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ └── routes │ │ │ │ ├── demo.jsx │ │ │ │ └── index.jsx │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── public │ │ │ └── favicon.ico │ │ └── remix.config.js │ ├── 04 Styling Pages │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── index.jsx │ │ │ │ └── notes.jsx │ │ │ └── styles │ │ │ │ ├── home.css │ │ │ │ └── main.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── public │ │ │ └── favicon.ico │ │ └── remix.config.js │ ├── 05 Surfacing Component Styles │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── NewNote.css │ │ │ │ └── NewNote.jsx │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── index.jsx │ │ │ │ └── notes.jsx │ │ │ └── styles │ │ │ │ ├── home.css │ │ │ │ └── main.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── public │ │ │ └── favicon.ico │ │ └── remix.config.js │ ├── 06 Styling Active Links │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── MainNavigation.jsx │ │ │ │ ├── NewNote.css │ │ │ │ └── NewNote.jsx │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── index.jsx │ │ │ │ └── notes.jsx │ │ │ └── styles │ │ │ │ ├── home.css │ │ │ │ └── main.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── public │ │ │ └── favicon.ico │ │ └── remix.config.js │ ├── 07 Adding Backend Code │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── MainNavigation.jsx │ │ │ │ ├── NewNote.css │ │ │ │ └── NewNote.jsx │ │ │ ├── data │ │ │ │ ├── notes copy.js │ │ │ │ └── notes.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── index.jsx │ │ │ │ └── notes.jsx │ │ │ └── styles │ │ │ │ ├── home.css │ │ │ │ └── main.css │ │ ├── jsconfig.json │ │ ├── notes.json │ │ ├── package.json │ │ ├── public │ │ │ └── favicon.ico │ │ └── remix.config.js │ ├── 08 Returning & Using Fetched Data │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── MainNavigation.jsx │ │ │ │ ├── NewNote.css │ │ │ │ ├── NewNote.jsx │ │ │ │ ├── NoteList.css │ │ │ │ └── NoteList.jsx │ │ │ ├── data │ │ │ │ └── notes.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── index.jsx │ │ │ │ └── notes.jsx │ │ │ └── styles │ │ │ │ ├── home.css │ │ │ │ └── main.css │ │ ├── jsconfig.json │ │ ├── notes.json │ │ ├── package.json │ │ ├── public │ │ │ └── favicon.ico │ │ └── remix.config.js │ ├── 09 Providing User Feedback │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── MainNavigation.jsx │ │ │ │ ├── NewNote.css │ │ │ │ ├── NewNote.jsx │ │ │ │ ├── NoteList.css │ │ │ │ └── NoteList.jsx │ │ │ ├── data │ │ │ │ └── notes.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── index.jsx │ │ │ │ └── notes.jsx │ │ │ └── styles │ │ │ │ ├── home.css │ │ │ │ └── main.css │ │ ├── jsconfig.json │ │ ├── notes.json │ │ ├── package.json │ │ ├── public │ │ │ └── favicon.ico │ │ └── remix.config.js │ ├── 10 Validating Input │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── MainNavigation.jsx │ │ │ │ ├── NewNote.css │ │ │ │ ├── NewNote.jsx │ │ │ │ ├── NoteList.css │ │ │ │ └── NoteList.jsx │ │ │ ├── data │ │ │ │ └── notes.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── index.jsx │ │ │ │ └── notes.jsx │ │ │ └── styles │ │ │ │ ├── home.css │ │ │ │ └── main.css │ │ ├── jsconfig.json │ │ ├── notes.json │ │ ├── package.json │ │ ├── public │ │ │ └── favicon.ico │ │ └── remix.config.js │ ├── 11 Handling Error Responses │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── MainNavigation.jsx │ │ │ │ ├── NewNote.css │ │ │ │ ├── NewNote.jsx │ │ │ │ ├── NoteList.css │ │ │ │ └── NoteList.jsx │ │ │ ├── data │ │ │ │ └── notes.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── index.jsx │ │ │ │ └── notes.jsx │ │ │ └── styles │ │ │ │ ├── home.css │ │ │ │ └── main.css │ │ ├── jsconfig.json │ │ ├── notes.json │ │ ├── package.json │ │ ├── public │ │ │ └── favicon.ico │ │ └── remix.config.js │ ├── 12 Adding Dynamic Routes │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── MainNavigation.jsx │ │ │ │ ├── NewNote.css │ │ │ │ ├── NewNote.jsx │ │ │ │ ├── NoteList.css │ │ │ │ └── NoteList.jsx │ │ │ ├── data │ │ │ │ └── notes.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── index.jsx │ │ │ │ ├── notes.$noteId.jsx │ │ │ │ └── notes.jsx │ │ │ └── styles │ │ │ │ ├── home.css │ │ │ │ ├── main.css │ │ │ │ └── note-details.css │ │ ├── jsconfig.json │ │ ├── notes.json │ │ ├── package.json │ │ ├── public │ │ │ └── favicon.ico │ │ └── remix.config.js │ ├── 13 Fetching Data for Dynamic Routes │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── MainNavigation.jsx │ │ │ │ ├── NewNote.css │ │ │ │ ├── NewNote.jsx │ │ │ │ ├── NoteList.css │ │ │ │ └── NoteList.jsx │ │ │ ├── data │ │ │ │ └── notes.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── index.jsx │ │ │ │ ├── notes.$noteId.jsx │ │ │ │ └── notes.jsx │ │ │ └── styles │ │ │ │ ├── home.css │ │ │ │ ├── main.css │ │ │ │ └── note-details.css │ │ ├── jsconfig.json │ │ ├── notes.json │ │ ├── package.json │ │ ├── public │ │ │ └── favicon.ico │ │ └── remix.config.js │ ├── 14 Finished │ │ ├── .eslintrc.js │ │ ├── app │ │ │ ├── components │ │ │ │ ├── MainNavigation.jsx │ │ │ │ ├── NewNote.css │ │ │ │ ├── NewNote.jsx │ │ │ │ ├── NoteList.css │ │ │ │ └── NoteList.jsx │ │ │ ├── data │ │ │ │ └── notes.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── index.jsx │ │ │ │ ├── notes.$noteId.jsx │ │ │ │ └── notes.jsx │ │ │ └── styles │ │ │ │ ├── home.css │ │ │ │ ├── main.css │ │ │ │ └── note-details.css │ │ ├── jsconfig.json │ │ ├── notes.json │ │ ├── package.json │ │ ├── public │ │ │ └── favicon.ico │ │ └── remix.config.js │ ├── Extra Files │ │ ├── MainNavigation.jsx │ │ ├── NewNote.css │ │ ├── NewNote.jsx │ │ ├── NoteList.css │ │ ├── NoteList.jsx │ │ ├── home.css │ │ ├── index.jsx │ │ ├── main.css │ │ └── note-details.css │ └── ZZ V2-finished │ │ ├── .eslintrc.cjs │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ ├── components │ │ │ ├── MainNavigation.jsx │ │ │ ├── NewNote.css │ │ │ ├── NewNote.jsx │ │ │ ├── NoteList.css │ │ │ └── NoteList.jsx │ │ ├── data │ │ │ └── notes.js │ │ ├── entry.client.tsx │ │ ├── entry.server.tsx │ │ ├── root.jsx │ │ ├── routes │ │ │ ├── _index.jsx │ │ │ ├── notes.$noteId.jsx │ │ │ └── notes._index.jsx │ │ ├── styles │ │ │ ├── home.css │ │ │ ├── main.css │ │ │ └── note-details.css │ │ └── tailwind.css │ │ ├── package.json │ │ ├── postcss.config.js │ │ ├── public │ │ ├── favicon.ico │ │ ├── logo-dark.png │ │ └── logo-light.png │ │ ├── tailwind.config.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts ├── 03 Routing Deep Dive │ ├── 01 Starting Project │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ └── routes │ │ │ │ └── index.jsx │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── public │ │ │ └── favicon.ico │ │ └── remix.config.js │ ├── 02 Creating Project Routes │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ └── routes │ │ │ │ ├── auth.jsx │ │ │ │ ├── expenses.$id.jsx │ │ │ │ ├── expenses.add.jsx │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ ├── expenses.jsx │ │ │ │ ├── expenses.raw.jsx │ │ │ │ ├── index.jsx │ │ │ │ └── pricing.jsx │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── public │ │ │ └── favicon.ico │ │ └── remix.config.js │ ├── 03 Layout Routes │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ └── routes │ │ │ │ ├── auth.jsx │ │ │ │ ├── expenses.jsx │ │ │ │ ├── expenses.raw.jsx │ │ │ │ ├── expenses │ │ │ │ ├── $id.jsx │ │ │ │ ├── add.jsx │ │ │ │ └── analysis.jsx │ │ │ │ ├── index.jsx │ │ │ │ └── pricing.jsx │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── public │ │ │ └── favicon.ico │ │ └── remix.config.js │ ├── 04 Adding Components & Styling │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── auth.jsx │ │ │ │ ├── expenses.jsx │ │ │ │ ├── expenses.raw.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── $id.jsx │ │ │ │ │ ├── add.jsx │ │ │ │ │ └── analysis.jsx │ │ │ │ ├── index.jsx │ │ │ │ └── pricing.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── public │ │ │ └── favicon.ico │ │ └── remix.config.js │ ├── 05 Marketing Pages │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── auth.jsx │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ ├── expenses.jsx │ │ │ │ ├── expenses.raw.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── $id.jsx │ │ │ │ │ └── add.jsx │ │ │ │ ├── index.jsx │ │ │ │ └── pricing.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 06 Rendering a Modal Page │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── auth.jsx │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ ├── expenses.jsx │ │ │ │ ├── expenses.raw.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── $id.jsx │ │ │ │ │ └── add.jsx │ │ │ │ ├── index.jsx │ │ │ │ └── pricing.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 07 Paths │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── auth.jsx │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ ├── expenses.jsx │ │ │ │ ├── expenses.raw.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── $id.jsx │ │ │ │ │ └── add.jsx │ │ │ │ ├── index.jsx │ │ │ │ └── pricing.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 08 Navigating Programmatically │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── auth.jsx │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ ├── expenses.jsx │ │ │ │ ├── expenses.raw.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── $id.jsx │ │ │ │ │ └── add.jsx │ │ │ │ ├── index.jsx │ │ │ │ └── pricing.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 09 Introducing Pathless Layout Routes │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ ├── auth.jsx │ │ │ │ └── expenses.raw.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 10 Doing More With Pathless │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── FormattedDate.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── auth.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ └── expenses.raw.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 11 Splat Routes │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── FormattedDate.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── $.jsx │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── auth.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ └── expenses.raw.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 12 Finished │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── FormattedDate.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── $.jsx │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── auth.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ └── expenses.raw.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── Extra Files │ │ ├── ExpensesHeader.jsx │ │ ├── components.zip │ │ ├── components │ │ │ ├── auth │ │ │ │ └── AuthForm.jsx │ │ │ ├── expenses │ │ │ │ ├── Chart.jsx │ │ │ │ ├── ChartBar.jsx │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ └── ExpensesList.jsx │ │ │ ├── marketing │ │ │ │ └── PricingPlan.jsx │ │ │ ├── navigation │ │ │ │ └── MainHeader.jsx │ │ │ └── util │ │ │ │ ├── Error.jsx │ │ │ │ ├── Logo.jsx │ │ │ │ └── Modal.jsx │ │ ├── images.zip │ │ ├── images │ │ │ ├── expenses-chart.jpg │ │ │ └── expenses-management.jpg │ │ ├── index.jsx │ │ ├── pricing.jsx │ │ ├── styles.zip │ │ └── styles │ │ │ ├── auth.css │ │ │ ├── expenses.css │ │ │ ├── marketing.css │ │ │ └── shared.css │ └── ZZ V2-finished │ │ ├── .eslintrc.cjs │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ ├── components │ │ │ ├── auth │ │ │ │ └── AuthForm.jsx │ │ │ ├── expenses │ │ │ │ ├── Chart.jsx │ │ │ │ ├── ChartBar.jsx │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ └── ExpensesList.jsx │ │ │ ├── marketing │ │ │ │ └── PricingPlan.jsx │ │ │ ├── navigation │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ └── MainHeader.jsx │ │ │ └── util │ │ │ │ ├── Error.jsx │ │ │ │ ├── FormattedDate.jsx │ │ │ │ ├── Logo.jsx │ │ │ │ └── Modal.jsx │ │ ├── entry.client.tsx │ │ ├── entry.server.tsx │ │ ├── root.jsx │ │ ├── routes │ │ │ ├── $.jsx │ │ │ ├── _app.expenses.$id.jsx │ │ │ ├── _app.expenses._index.jsx │ │ │ ├── _app.expenses.add.jsx │ │ │ ├── _app.expenses.analysis.jsx │ │ │ ├── _app.jsx │ │ │ ├── _marketing._index.jsx │ │ │ ├── _marketing.auth.jsx │ │ │ ├── _marketing.jsx │ │ │ ├── _marketing.pricing.jsx │ │ │ └── expenses.raw.jsx │ │ ├── styles │ │ │ ├── auth.css │ │ │ ├── expenses.css │ │ │ ├── marketing.css │ │ │ └── shared.css │ │ └── tailwind.css │ │ ├── package.json │ │ ├── postcss.config.js │ │ ├── public │ │ ├── favicon.ico │ │ ├── images │ │ │ ├── expenses-chart.jpg │ │ │ └── expenses-management.jpg │ │ └── logo-light.png │ │ ├── tailwind.config.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts ├── 04 Data Deep Dive │ ├── 01 Starting Project │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── FormattedDate.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── auth.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ └── expenses.raw.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 02 Adding Expense Model │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── FormattedDate.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── auth.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ └── expenses.raw.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── prisma │ │ │ └── schema.prisma │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 03 Adding Expenses to the Database │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── FormattedDate.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── data │ │ │ │ ├── database.server.js │ │ │ │ └── expenses.server.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── auth.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ └── expenses.raw.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── prisma │ │ │ └── schema.prisma │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 04 Server-side Validation │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── FormattedDate.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── data │ │ │ │ ├── database.server.js │ │ │ │ ├── expenses.server.js │ │ │ │ └── validation.server.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── auth.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ └── expenses.raw.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── prisma │ │ │ └── schema.prisma │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 05 Submitting Forms Programmatically │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── FormattedDate.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── data │ │ │ │ ├── database.server.js │ │ │ │ ├── expenses.server.js │ │ │ │ └── validation.server.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── auth.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ └── expenses.raw.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── prisma │ │ │ └── schema.prisma │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 06 Fetching Expenses │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── FormattedDate.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── data │ │ │ │ ├── database.server.js │ │ │ │ ├── expenses.server.js │ │ │ │ └── validation.server.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── auth.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ └── expenses.raw.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── prisma │ │ │ └── schema.prisma │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 07 Loading a Single Expense │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── FormattedDate.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── data │ │ │ │ ├── database.server.js │ │ │ │ ├── expenses.server.js │ │ │ │ └── validation.server.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── auth.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ └── expenses.raw.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── prisma │ │ │ └── schema.prisma │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 08 Using Parent Loader Data │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── FormattedDate.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── data │ │ │ │ ├── database.server.js │ │ │ │ ├── expenses.server.js │ │ │ │ └── validation.server.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── auth.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ └── expenses.raw.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── prisma │ │ │ └── schema.prisma │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 09 Updating Data │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── FormattedDate.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── data │ │ │ │ ├── database.server.js │ │ │ │ ├── expenses.server.js │ │ │ │ └── validation.server.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── auth.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ └── expenses.raw.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── prisma │ │ │ └── schema.prisma │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 10 Deleting Data │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── FormattedDate.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── data │ │ │ │ ├── database.server.js │ │ │ │ ├── expenses.server.js │ │ │ │ └── validation.server.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── auth.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ └── expenses.raw.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── prisma │ │ │ └── schema.prisma │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 11 Programmatic Behind-the-Scenes Submission │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── FormattedDate.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── data │ │ │ │ ├── database.server.js │ │ │ │ ├── expenses.server.js │ │ │ │ └── validation.server.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── auth.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ └── expenses.raw.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── prisma │ │ │ └── schema.prisma │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 12 Extracting Search Parameters │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── FormattedDate.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── data │ │ │ │ ├── database.server.js │ │ │ │ ├── expenses.server.js │ │ │ │ └── validation.server.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── auth.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ └── expenses.raw.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── prisma │ │ │ └── schema.prisma │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 13 Managing Errors Inside Components │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── FormattedDate.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── data │ │ │ │ ├── database.server.js │ │ │ │ ├── expenses.server.js │ │ │ │ └── validation.server.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── auth.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ └── expenses.raw.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── prisma │ │ │ └── schema.prisma │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 14 Practice Time Solution │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── FormattedDate.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── data │ │ │ │ ├── database.server.js │ │ │ │ ├── expenses.server.js │ │ │ │ └── validation.server.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── auth.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ └── expenses.raw.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── prisma │ │ │ └── schema.prisma │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 15 Finished │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── data │ │ │ │ ├── database.server.js │ │ │ │ ├── expenses.server.js │ │ │ │ └── validation.server.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── auth.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ └── expenses.raw.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── prisma │ │ │ └── schema.prisma │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── Extra Files │ │ ├── database.server.js │ │ └── validation.server.js │ └── ZZ V2-finished │ │ ├── .eslintrc.cjs │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ ├── components │ │ │ ├── auth │ │ │ │ └── AuthForm.jsx │ │ │ ├── expenses │ │ │ │ ├── Chart.jsx │ │ │ │ ├── ChartBar.jsx │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ └── ExpensesList.jsx │ │ │ ├── marketing │ │ │ │ └── PricingPlan.jsx │ │ │ ├── navigation │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ └── MainHeader.jsx │ │ │ └── util │ │ │ │ ├── Error.jsx │ │ │ │ ├── Logo.jsx │ │ │ │ └── Modal.jsx │ │ ├── data │ │ │ ├── database.server.js │ │ │ ├── expenses.server.js │ │ │ └── validation.server.js │ │ ├── entry.client.tsx │ │ ├── entry.server.tsx │ │ ├── root.jsx │ │ ├── routes │ │ │ ├── _app.expenses.$id.jsx │ │ │ ├── _app.expenses.add.jsx │ │ │ ├── _app.expenses.analysis.jsx │ │ │ ├── _app.expenses.jsx │ │ │ ├── _app.jsx │ │ │ ├── _marketing._index.jsx │ │ │ ├── _marketing.auth.jsx │ │ │ ├── _marketing.jsx │ │ │ ├── _marketing.pricing.jsx │ │ │ └── expenses.raw.jsx │ │ ├── styles │ │ │ ├── auth.css │ │ │ ├── expenses.css │ │ │ ├── marketing.css │ │ │ └── shared.css │ │ └── tailwind.css │ │ ├── package.json │ │ ├── postcss.config.js │ │ ├── prisma │ │ └── schema.prisma │ │ ├── public │ │ ├── favicon.ico │ │ └── images │ │ │ ├── expenses-chart.jpg │ │ │ └── expenses-management.jpg │ │ ├── tailwind.config.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts ├── 05 Authentication │ ├── 01 Starting Project │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── data │ │ │ │ ├── database.server.js │ │ │ │ ├── expenses.server.js │ │ │ │ └── validation.server.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── auth.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ └── expenses.raw.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── prisma │ │ │ └── schema.prisma │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 02 Preparing the Database │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── data │ │ │ │ ├── database.server.js │ │ │ │ ├── expenses.server.js │ │ │ │ └── validation.server.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── auth.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ └── expenses.raw.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── prisma │ │ │ └── schema.prisma │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 03 User Signup │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── data │ │ │ │ ├── auth.server.js │ │ │ │ ├── database.server.js │ │ │ │ ├── expenses.server.js │ │ │ │ └── validation.server.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── auth.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ └── expenses.raw.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── prisma │ │ │ └── schema.prisma │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 04 Creating Session Cookies │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── data │ │ │ │ ├── auth.server.js │ │ │ │ ├── database.server.js │ │ │ │ ├── expenses.server.js │ │ │ │ └── validation.server.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── auth.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ └── expenses.raw.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── prisma │ │ │ └── schema.prisma │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 05 Extracting Session Data │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── data │ │ │ │ ├── auth.server.js │ │ │ │ ├── database.server.js │ │ │ │ ├── expenses.server.js │ │ │ │ └── validation.server.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── auth.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ └── expenses.raw.jsx │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── prisma │ │ │ └── schema.prisma │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 06 Adding Logout │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── data │ │ │ │ ├── auth.server.js │ │ │ │ ├── database.server.js │ │ │ │ ├── expenses.server.js │ │ │ │ └── validation.server.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── auth.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ ├── expenses.raw.js │ │ │ │ └── logout.js │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── prisma │ │ │ └── schema.prisma │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 07 More Route Protection │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── data │ │ │ │ ├── auth.server.js │ │ │ │ ├── database.server.js │ │ │ │ ├── expenses.server.js │ │ │ │ └── validation.server.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── auth.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ ├── expenses.raw.jsx │ │ │ │ └── logout.js │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── prisma │ │ │ └── schema.prisma │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── 08 Finished │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── components │ │ │ │ ├── auth │ │ │ │ │ └── AuthForm.jsx │ │ │ │ ├── expenses │ │ │ │ │ ├── Chart.jsx │ │ │ │ │ ├── ChartBar.jsx │ │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ │ └── ExpensesList.jsx │ │ │ │ ├── marketing │ │ │ │ │ └── PricingPlan.jsx │ │ │ │ ├── navigation │ │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ │ └── MainHeader.jsx │ │ │ │ └── util │ │ │ │ │ ├── Error.jsx │ │ │ │ │ ├── Logo.jsx │ │ │ │ │ └── Modal.jsx │ │ │ ├── data │ │ │ │ ├── auth.server.js │ │ │ │ ├── database.server.js │ │ │ │ ├── expenses.server.js │ │ │ │ └── validation.server.js │ │ │ ├── entry.client.jsx │ │ │ ├── entry.server.jsx │ │ │ ├── root.jsx │ │ │ ├── routes │ │ │ │ ├── __app.jsx │ │ │ │ ├── __app │ │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ │ ├── expenses.jsx │ │ │ │ │ └── expenses │ │ │ │ │ │ ├── $id.jsx │ │ │ │ │ │ └── add.jsx │ │ │ │ ├── __marketing.jsx │ │ │ │ ├── __marketing │ │ │ │ │ ├── auth.jsx │ │ │ │ │ ├── index.jsx │ │ │ │ │ └── pricing.jsx │ │ │ │ ├── expenses.raw.jsx │ │ │ │ └── logout.js │ │ │ └── styles │ │ │ │ ├── auth.css │ │ │ │ ├── expenses.css │ │ │ │ ├── marketing.css │ │ │ │ └── shared.css │ │ ├── jsconfig.json │ │ ├── package.json │ │ ├── prisma │ │ │ └── schema.prisma │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── images │ │ │ │ ├── expenses-chart.jpg │ │ │ │ └── expenses-management.jpg │ │ └── remix.config.js │ ├── Extra Files │ │ └── validation.server.js │ └── ZZ V2-finished │ │ ├── .eslintrc.cjs │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ ├── components │ │ │ ├── auth │ │ │ │ └── AuthForm.jsx │ │ │ ├── expenses │ │ │ │ ├── Chart.jsx │ │ │ │ ├── ChartBar.jsx │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ └── ExpensesList.jsx │ │ │ ├── marketing │ │ │ │ └── PricingPlan.jsx │ │ │ ├── navigation │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ └── MainHeader.jsx │ │ │ └── util │ │ │ │ ├── Error.jsx │ │ │ │ ├── Logo.jsx │ │ │ │ └── Modal.jsx │ │ ├── data │ │ │ ├── auth.server.js │ │ │ ├── database.server.js │ │ │ ├── expenses.server.js │ │ │ └── validation.server.js │ │ ├── entry.client.tsx │ │ ├── entry.server.tsx │ │ ├── prisma │ │ │ └── schema.prisma │ │ ├── root.jsx │ │ ├── routes │ │ │ ├── _app.expenses.$id.jsx │ │ │ ├── _app.expenses.add.jsx │ │ │ ├── _app.expenses.analysis.jsx │ │ │ ├── _app.expenses.jsx │ │ │ ├── _app.jsx │ │ │ ├── _marketing._index.jsx │ │ │ ├── _marketing.auth.jsx │ │ │ ├── _marketing.jsx │ │ │ ├── _marketing.pricing.jsx │ │ │ ├── expenses.raw.jsx │ │ │ └── logout.js │ │ ├── styles │ │ │ ├── auth.css │ │ │ ├── expenses.css │ │ │ ├── marketing.css │ │ │ └── shared.css │ │ └── tailwind.css │ │ ├── package.json │ │ ├── postcss.config.js │ │ ├── prisma │ │ └── schema.prisma │ │ ├── public │ │ ├── favicon.ico │ │ └── images │ │ │ ├── expenses-chart.jpg │ │ │ └── expenses-management.jpg │ │ ├── tailwind.config.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts └── 06 Deployment │ ├── 01 Starting Project │ ├── .eslintrc.js │ ├── .gitignore │ ├── README.md │ ├── app │ │ ├── components │ │ │ ├── auth │ │ │ │ └── AuthForm.jsx │ │ │ ├── expenses │ │ │ │ ├── Chart.jsx │ │ │ │ ├── ChartBar.jsx │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ └── ExpensesList.jsx │ │ │ ├── marketing │ │ │ │ └── PricingPlan.jsx │ │ │ ├── navigation │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ └── MainHeader.jsx │ │ │ └── util │ │ │ │ ├── Error.jsx │ │ │ │ ├── Logo.jsx │ │ │ │ └── Modal.jsx │ │ ├── data │ │ │ ├── auth.server.js │ │ │ ├── database.server.js │ │ │ ├── expenses.server.js │ │ │ └── validation.server.js │ │ ├── entry.client.jsx │ │ ├── entry.server.jsx │ │ ├── root.jsx │ │ ├── routes │ │ │ ├── __app.jsx │ │ │ ├── __app │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ ├── expenses.jsx │ │ │ │ └── expenses │ │ │ │ │ ├── $id.jsx │ │ │ │ │ └── add.jsx │ │ │ ├── __marketing.jsx │ │ │ ├── __marketing │ │ │ │ ├── auth.jsx │ │ │ │ ├── index.jsx │ │ │ │ └── pricing.jsx │ │ │ ├── expenses.raw.jsx │ │ │ └── logout.js │ │ └── styles │ │ │ ├── auth.css │ │ │ ├── expenses.css │ │ │ ├── marketing.css │ │ │ └── shared.css │ ├── jsconfig.json │ ├── package.json │ ├── prisma │ │ └── schema.prisma │ ├── public │ │ ├── favicon.ico │ │ └── images │ │ │ ├── expenses-chart.jpg │ │ │ └── expenses-management.jpg │ └── remix.config.js │ ├── 02 Adding Metadata │ ├── .eslintrc.js │ ├── .gitignore │ ├── README.md │ ├── app │ │ ├── components │ │ │ ├── auth │ │ │ │ └── AuthForm.jsx │ │ │ ├── expenses │ │ │ │ ├── Chart.jsx │ │ │ │ ├── ChartBar.jsx │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ └── ExpensesList.jsx │ │ │ ├── marketing │ │ │ │ └── PricingPlan.jsx │ │ │ ├── navigation │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ └── MainHeader.jsx │ │ │ └── util │ │ │ │ ├── Error.jsx │ │ │ │ ├── Logo.jsx │ │ │ │ └── Modal.jsx │ │ ├── data │ │ │ ├── auth.server.js │ │ │ ├── database.server.js │ │ │ ├── expenses.server.js │ │ │ └── validation.server.js │ │ ├── entry.client.jsx │ │ ├── entry.server.jsx │ │ ├── root.jsx │ │ ├── routes │ │ │ ├── __app.jsx │ │ │ ├── __app │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ ├── expenses.jsx │ │ │ │ └── expenses │ │ │ │ │ ├── $id.jsx │ │ │ │ │ └── add.jsx │ │ │ ├── __marketing.jsx │ │ │ ├── __marketing │ │ │ │ ├── auth.jsx │ │ │ │ ├── index.jsx │ │ │ │ └── pricing.jsx │ │ │ ├── expenses.raw.jsx │ │ │ └── logout.js │ │ └── styles │ │ │ ├── auth.css │ │ │ ├── expenses.css │ │ │ ├── marketing.css │ │ │ └── shared.css │ ├── jsconfig.json │ ├── package.json │ ├── prisma │ │ └── schema.prisma │ ├── public │ │ ├── favicon.ico │ │ └── images │ │ │ ├── expenses-chart.jpg │ │ │ └── expenses-management.jpg │ └── remix.config.js │ ├── 03 Using Action & Loader Headers │ ├── .eslintrc.js │ ├── .gitignore │ ├── README.md │ ├── app │ │ ├── components │ │ │ ├── auth │ │ │ │ └── AuthForm.jsx │ │ │ ├── expenses │ │ │ │ ├── Chart.jsx │ │ │ │ ├── ChartBar.jsx │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ └── ExpensesList.jsx │ │ │ ├── marketing │ │ │ │ └── PricingPlan.jsx │ │ │ ├── navigation │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ └── MainHeader.jsx │ │ │ └── util │ │ │ │ ├── Error.jsx │ │ │ │ ├── Logo.jsx │ │ │ │ └── Modal.jsx │ │ ├── data │ │ │ ├── auth.server.js │ │ │ ├── database.server.js │ │ │ ├── expenses.server.js │ │ │ └── validation.server.js │ │ ├── entry.client.jsx │ │ ├── entry.server.jsx │ │ ├── root.jsx │ │ ├── routes │ │ │ ├── __app.jsx │ │ │ ├── __app │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ ├── expenses.jsx │ │ │ │ └── expenses │ │ │ │ │ ├── $id.jsx │ │ │ │ │ └── add.jsx │ │ │ ├── __marketing.jsx │ │ │ ├── __marketing │ │ │ │ ├── auth.jsx │ │ │ │ ├── index.jsx │ │ │ │ └── pricing.jsx │ │ │ ├── expenses.raw.jsx │ │ │ └── logout.js │ │ └── styles │ │ │ ├── auth.css │ │ │ ├── expenses.css │ │ │ ├── marketing.css │ │ │ └── shared.css │ ├── jsconfig.json │ ├── package.json │ ├── prisma │ │ └── schema.prisma │ ├── public │ │ ├── favicon.ico │ │ └── images │ │ │ ├── expenses-chart.jpg │ │ │ └── expenses-management.jpg │ └── remix.config.js │ ├── 04 Disable JavaScript │ ├── .eslintrc.js │ ├── .gitignore │ ├── README.md │ ├── app │ │ ├── components │ │ │ ├── auth │ │ │ │ └── AuthForm.jsx │ │ │ ├── expenses │ │ │ │ ├── Chart.jsx │ │ │ │ ├── ChartBar.jsx │ │ │ │ ├── ExpenseForm.jsx │ │ │ │ ├── ExpenseListItem.jsx │ │ │ │ ├── ExpenseStatistics.jsx │ │ │ │ └── ExpensesList.jsx │ │ │ ├── marketing │ │ │ │ └── PricingPlan.jsx │ │ │ ├── navigation │ │ │ │ ├── ExpensesHeader.jsx │ │ │ │ └── MainHeader.jsx │ │ │ └── util │ │ │ │ ├── Error.jsx │ │ │ │ ├── Logo.jsx │ │ │ │ └── Modal.jsx │ │ ├── data │ │ │ ├── auth.server.js │ │ │ ├── database.server.js │ │ │ ├── expenses.server.js │ │ │ └── validation.server.js │ │ ├── entry.client.jsx │ │ ├── entry.server.jsx │ │ ├── root.jsx │ │ ├── routes │ │ │ ├── __app.jsx │ │ │ ├── __app │ │ │ │ ├── expenses.analysis.jsx │ │ │ │ ├── expenses.jsx │ │ │ │ └── expenses │ │ │ │ │ ├── $id.jsx │ │ │ │ │ └── add.jsx │ │ │ ├── __marketing.jsx │ │ │ ├── __marketing │ │ │ │ ├── auth.jsx │ │ │ │ ├── index.jsx │ │ │ │ └── pricing.jsx │ │ │ ├── expenses.raw.jsx │ │ │ └── logout.js │ │ └── styles │ │ │ ├── auth.css │ │ │ ├── expenses.css │ │ │ ├── marketing.css │ │ │ └── shared.css │ ├── jsconfig.json │ ├── package.json │ ├── prisma │ │ └── schema.prisma │ ├── public │ │ ├── favicon.ico │ │ └── images │ │ │ ├── expenses-chart.jpg │ │ │ └── expenses-management.jpg │ └── remix.config.js │ └── ZZ V2-finished │ ├── .eslintrc.cjs │ ├── .gitignore │ ├── README.md │ ├── app │ ├── components │ │ ├── auth │ │ │ └── AuthForm.jsx │ │ ├── expenses │ │ │ ├── Chart.jsx │ │ │ ├── ChartBar.jsx │ │ │ ├── ExpenseForm.jsx │ │ │ ├── ExpenseListItem.jsx │ │ │ ├── ExpenseStatistics.jsx │ │ │ └── ExpensesList.jsx │ │ ├── marketing │ │ │ └── PricingPlan.jsx │ │ ├── navigation │ │ │ ├── ExpensesHeader.jsx │ │ │ └── MainHeader.jsx │ │ └── util │ │ │ ├── Error.jsx │ │ │ ├── Logo.jsx │ │ │ └── Modal.jsx │ ├── data │ │ ├── auth.server.js │ │ ├── database.server.js │ │ ├── expenses.server.js │ │ └── validation.server.js │ ├── entry.client.tsx │ ├── entry.server.tsx │ ├── root.jsx │ ├── routes │ │ ├── _app.expenses.$id.jsx │ │ ├── _app.expenses.add.jsx │ │ ├── _app.expenses.analysis.jsx │ │ ├── _app.expenses.jsx │ │ ├── _app.jsx │ │ ├── _marketing._index.jsx │ │ ├── _marketing.auth.jsx │ │ ├── _marketing.jsx │ │ ├── _marketing.pricing.jsx │ │ ├── expenses.raw.jsx │ │ └── logout.js │ ├── styles │ │ ├── auth.css │ │ ├── expenses.css │ │ ├── marketing.css │ │ └── shared.css │ └── tailwind.css │ ├── package.json │ ├── postcss.config.js │ ├── prisma │ └── schema.prisma │ ├── public │ ├── favicon.ico │ └── images │ │ ├── expenses-chart.jpg │ │ └── expenses-management.jpg │ ├── tailwind.config.ts │ ├── tsconfig.json │ └── vite.config.ts ├── README.md └── Slides └── remix-slides.pdf /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 2, 3 | "jsxSingleQuote": true, 4 | "singleQuote": true 5 | } 6 | -------------------------------------------------------------------------------- /Code/02 Essentials/01 Starting Project/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/02 Essentials/01 Starting Project/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/02 Essentials/01 Starting Project/app/routes/index.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | export default function Index() { 4 | return ( 5 | <> 6 |

Hello World!

7 | 8 | ); 9 | } 10 | -------------------------------------------------------------------------------- /Code/02 Essentials/01 Starting Project/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/02 Essentials/01 Starting Project/public/favicon.ico -------------------------------------------------------------------------------- /Code/02 Essentials/01 Starting Project/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/02 Essentials/02 Adding Links/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/02 Essentials/02 Adding Links/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/02 Essentials/02 Adding Links/app/routes/demo.jsx: -------------------------------------------------------------------------------- 1 | export default function DemoPage() { 2 | return

Demo Page

; 3 | } 4 | -------------------------------------------------------------------------------- /Code/02 Essentials/02 Adding Links/app/routes/index.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | export default function Index() { 4 | return ( 5 | <> 6 |

Hello World!

7 | Go to Demo Page 8 | 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /Code/02 Essentials/02 Adding Links/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/02 Essentials/02 Adding Links/public/favicon.ico -------------------------------------------------------------------------------- /Code/02 Essentials/02 Adding Links/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/02 Essentials/03 Onwards to Better Project/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/02 Essentials/03 Onwards to Better Project/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/02 Essentials/03 Onwards to Better Project/app/routes/demo.jsx: -------------------------------------------------------------------------------- 1 | export default function DemoPage() { 2 | return

Demo Page

; 3 | } 4 | -------------------------------------------------------------------------------- /Code/02 Essentials/03 Onwards to Better Project/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/02 Essentials/03 Onwards to Better Project/public/favicon.ico -------------------------------------------------------------------------------- /Code/02 Essentials/03 Onwards to Better Project/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/02 Essentials/04 Styling Pages/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/02 Essentials/04 Styling Pages/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/02 Essentials/04 Styling Pages/app/routes/notes.jsx: -------------------------------------------------------------------------------- 1 | export default function NotesPage() { 2 | return ( 3 |
4 |

My Notes

5 |
6 | ); 7 | } 8 | -------------------------------------------------------------------------------- /Code/02 Essentials/04 Styling Pages/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/02 Essentials/04 Styling Pages/public/favicon.ico -------------------------------------------------------------------------------- /Code/02 Essentials/04 Styling Pages/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/02 Essentials/05 Surfacing Component Styles/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/02 Essentials/05 Surfacing Component Styles/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/02 Essentials/05 Surfacing Component Styles/app/routes/notes.jsx: -------------------------------------------------------------------------------- 1 | import NewNote, { links as newNoteLinks } from '~/components/NewNote'; 2 | 3 | export default function NotesPage() { 4 | return ( 5 |
6 | 7 |
8 | ); 9 | } 10 | 11 | export function links() { 12 | return [...newNoteLinks()]; 13 | } 14 | -------------------------------------------------------------------------------- /Code/02 Essentials/05 Surfacing Component Styles/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/02 Essentials/05 Surfacing Component Styles/public/favicon.ico -------------------------------------------------------------------------------- /Code/02 Essentials/05 Surfacing Component Styles/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/02 Essentials/06 Styling Active Links/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/02 Essentials/06 Styling Active Links/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/02 Essentials/06 Styling Active Links/app/routes/notes.jsx: -------------------------------------------------------------------------------- 1 | import NewNote, { links as newNoteLinks } from '~/components/NewNote'; 2 | 3 | export default function NotesPage() { 4 | return ( 5 |
6 | 7 |
8 | ); 9 | } 10 | 11 | export function links() { 12 | return [...newNoteLinks()]; 13 | } 14 | -------------------------------------------------------------------------------- /Code/02 Essentials/06 Styling Active Links/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/02 Essentials/06 Styling Active Links/public/favicon.ico -------------------------------------------------------------------------------- /Code/02 Essentials/06 Styling Active Links/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/02 Essentials/07 Adding Backend Code/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/02 Essentials/07 Adding Backend Code/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/02 Essentials/07 Adding Backend Code/notes.json: -------------------------------------------------------------------------------- 1 | {"notes":[{"title":"Test","content":"Test","id":"2022-10-19T09:23:11.183Z"}]} -------------------------------------------------------------------------------- /Code/02 Essentials/07 Adding Backend Code/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/02 Essentials/07 Adding Backend Code/public/favicon.ico -------------------------------------------------------------------------------- /Code/02 Essentials/07 Adding Backend Code/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/02 Essentials/08 Returning & Using Fetched Data/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/02 Essentials/08 Returning & Using Fetched Data/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/02 Essentials/08 Returning & Using Fetched Data/notes.json: -------------------------------------------------------------------------------- 1 | {"notes":[{"title":"Test","content":"Test","id":"2022-10-19T09:23:11.183Z"},{"title":"A second note","content":"Remix is awesome!","id":"2022-10-19T10:28:10.980Z"}]} -------------------------------------------------------------------------------- /Code/02 Essentials/08 Returning & Using Fetched Data/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/02 Essentials/08 Returning & Using Fetched Data/public/favicon.ico -------------------------------------------------------------------------------- /Code/02 Essentials/08 Returning & Using Fetched Data/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/02 Essentials/09 Providing User Feedback/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/02 Essentials/09 Providing User Feedback/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/02 Essentials/09 Providing User Feedback/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/02 Essentials/09 Providing User Feedback/public/favicon.ico -------------------------------------------------------------------------------- /Code/02 Essentials/09 Providing User Feedback/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/02 Essentials/10 Validating Input/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/02 Essentials/10 Validating Input/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/02 Essentials/10 Validating Input/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/02 Essentials/10 Validating Input/public/favicon.ico -------------------------------------------------------------------------------- /Code/02 Essentials/10 Validating Input/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/02 Essentials/11 Handling Error Responses/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/02 Essentials/11 Handling Error Responses/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/02 Essentials/11 Handling Error Responses/notes.json: -------------------------------------------------------------------------------- 1 | {"notes":[{"title":"New Notes","content":"A new note!","id":"2022-10-19T11:10:56.831Z"}]} -------------------------------------------------------------------------------- /Code/02 Essentials/11 Handling Error Responses/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/02 Essentials/11 Handling Error Responses/public/favicon.ico -------------------------------------------------------------------------------- /Code/02 Essentials/11 Handling Error Responses/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/02 Essentials/12 Adding Dynamic Routes/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/02 Essentials/12 Adding Dynamic Routes/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/02 Essentials/12 Adding Dynamic Routes/notes.json: -------------------------------------------------------------------------------- 1 | {"notes":[{"title":"New Notes","content":"A new note!","id":"2022-10-19T11:10:56.831Z"},{"title":"Remix is awesome!","content":"It really is!","id":"2022-10-19T11:16:55.247Z"}]} -------------------------------------------------------------------------------- /Code/02 Essentials/12 Adding Dynamic Routes/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/02 Essentials/12 Adding Dynamic Routes/public/favicon.ico -------------------------------------------------------------------------------- /Code/02 Essentials/12 Adding Dynamic Routes/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/02 Essentials/13 Fetching Data for Dynamic Routes/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/02 Essentials/13 Fetching Data for Dynamic Routes/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/02 Essentials/13 Fetching Data for Dynamic Routes/notes.json: -------------------------------------------------------------------------------- 1 | {"notes":[{"title":"New Notes","content":"A new note!","id":"2022-10-19T11:10:56.831Z"},{"title":"Remix is awesome!","content":"It really is!","id":"2022-10-19T11:16:55.247Z"}]} -------------------------------------------------------------------------------- /Code/02 Essentials/13 Fetching Data for Dynamic Routes/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/02 Essentials/13 Fetching Data for Dynamic Routes/public/favicon.ico -------------------------------------------------------------------------------- /Code/02 Essentials/13 Fetching Data for Dynamic Routes/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/02 Essentials/14 Finished/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/02 Essentials/14 Finished/notes.json: -------------------------------------------------------------------------------- 1 | { 2 | "notes": [ 3 | { 4 | "title": "New Notes", 5 | "content": "A new note!", 6 | "id": "2022-10-19T11:10:56.831Z" 7 | }, 8 | { 9 | "title": "Remix is awesome!", 10 | "content": "It really is!", 11 | "id": "2022-10-19T11:16:55.247Z" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /Code/02 Essentials/14 Finished/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/02 Essentials/14 Finished/public/favicon.ico -------------------------------------------------------------------------------- /Code/02 Essentials/14 Finished/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/02 Essentials/Extra Files/index.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | export default function Index() { 4 | return ( 5 |
6 |

A better way of keeping track of your notes

7 |

Try our early beta and never loose track of your notes again!

8 |

9 | Try Now! 10 |

11 |
12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /Code/02 Essentials/ZZ V2-finished/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | .env 6 | -------------------------------------------------------------------------------- /Code/02 Essentials/ZZ V2-finished/app/tailwind.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | html, 6 | body { 7 | @apply bg-white dark:bg-gray-950; 8 | 9 | @media (prefers-color-scheme: dark) { 10 | color-scheme: dark; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Code/02 Essentials/ZZ V2-finished/postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /Code/02 Essentials/ZZ V2-finished/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/02 Essentials/ZZ V2-finished/public/favicon.ico -------------------------------------------------------------------------------- /Code/02 Essentials/ZZ V2-finished/public/logo-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/02 Essentials/ZZ V2-finished/public/logo-dark.png -------------------------------------------------------------------------------- /Code/02 Essentials/ZZ V2-finished/public/logo-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/02 Essentials/ZZ V2-finished/public/logo-light.png -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/01 Starting Project/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/01 Starting Project/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/01 Starting Project/app/routes/index.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | export default function Index() { 4 | return ( 5 | <> 6 |

Hello World!

7 | 8 | ); 9 | } 10 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/01 Starting Project/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/01 Starting Project/public/favicon.ico -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/01 Starting Project/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/02 Creating Project Routes/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/02 Creating Project Routes/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/02 Creating Project Routes/app/routes/auth.jsx: -------------------------------------------------------------------------------- 1 | export default function AuthPage() { 2 | return

Auth Page

; 3 | } 4 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/02 Creating Project Routes/app/routes/expenses.$id.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/ => /expenses/expense-1, /expenses/e-1 2 | 3 | export default function UpdateExpensesPage() { 4 | return

Update Expenses Page

; 5 | } 6 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/02 Creating Project Routes/app/routes/expenses.add.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/add 2 | 3 | export default function AddExpensesPage() { 4 | return

Add Expenses Page

; 5 | } 6 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/02 Creating Project Routes/app/routes/expenses.analysis.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/analysis 2 | 3 | export default function ExpensesAnalysisPage() { 4 | return

Expenses Analysis Page

; 5 | } 6 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/02 Creating Project Routes/app/routes/expenses.jsx: -------------------------------------------------------------------------------- 1 | export default function ExpensesPage() { 2 | return

Expenses Page

; 3 | } 4 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/02 Creating Project Routes/app/routes/expenses.raw.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/raw 2 | 3 | export default function ExpensesRawPage() { 4 | return

Expenses Raw Page

; 5 | } 6 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/02 Creating Project Routes/app/routes/index.jsx: -------------------------------------------------------------------------------- 1 | export default function Index() { 2 | return

Home Page

; 3 | } 4 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/02 Creating Project Routes/app/routes/pricing.jsx: -------------------------------------------------------------------------------- 1 | export default function PricingPage() { 2 | return

Pricing Page

; 3 | } 4 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/02 Creating Project Routes/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/02 Creating Project Routes/public/favicon.ico -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/02 Creating Project Routes/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/03 Layout Routes/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/03 Layout Routes/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/03 Layout Routes/app/routes/auth.jsx: -------------------------------------------------------------------------------- 1 | export default function AuthPage() { 2 | return

Auth Page

; 3 | } 4 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/03 Layout Routes/app/routes/expenses.jsx: -------------------------------------------------------------------------------- 1 | // /expenses => shared layout 2 | 3 | import { Outlet } from '@remix-run/react'; 4 | 5 | export default function ExpensesLayout() { 6 | return ( 7 |
8 |

Shared element!

9 | 10 |
11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/03 Layout Routes/app/routes/expenses.raw.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/raw 2 | 3 | export default function ExpensesRawPage() { 4 | return

Expenses Raw Page

; 5 | } 6 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/03 Layout Routes/app/routes/expenses/$id.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/ => /expenses/expense-1, /expenses/e-1 2 | 3 | export default function UpdateExpensesPage() { 4 | return

Update Expenses Page

; 5 | } 6 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/03 Layout Routes/app/routes/expenses/add.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/add 2 | 3 | export default function AddExpensesPage() { 4 | return

Add Expenses Page

; 5 | } 6 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/03 Layout Routes/app/routes/expenses/analysis.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/analysis 2 | 3 | export default function ExpensesAnalysisPage() { 4 | return

Expenses Analysis Page

; 5 | } 6 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/03 Layout Routes/app/routes/index.jsx: -------------------------------------------------------------------------------- 1 | // your-domain.com/ 2 | 3 | export default function Index() { 4 | return

Home Page

; 5 | } 6 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/03 Layout Routes/app/routes/pricing.jsx: -------------------------------------------------------------------------------- 1 | export default function PricingPage() { 2 | return

Pricing Page

; 3 | } 4 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/03 Layout Routes/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/03 Layout Routes/public/favicon.ico -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/03 Layout Routes/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/04 Adding Components & Styling/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/04 Adding Components & Styling/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/04 Adding Components & Styling/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/04 Adding Components & Styling/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | function Logo() { 2 | return ( 3 |

4 | RemixExpenses 5 |

6 | ); 7 | } 8 | 9 | export default Logo; 10 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/04 Adding Components & Styling/app/routes/auth.jsx: -------------------------------------------------------------------------------- 1 | import authStyles from '~/styles/auth.css'; 2 | 3 | export default function AuthPage() { 4 | return

Auth Page

; 5 | } 6 | 7 | export function links() { 8 | return [{ rel: 'stylesheet', href: authStyles }]; 9 | } 10 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/04 Adding Components & Styling/app/routes/expenses.raw.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/raw 2 | 3 | export default function ExpensesRawPage() { 4 | return

Expenses Raw Page

; 5 | } 6 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/04 Adding Components & Styling/app/routes/expenses/$id.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/ => /expenses/expense-1, /expenses/e-1 2 | 3 | export default function UpdateExpensesPage() { 4 | return

Update Expenses Page

; 5 | } 6 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/04 Adding Components & Styling/app/routes/expenses/add.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/add 2 | 3 | export default function AddExpensesPage() { 4 | return

Add Expenses Page

; 5 | } 6 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/04 Adding Components & Styling/app/routes/expenses/analysis.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/analysis 2 | 3 | export default function ExpensesAnalysisPage() { 4 | return

Expenses Analysis Page

; 5 | } 6 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/04 Adding Components & Styling/app/routes/index.jsx: -------------------------------------------------------------------------------- 1 | // your-domain.com/ 2 | 3 | export default function Index() { 4 | return

Home Page

; 5 | } 6 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/04 Adding Components & Styling/app/routes/pricing.jsx: -------------------------------------------------------------------------------- 1 | export default function PricingPage() { 2 | return

Pricing Page

; 3 | } 4 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/04 Adding Components & Styling/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/04 Adding Components & Styling/public/favicon.ico -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/04 Adding Components & Styling/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/05 Marketing Pages/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/05 Marketing Pages/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/05 Marketing Pages/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/05 Marketing Pages/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | function Logo() { 2 | return ( 3 |

4 | RemixExpenses 5 |

6 | ); 7 | } 8 | 9 | export default Logo; 10 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/05 Marketing Pages/app/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/05 Marketing Pages/app/routes/auth.jsx: -------------------------------------------------------------------------------- 1 | import AuthForm from '~/components/auth/AuthForm'; 2 | import authStyles from '~/styles/auth.css'; 3 | 4 | export default function AuthPage() { 5 | return ; 6 | } 7 | 8 | export function links() { 9 | return [{ rel: 'stylesheet', href: authStyles }]; 10 | } 11 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/05 Marketing Pages/app/routes/expenses.raw.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/raw 2 | 3 | export default function ExpensesRawPage() { 4 | return

Expenses Raw Page

; 5 | } 6 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/05 Marketing Pages/app/routes/expenses/$id.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/ => /expenses/expense-1, /expenses/e-1 2 | 3 | import ExpenseForm from '~/components/expenses/ExpenseForm'; 4 | 5 | export default function UpdateExpensesPage() { 6 | return ; 7 | } 8 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/05 Marketing Pages/app/routes/expenses/add.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/add 2 | 3 | import ExpenseForm from '~/components/expenses/ExpenseForm'; 4 | 5 | export default function AddExpensesPage() { 6 | return ; 7 | } 8 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/05 Marketing Pages/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/05 Marketing Pages/public/favicon.ico -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/05 Marketing Pages/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/05 Marketing Pages/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/05 Marketing Pages/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/05 Marketing Pages/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/05 Marketing Pages/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/06 Rendering a Modal Page/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/06 Rendering a Modal Page/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/06 Rendering a Modal Page/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/06 Rendering a Modal Page/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | function Logo() { 2 | return ( 3 |

4 | RemixExpenses 5 |

6 | ); 7 | } 8 | 9 | export default Logo; 10 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/06 Rendering a Modal Page/app/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/06 Rendering a Modal Page/app/routes/auth.jsx: -------------------------------------------------------------------------------- 1 | import AuthForm from '~/components/auth/AuthForm'; 2 | import authStyles from '~/styles/auth.css'; 3 | 4 | export default function AuthPage() { 5 | return ; 6 | } 7 | 8 | export function links() { 9 | return [{ rel: 'stylesheet', href: authStyles }]; 10 | } 11 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/06 Rendering a Modal Page/app/routes/expenses.raw.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/raw 2 | 3 | export default function ExpensesRawPage() { 4 | return

Expenses Raw Page

; 5 | } 6 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/06 Rendering a Modal Page/app/routes/expenses/$id.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/ => /expenses/expense-1, /expenses/e-1 2 | 3 | import ExpenseForm from '~/components/expenses/ExpenseForm'; 4 | import Modal from '~/components/util/Modal'; 5 | 6 | export default function UpdateExpensesPage() { 7 | return ( 8 | 9 | 10 | 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/06 Rendering a Modal Page/app/routes/expenses/add.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/add 2 | 3 | import ExpenseForm from '~/components/expenses/ExpenseForm'; 4 | import Modal from '~/components/util/Modal'; 5 | 6 | export default function AddExpensesPage() { 7 | return ( 8 | 9 | 10 | 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/06 Rendering a Modal Page/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/06 Rendering a Modal Page/public/favicon.ico -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/06 Rendering a Modal Page/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/06 Rendering a Modal Page/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/06 Rendering a Modal Page/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/06 Rendering a Modal Page/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/06 Rendering a Modal Page/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/07 Paths/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/07 Paths/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/07 Paths/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/07 Paths/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | function Logo() { 2 | return ( 3 |

4 | RemixExpenses 5 |

6 | ); 7 | } 8 | 9 | export default Logo; 10 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/07 Paths/app/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/07 Paths/app/routes/auth.jsx: -------------------------------------------------------------------------------- 1 | import AuthForm from '~/components/auth/AuthForm'; 2 | import authStyles from '~/styles/auth.css'; 3 | 4 | export default function AuthPage() { 5 | return ; 6 | } 7 | 8 | export function links() { 9 | return [{ rel: 'stylesheet', href: authStyles }]; 10 | } 11 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/07 Paths/app/routes/expenses.raw.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/raw 2 | 3 | export default function ExpensesRawPage() { 4 | return

Expenses Raw Page

; 5 | } 6 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/07 Paths/app/routes/expenses/$id.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/ => /expenses/expense-1, /expenses/e-1 2 | 3 | import ExpenseForm from '~/components/expenses/ExpenseForm'; 4 | import Modal from '~/components/util/Modal'; 5 | 6 | export default function UpdateExpensesPage() { 7 | return ( 8 | 9 | 10 | 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/07 Paths/app/routes/expenses/add.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/add 2 | 3 | import ExpenseForm from '~/components/expenses/ExpenseForm'; 4 | import Modal from '~/components/util/Modal'; 5 | 6 | export default function AddExpensesPage() { 7 | return ( 8 | 9 | 10 | 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/07 Paths/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/07 Paths/public/favicon.ico -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/07 Paths/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/07 Paths/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/07 Paths/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/07 Paths/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/07 Paths/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/08 Navigating Programmatically/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/08 Navigating Programmatically/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/08 Navigating Programmatically/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/08 Navigating Programmatically/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | function Logo() { 2 | return ( 3 |

4 | RemixExpenses 5 |

6 | ); 7 | } 8 | 9 | export default Logo; 10 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/08 Navigating Programmatically/app/routes/auth.jsx: -------------------------------------------------------------------------------- 1 | import AuthForm from '~/components/auth/AuthForm'; 2 | import authStyles from '~/styles/auth.css'; 3 | 4 | export default function AuthPage() { 5 | return ; 6 | } 7 | 8 | export function links() { 9 | return [{ rel: 'stylesheet', href: authStyles }]; 10 | } 11 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/08 Navigating Programmatically/app/routes/expenses.raw.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/raw 2 | 3 | export default function ExpensesRawPage() { 4 | return

Expenses Raw Page

; 5 | } 6 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/08 Navigating Programmatically/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/08 Navigating Programmatically/public/favicon.ico -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/08 Navigating Programmatically/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/08 Navigating Programmatically/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/08 Navigating Programmatically/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/08 Navigating Programmatically/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/08 Navigating Programmatically/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/09 Introducing Pathless Layout Routes/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/09 Introducing Pathless Layout Routes/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/09 Introducing Pathless Layout Routes/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/09 Introducing Pathless Layout Routes/app/routes/__app.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/add 2 | 3 | import expensesStyles from '~/styles/expenses.css'; 4 | 5 | import { Outlet } from '@remix-run/react'; 6 | 7 | export default function ExpensesAppLayout() { 8 | return ; 9 | } 10 | 11 | export function links() { 12 | return [{ rel: 'stylesheet', href: expensesStyles }]; 13 | } 14 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/09 Introducing Pathless Layout Routes/app/routes/__marketing.jsx: -------------------------------------------------------------------------------- 1 | import { Outlet } from '@remix-run/react'; 2 | 3 | import marketingStyles from '~/styles/marketing.css'; 4 | 5 | export default function MarketingLayout() { 6 | return ; 7 | } 8 | 9 | export function links() { 10 | return [{ rel: 'stylesheet', href: marketingStyles }]; 11 | } 12 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/09 Introducing Pathless Layout Routes/app/routes/auth.jsx: -------------------------------------------------------------------------------- 1 | import AuthForm from '~/components/auth/AuthForm'; 2 | import authStyles from '~/styles/auth.css'; 3 | 4 | export default function AuthPage() { 5 | return ; 6 | } 7 | 8 | export function links() { 9 | return [{ rel: 'stylesheet', href: authStyles }]; 10 | } 11 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/09 Introducing Pathless Layout Routes/app/routes/expenses.raw.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/raw 2 | 3 | export default function ExpensesRawPage() { 4 | return

Expenses Raw Page

; 5 | } 6 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/09 Introducing Pathless Layout Routes/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/09 Introducing Pathless Layout Routes/public/favicon.ico -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/09 Introducing Pathless Layout Routes/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/09 Introducing Pathless Layout Routes/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/09 Introducing Pathless Layout Routes/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/09 Introducing Pathless Layout Routes/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/09 Introducing Pathless Layout Routes/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/10 Doing More With Pathless/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/10 Doing More With Pathless/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/10 Doing More With Pathless/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/10 Doing More With Pathless/app/components/util/FormattedDate.jsx: -------------------------------------------------------------------------------- 1 | function FormattedDate({date}) { 2 | const formattedDate = new Date(date).toLocaleDateString('en-US', { 3 | day: 'numeric', 4 | month: 'short', 5 | year: 'numeric', 6 | }); 7 | 8 | return ; 9 | } 10 | 11 | export default FormattedDate; 12 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/10 Doing More With Pathless/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/10 Doing More With Pathless/app/routes/__marketing/auth.jsx: -------------------------------------------------------------------------------- 1 | import AuthForm from '~/components/auth/AuthForm'; 2 | import authStyles from '~/styles/auth.css'; 3 | 4 | export default function AuthPage() { 5 | return ; 6 | } 7 | 8 | export function links() { 9 | return [{ rel: 'stylesheet', href: authStyles }]; 10 | } 11 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/10 Doing More With Pathless/app/routes/expenses.raw.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/raw 2 | 3 | export default function ExpensesRawPage() { 4 | return

Expenses Raw Page

; 5 | } 6 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/10 Doing More With Pathless/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/10 Doing More With Pathless/public/favicon.ico -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/10 Doing More With Pathless/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/10 Doing More With Pathless/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/10 Doing More With Pathless/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/10 Doing More With Pathless/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/10 Doing More With Pathless/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/11 Splat Routes/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/11 Splat Routes/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/11 Splat Routes/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/11 Splat Routes/app/components/util/FormattedDate.jsx: -------------------------------------------------------------------------------- 1 | function FormattedDate({date}) { 2 | const formattedDate = new Date(date).toLocaleDateString('en-US', { 3 | day: 'numeric', 4 | month: 'short', 5 | year: 'numeric', 6 | }); 7 | 8 | return ; 9 | } 10 | 11 | export default FormattedDate; 12 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/11 Splat Routes/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/11 Splat Routes/app/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/11 Splat Routes/app/routes/$.jsx: -------------------------------------------------------------------------------- 1 | import { redirect } from '@remix-run/node'; 2 | 3 | export function loader({ params }) { 4 | if (params['*'] === 'exp') { 5 | return redirect('/expenses'); 6 | } 7 | 8 | throw new Response('Not found', { status: 404 }); 9 | } 10 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/11 Splat Routes/app/routes/__marketing/auth.jsx: -------------------------------------------------------------------------------- 1 | import AuthForm from '~/components/auth/AuthForm'; 2 | import authStyles from '~/styles/auth.css'; 3 | 4 | export default function AuthPage() { 5 | return ; 6 | } 7 | 8 | export function links() { 9 | return [{ rel: 'stylesheet', href: authStyles }]; 10 | } 11 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/11 Splat Routes/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/11 Splat Routes/public/favicon.ico -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/11 Splat Routes/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/11 Splat Routes/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/11 Splat Routes/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/11 Splat Routes/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/11 Splat Routes/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/12 Finished/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/12 Finished/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/12 Finished/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/12 Finished/app/components/util/FormattedDate.jsx: -------------------------------------------------------------------------------- 1 | function FormattedDate({date}) { 2 | const formattedDate = new Date(date).toLocaleDateString('en-US', { 3 | day: 'numeric', 4 | month: 'short', 5 | year: 'numeric', 6 | }); 7 | 8 | return ; 9 | } 10 | 11 | export default FormattedDate; 12 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/12 Finished/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/12 Finished/app/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/12 Finished/app/routes/$.jsx: -------------------------------------------------------------------------------- 1 | import { redirect } from '@remix-run/node'; 2 | 3 | export function loader({ params }) { 4 | if (params['*'] === 'exp') { 5 | return redirect('/expenses'); 6 | } 7 | 8 | throw new Response('Not found', { status: 404 }); 9 | } 10 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/12 Finished/app/routes/__marketing/auth.jsx: -------------------------------------------------------------------------------- 1 | import AuthForm from '~/components/auth/AuthForm'; 2 | import authStyles from '~/styles/auth.css'; 3 | 4 | export default function AuthPage() { 5 | return ; 6 | } 7 | 8 | export function links() { 9 | return [{ rel: 'stylesheet', href: authStyles }]; 10 | } 11 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/12 Finished/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/12 Finished/public/favicon.ico -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/12 Finished/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/12 Finished/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/12 Finished/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/12 Finished/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/12 Finished/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/Extra Files/components.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/Extra Files/components.zip -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/Extra Files/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/Extra Files/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | function Logo() { 2 | return ( 3 |

4 | RemixExpenses 5 |

6 | ); 7 | } 8 | 9 | export default Logo; 10 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/Extra Files/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/Extra Files/images.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/Extra Files/images.zip -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/Extra Files/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/Extra Files/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/Extra Files/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/Extra Files/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/Extra Files/styles.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/Extra Files/styles.zip -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/ZZ V2-finished/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | .env 6 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/ZZ V2-finished/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/ZZ V2-finished/app/components/util/FormattedDate.jsx: -------------------------------------------------------------------------------- 1 | function FormattedDate({date}) { 2 | const formattedDate = new Date(date).toLocaleDateString('en-US', { 3 | day: 'numeric', 4 | month: 'short', 5 | year: 'numeric', 6 | }); 7 | 8 | return ; 9 | } 10 | 11 | export default FormattedDate; 12 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/ZZ V2-finished/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/ZZ V2-finished/app/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/ZZ V2-finished/app/routes/$.jsx: -------------------------------------------------------------------------------- 1 | import { redirect } from '@remix-run/node'; 2 | 3 | export function loader({ params }) { 4 | if (params['*'] === 'exp') { 5 | return redirect('/expenses'); 6 | } 7 | 8 | throw new Response('Not found', { status: 404 }); 9 | } 10 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/ZZ V2-finished/app/routes/_marketing.auth.jsx: -------------------------------------------------------------------------------- 1 | import AuthForm from '~/components/auth/AuthForm'; 2 | import authStyles from '~/styles/auth.css?url'; 3 | 4 | export default function AuthPage() { 5 | return ; 6 | } 7 | 8 | export function links() { 9 | return [{ rel: 'stylesheet', href: authStyles }]; 10 | } 11 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/ZZ V2-finished/app/tailwind.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | html, 6 | body { 7 | @apply bg-white dark:bg-gray-950; 8 | 9 | @media (prefers-color-scheme: dark) { 10 | color-scheme: dark; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/ZZ V2-finished/postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/ZZ V2-finished/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/ZZ V2-finished/public/favicon.ico -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/ZZ V2-finished/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/ZZ V2-finished/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/ZZ V2-finished/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/ZZ V2-finished/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/03 Routing Deep Dive/ZZ V2-finished/public/logo-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/03 Routing Deep Dive/ZZ V2-finished/public/logo-light.png -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/01 Starting Project/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/01 Starting Project/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/01 Starting Project/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/01 Starting Project/app/components/util/FormattedDate.jsx: -------------------------------------------------------------------------------- 1 | function FormattedDate({date}) { 2 | const formattedDate = new Date(date).toLocaleDateString('en-US', { 3 | day: 'numeric', 4 | month: 'short', 5 | year: 'numeric', 6 | }); 7 | 8 | return ; 9 | } 10 | 11 | export default FormattedDate; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/01 Starting Project/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/01 Starting Project/app/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/01 Starting Project/app/routes/__marketing/auth.jsx: -------------------------------------------------------------------------------- 1 | import AuthForm from '~/components/auth/AuthForm'; 2 | import authStyles from '~/styles/auth.css'; 3 | 4 | export default function AuthPage() { 5 | return ; 6 | } 7 | 8 | export function links() { 9 | return [{ rel: 'stylesheet', href: authStyles }]; 10 | } 11 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/01 Starting Project/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/01 Starting Project/public/favicon.ico -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/01 Starting Project/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/01 Starting Project/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/01 Starting Project/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/01 Starting Project/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/01 Starting Project/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/02 Adding Expense Model/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/02 Adding Expense Model/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/02 Adding Expense Model/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/02 Adding Expense Model/app/components/util/FormattedDate.jsx: -------------------------------------------------------------------------------- 1 | function FormattedDate({date}) { 2 | const formattedDate = new Date(date).toLocaleDateString('en-US', { 3 | day: 'numeric', 4 | month: 'short', 5 | year: 'numeric', 6 | }); 7 | 8 | return ; 9 | } 10 | 11 | export default FormattedDate; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/02 Adding Expense Model/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/02 Adding Expense Model/app/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/02 Adding Expense Model/app/routes/__marketing/auth.jsx: -------------------------------------------------------------------------------- 1 | import AuthForm from '~/components/auth/AuthForm'; 2 | import authStyles from '~/styles/auth.css'; 3 | 4 | export default function AuthPage() { 5 | return ; 6 | } 7 | 8 | export function links() { 9 | return [{ rel: 'stylesheet', href: authStyles }]; 10 | } 11 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/02 Adding Expense Model/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/02 Adding Expense Model/public/favicon.ico -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/02 Adding Expense Model/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/02 Adding Expense Model/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/02 Adding Expense Model/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/02 Adding Expense Model/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/02 Adding Expense Model/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/03 Adding Expenses to the Database/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/03 Adding Expenses to the Database/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/03 Adding Expenses to the Database/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/03 Adding Expenses to the Database/app/components/util/FormattedDate.jsx: -------------------------------------------------------------------------------- 1 | function FormattedDate({date}) { 2 | const formattedDate = new Date(date).toLocaleDateString('en-US', { 3 | day: 'numeric', 4 | month: 'short', 5 | year: 'numeric', 6 | }); 7 | 8 | return ; 9 | } 10 | 11 | export default FormattedDate; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/03 Adding Expenses to the Database/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/03 Adding Expenses to the Database/app/routes/__marketing/auth.jsx: -------------------------------------------------------------------------------- 1 | import AuthForm from '~/components/auth/AuthForm'; 2 | import authStyles from '~/styles/auth.css'; 3 | 4 | export default function AuthPage() { 5 | return ; 6 | } 7 | 8 | export function links() { 9 | return [{ rel: 'stylesheet', href: authStyles }]; 10 | } 11 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/03 Adding Expenses to the Database/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/03 Adding Expenses to the Database/public/favicon.ico -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/03 Adding Expenses to the Database/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/03 Adding Expenses to the Database/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/03 Adding Expenses to the Database/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/03 Adding Expenses to the Database/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/03 Adding Expenses to the Database/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/04 Server-side Validation/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/04 Server-side Validation/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/04 Server-side Validation/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/04 Server-side Validation/app/components/util/FormattedDate.jsx: -------------------------------------------------------------------------------- 1 | function FormattedDate({date}) { 2 | const formattedDate = new Date(date).toLocaleDateString('en-US', { 3 | day: 'numeric', 4 | month: 'short', 5 | year: 'numeric', 6 | }); 7 | 8 | return ; 9 | } 10 | 11 | export default FormattedDate; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/04 Server-side Validation/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/04 Server-side Validation/app/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/04 Server-side Validation/app/routes/__marketing/auth.jsx: -------------------------------------------------------------------------------- 1 | import AuthForm from '~/components/auth/AuthForm'; 2 | import authStyles from '~/styles/auth.css'; 3 | 4 | export default function AuthPage() { 5 | return ; 6 | } 7 | 8 | export function links() { 9 | return [{ rel: 'stylesheet', href: authStyles }]; 10 | } 11 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/04 Server-side Validation/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/04 Server-side Validation/public/favicon.ico -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/04 Server-side Validation/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/04 Server-side Validation/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/04 Server-side Validation/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/04 Server-side Validation/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/04 Server-side Validation/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/05 Submitting Forms Programmatically/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/05 Submitting Forms Programmatically/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/05 Submitting Forms Programmatically/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/05 Submitting Forms Programmatically/app/components/util/FormattedDate.jsx: -------------------------------------------------------------------------------- 1 | function FormattedDate({date}) { 2 | const formattedDate = new Date(date).toLocaleDateString('en-US', { 3 | day: 'numeric', 4 | month: 'short', 5 | year: 'numeric', 6 | }); 7 | 8 | return ; 9 | } 10 | 11 | export default FormattedDate; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/05 Submitting Forms Programmatically/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/05 Submitting Forms Programmatically/app/routes/__marketing/auth.jsx: -------------------------------------------------------------------------------- 1 | import AuthForm from '~/components/auth/AuthForm'; 2 | import authStyles from '~/styles/auth.css'; 3 | 4 | export default function AuthPage() { 5 | return ; 6 | } 7 | 8 | export function links() { 9 | return [{ rel: 'stylesheet', href: authStyles }]; 10 | } 11 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/05 Submitting Forms Programmatically/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/05 Submitting Forms Programmatically/public/favicon.ico -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/05 Submitting Forms Programmatically/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/05 Submitting Forms Programmatically/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/05 Submitting Forms Programmatically/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/05 Submitting Forms Programmatically/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/05 Submitting Forms Programmatically/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/06 Fetching Expenses/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/06 Fetching Expenses/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/06 Fetching Expenses/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/06 Fetching Expenses/app/components/util/FormattedDate.jsx: -------------------------------------------------------------------------------- 1 | function FormattedDate({date}) { 2 | const formattedDate = new Date(date).toLocaleDateString('en-US', { 3 | day: 'numeric', 4 | month: 'short', 5 | year: 'numeric', 6 | }); 7 | 8 | return ; 9 | } 10 | 11 | export default FormattedDate; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/06 Fetching Expenses/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/06 Fetching Expenses/app/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/06 Fetching Expenses/app/routes/__marketing/auth.jsx: -------------------------------------------------------------------------------- 1 | import AuthForm from '~/components/auth/AuthForm'; 2 | import authStyles from '~/styles/auth.css'; 3 | 4 | export default function AuthPage() { 5 | return ; 6 | } 7 | 8 | export function links() { 9 | return [{ rel: 'stylesheet', href: authStyles }]; 10 | } 11 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/06 Fetching Expenses/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/06 Fetching Expenses/public/favicon.ico -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/06 Fetching Expenses/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/06 Fetching Expenses/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/06 Fetching Expenses/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/06 Fetching Expenses/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/06 Fetching Expenses/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/07 Loading a Single Expense/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/07 Loading a Single Expense/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/07 Loading a Single Expense/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/07 Loading a Single Expense/app/components/util/FormattedDate.jsx: -------------------------------------------------------------------------------- 1 | function FormattedDate({date}) { 2 | const formattedDate = new Date(date).toLocaleDateString('en-US', { 3 | day: 'numeric', 4 | month: 'short', 5 | year: 'numeric', 6 | }); 7 | 8 | return ; 9 | } 10 | 11 | export default FormattedDate; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/07 Loading a Single Expense/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/07 Loading a Single Expense/app/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/07 Loading a Single Expense/app/routes/__marketing/auth.jsx: -------------------------------------------------------------------------------- 1 | import AuthForm from '~/components/auth/AuthForm'; 2 | import authStyles from '~/styles/auth.css'; 3 | 4 | export default function AuthPage() { 5 | return ; 6 | } 7 | 8 | export function links() { 9 | return [{ rel: 'stylesheet', href: authStyles }]; 10 | } 11 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/07 Loading a Single Expense/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/07 Loading a Single Expense/public/favicon.ico -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/07 Loading a Single Expense/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/07 Loading a Single Expense/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/07 Loading a Single Expense/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/07 Loading a Single Expense/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/07 Loading a Single Expense/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/08 Using Parent Loader Data/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/08 Using Parent Loader Data/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/08 Using Parent Loader Data/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/08 Using Parent Loader Data/app/components/util/FormattedDate.jsx: -------------------------------------------------------------------------------- 1 | function FormattedDate({date}) { 2 | const formattedDate = new Date(date).toLocaleDateString('en-US', { 3 | day: 'numeric', 4 | month: 'short', 5 | year: 'numeric', 6 | }); 7 | 8 | return ; 9 | } 10 | 11 | export default FormattedDate; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/08 Using Parent Loader Data/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/08 Using Parent Loader Data/app/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/08 Using Parent Loader Data/app/routes/__marketing/auth.jsx: -------------------------------------------------------------------------------- 1 | import AuthForm from '~/components/auth/AuthForm'; 2 | import authStyles from '~/styles/auth.css'; 3 | 4 | export default function AuthPage() { 5 | return ; 6 | } 7 | 8 | export function links() { 9 | return [{ rel: 'stylesheet', href: authStyles }]; 10 | } 11 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/08 Using Parent Loader Data/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/08 Using Parent Loader Data/public/favicon.ico -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/08 Using Parent Loader Data/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/08 Using Parent Loader Data/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/08 Using Parent Loader Data/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/08 Using Parent Loader Data/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/08 Using Parent Loader Data/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/09 Updating Data/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/09 Updating Data/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/09 Updating Data/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/09 Updating Data/app/components/util/FormattedDate.jsx: -------------------------------------------------------------------------------- 1 | function FormattedDate({date}) { 2 | const formattedDate = new Date(date).toLocaleDateString('en-US', { 3 | day: 'numeric', 4 | month: 'short', 5 | year: 'numeric', 6 | }); 7 | 8 | return ; 9 | } 10 | 11 | export default FormattedDate; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/09 Updating Data/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/09 Updating Data/app/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/09 Updating Data/app/routes/__marketing/auth.jsx: -------------------------------------------------------------------------------- 1 | import AuthForm from '~/components/auth/AuthForm'; 2 | import authStyles from '~/styles/auth.css'; 3 | 4 | export default function AuthPage() { 5 | return ; 6 | } 7 | 8 | export function links() { 9 | return [{ rel: 'stylesheet', href: authStyles }]; 10 | } 11 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/09 Updating Data/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/09 Updating Data/public/favicon.ico -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/09 Updating Data/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/09 Updating Data/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/09 Updating Data/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/09 Updating Data/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/09 Updating Data/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/10 Deleting Data/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/10 Deleting Data/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/10 Deleting Data/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/10 Deleting Data/app/components/util/FormattedDate.jsx: -------------------------------------------------------------------------------- 1 | function FormattedDate({date}) { 2 | const formattedDate = new Date(date).toLocaleDateString('en-US', { 3 | day: 'numeric', 4 | month: 'short', 5 | year: 'numeric', 6 | }); 7 | 8 | return ; 9 | } 10 | 11 | export default FormattedDate; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/10 Deleting Data/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/10 Deleting Data/app/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/10 Deleting Data/app/routes/__marketing/auth.jsx: -------------------------------------------------------------------------------- 1 | import AuthForm from '~/components/auth/AuthForm'; 2 | import authStyles from '~/styles/auth.css'; 3 | 4 | export default function AuthPage() { 5 | return ; 6 | } 7 | 8 | export function links() { 9 | return [{ rel: 'stylesheet', href: authStyles }]; 10 | } 11 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/10 Deleting Data/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/10 Deleting Data/public/favicon.ico -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/10 Deleting Data/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/10 Deleting Data/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/10 Deleting Data/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/10 Deleting Data/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/10 Deleting Data/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/11 Programmatic Behind-the-Scenes Submission/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/11 Programmatic Behind-the-Scenes Submission/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/11 Programmatic Behind-the-Scenes Submission/app/components/util/FormattedDate.jsx: -------------------------------------------------------------------------------- 1 | function FormattedDate({date}) { 2 | const formattedDate = new Date(date).toLocaleDateString('en-US', { 3 | day: 'numeric', 4 | month: 'short', 5 | year: 'numeric', 6 | }); 7 | 8 | return ; 9 | } 10 | 11 | export default FormattedDate; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/11 Programmatic Behind-the-Scenes Submission/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/11 Programmatic Behind-the-Scenes Submission/app/routes/__marketing/auth.jsx: -------------------------------------------------------------------------------- 1 | import AuthForm from '~/components/auth/AuthForm'; 2 | import authStyles from '~/styles/auth.css'; 3 | 4 | export default function AuthPage() { 5 | return ; 6 | } 7 | 8 | export function links() { 9 | return [{ rel: 'stylesheet', href: authStyles }]; 10 | } 11 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/11 Programmatic Behind-the-Scenes Submission/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/11 Programmatic Behind-the-Scenes Submission/public/favicon.ico -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/11 Programmatic Behind-the-Scenes Submission/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/11 Programmatic Behind-the-Scenes Submission/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/11 Programmatic Behind-the-Scenes Submission/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/11 Programmatic Behind-the-Scenes Submission/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/11 Programmatic Behind-the-Scenes Submission/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/12 Extracting Search Parameters/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/12 Extracting Search Parameters/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/12 Extracting Search Parameters/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/12 Extracting Search Parameters/app/components/util/FormattedDate.jsx: -------------------------------------------------------------------------------- 1 | function FormattedDate({date}) { 2 | const formattedDate = new Date(date).toLocaleDateString('en-US', { 3 | day: 'numeric', 4 | month: 'short', 5 | year: 'numeric', 6 | }); 7 | 8 | return ; 9 | } 10 | 11 | export default FormattedDate; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/12 Extracting Search Parameters/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/12 Extracting Search Parameters/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/12 Extracting Search Parameters/public/favicon.ico -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/12 Extracting Search Parameters/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/12 Extracting Search Parameters/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/12 Extracting Search Parameters/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/12 Extracting Search Parameters/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/12 Extracting Search Parameters/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/13 Managing Errors Inside Components/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/13 Managing Errors Inside Components/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/13 Managing Errors Inside Components/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/13 Managing Errors Inside Components/app/components/util/FormattedDate.jsx: -------------------------------------------------------------------------------- 1 | function FormattedDate({date}) { 2 | const formattedDate = new Date(date).toLocaleDateString('en-US', { 3 | day: 'numeric', 4 | month: 'short', 5 | year: 'numeric', 6 | }); 7 | 8 | return ; 9 | } 10 | 11 | export default FormattedDate; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/13 Managing Errors Inside Components/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/13 Managing Errors Inside Components/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/13 Managing Errors Inside Components/public/favicon.ico -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/13 Managing Errors Inside Components/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/13 Managing Errors Inside Components/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/13 Managing Errors Inside Components/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/13 Managing Errors Inside Components/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/13 Managing Errors Inside Components/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/14 Practice Time Solution/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/14 Practice Time Solution/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/14 Practice Time Solution/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/14 Practice Time Solution/app/components/util/FormattedDate.jsx: -------------------------------------------------------------------------------- 1 | function FormattedDate({date}) { 2 | const formattedDate = new Date(date).toLocaleDateString('en-US', { 3 | day: 'numeric', 4 | month: 'short', 5 | year: 'numeric', 6 | }); 7 | 8 | return ; 9 | } 10 | 11 | export default FormattedDate; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/14 Practice Time Solution/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/14 Practice Time Solution/app/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/14 Practice Time Solution/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/14 Practice Time Solution/public/favicon.ico -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/14 Practice Time Solution/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/14 Practice Time Solution/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/14 Practice Time Solution/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/14 Practice Time Solution/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/14 Practice Time Solution/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/15 Finished/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/15 Finished/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/15 Finished/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/15 Finished/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/15 Finished/app/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/15 Finished/app/routes/expenses.raw.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/raw 2 | 3 | import { getExpenses } from '~/data/expenses.server'; 4 | 5 | export function loader() { 6 | return getExpenses(); 7 | } 8 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/15 Finished/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/15 Finished/public/favicon.ico -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/15 Finished/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/15 Finished/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/15 Finished/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/15 Finished/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/15 Finished/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/ZZ V2-finished/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | .env 6 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/ZZ V2-finished/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/ZZ V2-finished/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/ZZ V2-finished/app/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/ZZ V2-finished/app/routes/expenses.raw.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/raw 2 | 3 | import { getExpenses } from '~/data/expenses.server'; 4 | 5 | export function loader() { 6 | return getExpenses(); 7 | } 8 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/ZZ V2-finished/app/tailwind.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | html, 6 | body { 7 | @apply bg-white dark:bg-gray-950; 8 | 9 | @media (prefers-color-scheme: dark) { 10 | color-scheme: dark; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/ZZ V2-finished/postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/ZZ V2-finished/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/ZZ V2-finished/public/favicon.ico -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/ZZ V2-finished/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/ZZ V2-finished/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/04 Data Deep Dive/ZZ V2-finished/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/04 Data Deep Dive/ZZ V2-finished/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/05 Authentication/01 Starting Project/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/05 Authentication/01 Starting Project/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/05 Authentication/01 Starting Project/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/05 Authentication/01 Starting Project/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/05 Authentication/01 Starting Project/app/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/05 Authentication/01 Starting Project/app/routes/expenses.raw.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/raw 2 | 3 | import { getExpenses } from '~/data/expenses.server'; 4 | 5 | export function loader() { 6 | return getExpenses(); 7 | } 8 | -------------------------------------------------------------------------------- /Code/05 Authentication/01 Starting Project/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/01 Starting Project/public/favicon.ico -------------------------------------------------------------------------------- /Code/05 Authentication/01 Starting Project/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/01 Starting Project/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/05 Authentication/01 Starting Project/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/01 Starting Project/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/05 Authentication/01 Starting Project/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/05 Authentication/02 Preparing the Database/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/05 Authentication/02 Preparing the Database/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/05 Authentication/02 Preparing the Database/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/05 Authentication/02 Preparing the Database/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/05 Authentication/02 Preparing the Database/app/routes/expenses.raw.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/raw 2 | 3 | import { getExpenses } from '~/data/expenses.server'; 4 | 5 | export function loader() { 6 | return getExpenses(); 7 | } 8 | -------------------------------------------------------------------------------- /Code/05 Authentication/02 Preparing the Database/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/02 Preparing the Database/public/favicon.ico -------------------------------------------------------------------------------- /Code/05 Authentication/02 Preparing the Database/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/02 Preparing the Database/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/05 Authentication/02 Preparing the Database/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/02 Preparing the Database/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/05 Authentication/02 Preparing the Database/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/05 Authentication/03 User Signup/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/05 Authentication/03 User Signup/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/05 Authentication/03 User Signup/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/05 Authentication/03 User Signup/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/05 Authentication/03 User Signup/app/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/05 Authentication/03 User Signup/app/routes/expenses.raw.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/raw 2 | 3 | import { getExpenses } from '~/data/expenses.server'; 4 | 5 | export function loader() { 6 | return getExpenses(); 7 | } 8 | -------------------------------------------------------------------------------- /Code/05 Authentication/03 User Signup/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/03 User Signup/public/favicon.ico -------------------------------------------------------------------------------- /Code/05 Authentication/03 User Signup/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/03 User Signup/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/05 Authentication/03 User Signup/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/03 User Signup/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/05 Authentication/03 User Signup/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/05 Authentication/04 Creating Session Cookies/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/05 Authentication/04 Creating Session Cookies/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/05 Authentication/04 Creating Session Cookies/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/05 Authentication/04 Creating Session Cookies/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/05 Authentication/04 Creating Session Cookies/app/routes/expenses.raw.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/raw 2 | 3 | import { getExpenses } from '~/data/expenses.server'; 4 | 5 | export function loader() { 6 | return getExpenses(); 7 | } 8 | -------------------------------------------------------------------------------- /Code/05 Authentication/04 Creating Session Cookies/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/04 Creating Session Cookies/public/favicon.ico -------------------------------------------------------------------------------- /Code/05 Authentication/04 Creating Session Cookies/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/04 Creating Session Cookies/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/05 Authentication/04 Creating Session Cookies/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/04 Creating Session Cookies/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/05 Authentication/04 Creating Session Cookies/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/05 Authentication/05 Extracting Session Data/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/05 Authentication/05 Extracting Session Data/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/05 Authentication/05 Extracting Session Data/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/05 Authentication/05 Extracting Session Data/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/05 Authentication/05 Extracting Session Data/app/routes/expenses.raw.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/raw 2 | 3 | import { getExpenses } from '~/data/expenses.server'; 4 | 5 | export function loader() { 6 | return getExpenses(); 7 | } 8 | -------------------------------------------------------------------------------- /Code/05 Authentication/05 Extracting Session Data/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/05 Extracting Session Data/public/favicon.ico -------------------------------------------------------------------------------- /Code/05 Authentication/05 Extracting Session Data/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/05 Extracting Session Data/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/05 Authentication/05 Extracting Session Data/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/05 Extracting Session Data/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/05 Authentication/05 Extracting Session Data/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/05 Authentication/06 Adding Logout/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/05 Authentication/06 Adding Logout/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/05 Authentication/06 Adding Logout/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/05 Authentication/06 Adding Logout/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/05 Authentication/06 Adding Logout/app/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/05 Authentication/06 Adding Logout/app/routes/expenses.raw.js: -------------------------------------------------------------------------------- 1 | // /expenses/raw 2 | 3 | import { getExpenses } from '~/data/expenses.server'; 4 | 5 | export function loader() { 6 | return getExpenses(); 7 | } 8 | -------------------------------------------------------------------------------- /Code/05 Authentication/06 Adding Logout/app/routes/logout.js: -------------------------------------------------------------------------------- 1 | import { json } from '@remix-run/node'; 2 | import { destroyUserSession } from '~/data/auth.server'; 3 | 4 | export function action({ request }) { 5 | if (request.method !== 'POST') { 6 | throw json({ message: 'Invalid request method' }, { status: 400 }); 7 | } 8 | 9 | return destroyUserSession(request); 10 | } 11 | -------------------------------------------------------------------------------- /Code/05 Authentication/06 Adding Logout/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/06 Adding Logout/public/favicon.ico -------------------------------------------------------------------------------- /Code/05 Authentication/06 Adding Logout/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/06 Adding Logout/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/05 Authentication/06 Adding Logout/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/06 Adding Logout/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/05 Authentication/06 Adding Logout/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/05 Authentication/07 More Route Protection/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/05 Authentication/07 More Route Protection/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/05 Authentication/07 More Route Protection/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/05 Authentication/07 More Route Protection/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/05 Authentication/07 More Route Protection/app/routes/expenses.raw.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/raw 2 | 3 | import { requireUserSession } from '~/data/auth.server'; 4 | import { getExpenses } from '~/data/expenses.server'; 5 | 6 | export async function loader({request}) { 7 | await requireUserSession(request); 8 | return getExpenses(); 9 | } 10 | -------------------------------------------------------------------------------- /Code/05 Authentication/07 More Route Protection/app/routes/logout.js: -------------------------------------------------------------------------------- 1 | import { json } from '@remix-run/node'; 2 | import { destroyUserSession } from '~/data/auth.server'; 3 | 4 | export function action({ request }) { 5 | if (request.method !== 'POST') { 6 | throw json({ message: 'Invalid request method' }, { status: 400 }); 7 | } 8 | 9 | return destroyUserSession(request); 10 | } 11 | -------------------------------------------------------------------------------- /Code/05 Authentication/07 More Route Protection/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/07 More Route Protection/public/favicon.ico -------------------------------------------------------------------------------- /Code/05 Authentication/07 More Route Protection/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/07 More Route Protection/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/05 Authentication/07 More Route Protection/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/07 More Route Protection/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/05 Authentication/07 More Route Protection/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/05 Authentication/08 Finished/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/05 Authentication/08 Finished/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/05 Authentication/08 Finished/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/05 Authentication/08 Finished/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/05 Authentication/08 Finished/app/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/05 Authentication/08 Finished/app/routes/expenses.raw.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/raw 2 | 3 | import { requireUserSession } from '~/data/auth.server'; 4 | import { getExpenses } from '~/data/expenses.server'; 5 | 6 | export async function loader({request}) { 7 | const userId = await requireUserSession(request); 8 | return getExpenses(userId); 9 | } 10 | -------------------------------------------------------------------------------- /Code/05 Authentication/08 Finished/app/routes/logout.js: -------------------------------------------------------------------------------- 1 | import { json } from '@remix-run/node'; 2 | import { destroyUserSession } from '~/data/auth.server'; 3 | 4 | export function action({ request }) { 5 | if (request.method !== 'POST') { 6 | throw json({ message: 'Invalid request method' }, { status: 400 }); 7 | } 8 | 9 | return destroyUserSession(request); 10 | } 11 | -------------------------------------------------------------------------------- /Code/05 Authentication/08 Finished/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/08 Finished/public/favicon.ico -------------------------------------------------------------------------------- /Code/05 Authentication/08 Finished/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/08 Finished/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/05 Authentication/08 Finished/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/08 Finished/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/05 Authentication/08 Finished/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/05 Authentication/ZZ V2-finished/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | .env 6 | -------------------------------------------------------------------------------- /Code/05 Authentication/ZZ V2-finished/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/05 Authentication/ZZ V2-finished/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/05 Authentication/ZZ V2-finished/app/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/05 Authentication/ZZ V2-finished/app/routes/expenses.raw.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/raw 2 | 3 | import { requireUserSession } from '~/data/auth.server'; 4 | import { getExpenses } from '~/data/expenses.server'; 5 | 6 | export async function loader({ request }) { 7 | const userId = await requireUserSession(request); 8 | return getExpenses(userId); 9 | } 10 | -------------------------------------------------------------------------------- /Code/05 Authentication/ZZ V2-finished/app/routes/logout.js: -------------------------------------------------------------------------------- 1 | import { json } from '@remix-run/node'; 2 | import { destroyUserSession } from '~/data/auth.server'; 3 | 4 | export function action({ request }) { 5 | if (request.method !== 'POST') { 6 | throw json({ message: 'Invalid request method' }, { status: 400 }); 7 | } 8 | 9 | return destroyUserSession(request); 10 | } 11 | -------------------------------------------------------------------------------- /Code/05 Authentication/ZZ V2-finished/app/tailwind.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | html, 6 | body { 7 | @apply bg-white dark:bg-gray-950; 8 | 9 | @media (prefers-color-scheme: dark) { 10 | color-scheme: dark; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Code/05 Authentication/ZZ V2-finished/postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /Code/05 Authentication/ZZ V2-finished/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/ZZ V2-finished/public/favicon.ico -------------------------------------------------------------------------------- /Code/05 Authentication/ZZ V2-finished/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/ZZ V2-finished/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/05 Authentication/ZZ V2-finished/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/05 Authentication/ZZ V2-finished/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/06 Deployment/01 Starting Project/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/06 Deployment/01 Starting Project/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | -------------------------------------------------------------------------------- /Code/06 Deployment/01 Starting Project/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/06 Deployment/01 Starting Project/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/06 Deployment/01 Starting Project/app/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/06 Deployment/01 Starting Project/app/routes/expenses.raw.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/raw 2 | 3 | import { requireUserSession } from '~/data/auth.server'; 4 | import { getExpenses } from '~/data/expenses.server'; 5 | 6 | export async function loader({request}) { 7 | const userId = await requireUserSession(request); 8 | return getExpenses(userId); 9 | } 10 | -------------------------------------------------------------------------------- /Code/06 Deployment/01 Starting Project/app/routes/logout.js: -------------------------------------------------------------------------------- 1 | import { json } from '@remix-run/node'; 2 | import { destroyUserSession } from '~/data/auth.server'; 3 | 4 | export function action({ request }) { 5 | if (request.method !== 'POST') { 6 | throw json({ message: 'Invalid request method' }, { status: 400 }); 7 | } 8 | 9 | return destroyUserSession(request); 10 | } 11 | -------------------------------------------------------------------------------- /Code/06 Deployment/01 Starting Project/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/06 Deployment/01 Starting Project/public/favicon.ico -------------------------------------------------------------------------------- /Code/06 Deployment/01 Starting Project/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/06 Deployment/01 Starting Project/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/06 Deployment/01 Starting Project/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/06 Deployment/01 Starting Project/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/06 Deployment/01 Starting Project/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/06 Deployment/02 Adding Metadata/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/06 Deployment/02 Adding Metadata/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | .DS_Store -------------------------------------------------------------------------------- /Code/06 Deployment/02 Adding Metadata/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/06 Deployment/02 Adding Metadata/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/06 Deployment/02 Adding Metadata/app/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/06 Deployment/02 Adding Metadata/app/routes/expenses.raw.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/raw 2 | 3 | import { requireUserSession } from '~/data/auth.server'; 4 | import { getExpenses } from '~/data/expenses.server'; 5 | 6 | export async function loader({request}) { 7 | const userId = await requireUserSession(request); 8 | return getExpenses(userId); 9 | } 10 | -------------------------------------------------------------------------------- /Code/06 Deployment/02 Adding Metadata/app/routes/logout.js: -------------------------------------------------------------------------------- 1 | import { json } from '@remix-run/node'; 2 | import { destroyUserSession } from '~/data/auth.server'; 3 | 4 | export function action({ request }) { 5 | if (request.method !== 'POST') { 6 | throw json({ message: 'Invalid request method' }, { status: 400 }); 7 | } 8 | 9 | return destroyUserSession(request); 10 | } 11 | -------------------------------------------------------------------------------- /Code/06 Deployment/02 Adding Metadata/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/06 Deployment/02 Adding Metadata/public/favicon.ico -------------------------------------------------------------------------------- /Code/06 Deployment/02 Adding Metadata/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/06 Deployment/02 Adding Metadata/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/06 Deployment/02 Adding Metadata/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/06 Deployment/02 Adding Metadata/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/06 Deployment/02 Adding Metadata/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/06 Deployment/03 Using Action & Loader Headers/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/06 Deployment/03 Using Action & Loader Headers/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | .DS_Store -------------------------------------------------------------------------------- /Code/06 Deployment/03 Using Action & Loader Headers/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/06 Deployment/03 Using Action & Loader Headers/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/06 Deployment/03 Using Action & Loader Headers/app/routes/expenses.raw.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/raw 2 | 3 | import { requireUserSession } from '~/data/auth.server'; 4 | import { getExpenses } from '~/data/expenses.server'; 5 | 6 | export async function loader({request}) { 7 | const userId = await requireUserSession(request); 8 | return getExpenses(userId); 9 | } 10 | -------------------------------------------------------------------------------- /Code/06 Deployment/03 Using Action & Loader Headers/app/routes/logout.js: -------------------------------------------------------------------------------- 1 | import { json } from '@remix-run/node'; 2 | import { destroyUserSession } from '~/data/auth.server'; 3 | 4 | export function action({ request }) { 5 | if (request.method !== 'POST') { 6 | throw json({ message: 'Invalid request method' }, { status: 400 }); 7 | } 8 | 9 | return destroyUserSession(request); 10 | } 11 | -------------------------------------------------------------------------------- /Code/06 Deployment/03 Using Action & Loader Headers/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/06 Deployment/03 Using Action & Loader Headers/public/favicon.ico -------------------------------------------------------------------------------- /Code/06 Deployment/03 Using Action & Loader Headers/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/06 Deployment/03 Using Action & Loader Headers/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/06 Deployment/03 Using Action & Loader Headers/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/06 Deployment/03 Using Action & Loader Headers/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/06 Deployment/03 Using Action & Loader Headers/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/06 Deployment/04 Disable JavaScript/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | module.exports = { 3 | extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"], 4 | }; 5 | -------------------------------------------------------------------------------- /Code/06 Deployment/04 Disable JavaScript/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | /public/build 6 | .env 7 | .DS_Store -------------------------------------------------------------------------------- /Code/06 Deployment/04 Disable JavaScript/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/06 Deployment/04 Disable JavaScript/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/06 Deployment/04 Disable JavaScript/app/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/06 Deployment/04 Disable JavaScript/app/routes/expenses.raw.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/raw 2 | 3 | import { requireUserSession } from '~/data/auth.server'; 4 | import { getExpenses } from '~/data/expenses.server'; 5 | 6 | export async function loader({request}) { 7 | const userId = await requireUserSession(request); 8 | return getExpenses(userId); 9 | } 10 | -------------------------------------------------------------------------------- /Code/06 Deployment/04 Disable JavaScript/app/routes/logout.js: -------------------------------------------------------------------------------- 1 | import { json } from '@remix-run/node'; 2 | import { destroyUserSession } from '~/data/auth.server'; 3 | 4 | export function action({ request }) { 5 | if (request.method !== 'POST') { 6 | throw json({ message: 'Invalid request method' }, { status: 400 }); 7 | } 8 | 9 | return destroyUserSession(request); 10 | } 11 | -------------------------------------------------------------------------------- /Code/06 Deployment/04 Disable JavaScript/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/06 Deployment/04 Disable JavaScript/public/favicon.ico -------------------------------------------------------------------------------- /Code/06 Deployment/04 Disable JavaScript/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/06 Deployment/04 Disable JavaScript/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/06 Deployment/04 Disable JavaScript/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/06 Deployment/04 Disable JavaScript/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Code/06 Deployment/04 Disable JavaScript/remix.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@remix-run/dev').AppConfig} */ 2 | module.exports = { 3 | ignoredRouteFiles: ["**/.*"], 4 | // appDirectory: "app", 5 | // assetsBuildDirectory: "public/build", 6 | // serverBuildPath: "build/index.js", 7 | // publicPath: "/build/", 8 | }; 9 | -------------------------------------------------------------------------------- /Code/06 Deployment/ZZ V2-finished/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | .env 6 | -------------------------------------------------------------------------------- /Code/06 Deployment/ZZ V2-finished/app/components/util/Error.jsx: -------------------------------------------------------------------------------- 1 | import { FaExclamationCircle } from 'react-icons/fa'; 2 | 3 | function Error({ title, children }) { 4 | return ( 5 |
6 |
7 | 8 |
9 |

{title}

10 | {children} 11 |
12 | ); 13 | } 14 | 15 | export default Error; 16 | -------------------------------------------------------------------------------- /Code/06 Deployment/ZZ V2-finished/app/components/util/Logo.jsx: -------------------------------------------------------------------------------- 1 | import { Link } from '@remix-run/react'; 2 | 3 | function Logo() { 4 | return ( 5 |

6 | RemixExpenses 7 |

8 | ); 9 | } 10 | 11 | export default Logo; 12 | -------------------------------------------------------------------------------- /Code/06 Deployment/ZZ V2-finished/app/components/util/Modal.jsx: -------------------------------------------------------------------------------- 1 | function Modal({ children, onClose }) { 2 | return ( 3 |
4 | event.stopPropagation()} 8 | > 9 | {children} 10 | 11 |
12 | ); 13 | } 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /Code/06 Deployment/ZZ V2-finished/app/routes/expenses.raw.jsx: -------------------------------------------------------------------------------- 1 | // /expenses/raw 2 | 3 | import { requireUserSession } from '~/data/auth.server'; 4 | import { getExpenses } from '~/data/expenses.server'; 5 | 6 | export async function loader({request}) { 7 | const userId = await requireUserSession(request); 8 | return getExpenses(userId); 9 | } 10 | -------------------------------------------------------------------------------- /Code/06 Deployment/ZZ V2-finished/app/routes/logout.js: -------------------------------------------------------------------------------- 1 | import { json } from '@remix-run/node'; 2 | import { destroyUserSession } from '~/data/auth.server'; 3 | 4 | export function action({ request }) { 5 | if (request.method !== 'POST') { 6 | throw json({ message: 'Invalid request method' }, { status: 400 }); 7 | } 8 | 9 | return destroyUserSession(request); 10 | } 11 | -------------------------------------------------------------------------------- /Code/06 Deployment/ZZ V2-finished/app/tailwind.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | html, 6 | body { 7 | @apply bg-white dark:bg-gray-950; 8 | 9 | @media (prefers-color-scheme: dark) { 10 | color-scheme: dark; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Code/06 Deployment/ZZ V2-finished/postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /Code/06 Deployment/ZZ V2-finished/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/06 Deployment/ZZ V2-finished/public/favicon.ico -------------------------------------------------------------------------------- /Code/06 Deployment/ZZ V2-finished/public/images/expenses-chart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/06 Deployment/ZZ V2-finished/public/images/expenses-chart.jpg -------------------------------------------------------------------------------- /Code/06 Deployment/ZZ V2-finished/public/images/expenses-management.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Code/06 Deployment/ZZ V2-finished/public/images/expenses-management.jpg -------------------------------------------------------------------------------- /Slides/remix-slides.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/academind/remix-practical-guide-course-resources/d324c79ca029f2bde3cf6e0f0582555161137ee0/Slides/remix-slides.pdf --------------------------------------------------------------------------------