diff --git a/src/actions/guides/command_line_tasks/built_in.cr b/src/actions/guides/command_line_tasks/built_in.cr index d66c21f7..9be74913 100644 --- a/src/actions/guides/command_line_tasks/built_in.cr +++ b/src/actions/guides/command_line_tasks/built_in.cr @@ -12,7 +12,7 @@ class Guides::CommandLineTasks::BuiltIn < GuideAction Lucky comes bundled with [LuckyTask](https://github.com/luckyframework/lucky_task) for creating tasks. Tasks are used to run some code that sits outside of your main application. When you need to add a task, you'll place it in the `tasks` folder. - To see a list of the available tasks in your application, use `lucky --help`. + To see a list of the available tasks in your application, use `lucky tasks`. You can think of a Luck Task just like a [Rake task](https://github.com/ruby/rake) in Ruby, [npm script](https://docs.npmjs.com/misc/scripts) for Node, or [Mix Task](https://hexdocs.pm/mix/Mix.Task.html) for Elixir. @@ -27,7 +27,7 @@ class Guides::CommandLineTasks::BuiltIn < GuideAction By default, Lucky has lots of tasks already built in that you may find really handy while developing your application. These are the ones that you get by default. ```plain - # Generated with lucky --help + # Generated with lucky tasks ▸ db.console Access PostgreSQL console ▸ db.create Create the database ▸ db.drop Drop the database diff --git a/src/actions/guides/getting-started/installing.cr b/src/actions/guides/getting-started/installing.cr index cbcac42b..8c444582 100644 --- a/src/actions/guides/getting-started/installing.cr +++ b/src/actions/guides/getting-started/installing.cr @@ -1,8 +1,7 @@ class Guides::GettingStarted::Installing < GuideAction ANCHOR_INSTALL_REQUIRED_DEPENDENCIES = "perma-install-required-dependencies" ANCHOR_POSTGRESQL = "perma-install-postgres" - ANCHOR_PROC_MANAGER = "perma-install-process-manager" - ANCHOR_NODE = "perma-install-node" + ANCHOR_BUN = "perma-install-bun" guide_route "/getting-started/installing" def self.title @@ -318,7 +317,7 @@ class Guides::GettingStarted::Installing < GuideAction postgres=# \\q ``` - #{permalink(ANCHOR_NODE)} + #{permalink(ANCHOR_BUN)} ## Bun (optional) > You can skip this if you only plan to build APIs. diff --git a/src/actions/guides/tutorial/00_overview.cr b/src/actions/guides/tutorial/00_overview.cr index 1067e843..f2eec466 100644 --- a/src/actions/guides/tutorial/00_overview.cr +++ b/src/actions/guides/tutorial/00_overview.cr @@ -42,7 +42,7 @@ class Guides::Tutorial::Overview < GuideAction * installed Crystal. `crystal -v` should be at least #{LuckyCliVersion.min_compatible_crystal_version} or higher * installed Lucky. `lucky -v` should be #{LuckyCliVersion.current_tag}. * installed [Postgres](#{Guides::GettingStarted::Installing.path(anchor: Guides::GettingStarted::Installing::ANCHOR_POSTGRESQL)}). `psql --version` should be `>= #{LuckyDependencyVersions.min_compatible_postgres_version}` - * installed [Node](#{Guides::GettingStarted::Installing.path(anchor: Guides::GettingStarted::Installing::ANCHOR_NODE)}). `node -v` should be `>= v#{LuckyDependencyVersions.min_compatible_node_version}` (used for building css and javascript) + * installed [Bun](#{Guides::GettingStarted::Installing.path(anchor: Guides::GettingStarted::Installing::ANCHOR_BUN)}). `bun -v` should be `>= v#{LuckyDependencyVersions.min_compatible_bun_version}` (used for bundling css and javascript/typescript) ## The Wizard @@ -98,22 +98,22 @@ class Guides::Tutorial::Overview < GuideAction > For more information on setting up your database, read the [Database Setup](#{Guides::Database::DatabaseSetup.path}) guide. - ### Setup Script + ### Bootstrap Setup - Next we will run our setup script. This script does a few things: + Next we will run our setup script to bootstrap our app. This script does a few things: * Run a system check for 3rd party dependencies needed to run this app. - * Setup our assets (css, javascript) using Yarn + * Setup our assets (css, javascript) using Bun * Install Crystal shard dependencies. (e.g. Lucky, Avram, etc...) * Create our database. In this case, a database named `clover_developement` * Verify that we can connect to this new database * Run SQL code (migration) to create our users table. * Import sample data in to our database. On the first run, there's no sample data. - Run the setup script. Enter `./script/setup`: + Run the setup script. Enter `crystal script/setup.cr`: ```bash - ./script/setup + crystal script/setup.cr ``` > This may take a bit of time to run. If anything fails at any point, let us know! @@ -136,14 +136,14 @@ class Guides::Tutorial::Overview < GuideAction ## Browsing your Application Open up your favorite browser, and head over to `http://127.0.0.1:3000`. This URL will be printed - in your terminal log output. + in your terminal log output when the `web` process has booted. > To change the port your app runs on, update the `port` option in the `config/watch.yml` file. You should now see the Lucky home page. - Click the "VIEW YOUR NEW APP" button to be taken to a "Sign Up" page. Because the wizard set us up - with Authentication, we now have the ability to create a User account, and log in. Make your account! + Click the "VIEW YOUR NEW APP" button to be taken to a "Sign Up" page. Because the wizard set up + authentication, we now have the ability to create a User account, and log in. Make your account! After you've signed up, you are taken to your "Profile" page. @@ -160,7 +160,7 @@ class Guides::Tutorial::Overview < GuideAction * Sign back in to your account * View your terminal to see how each request is logged to the output - > When you're done, stop your server with `ctrl-C` before moving on to the next section. + > When you're done, stop your server with `ctrl-c` before moving on to the next section. MD end diff --git a/src/actions/guides/tutorial/01_new_resource.cr b/src/actions/guides/tutorial/01_new_resource.cr index 268c91ed..58c9a558 100644 --- a/src/actions/guides/tutorial/01_new_resource.cr +++ b/src/actions/guides/tutorial/01_new_resource.cr @@ -10,9 +10,12 @@ class Guides::Tutorial::NewResource < GuideAction ## Using the Generator CLI Lucky comes with a lot of neat commands to make building your application a little easier. - From your terminal, type `lucky -h`. Give it a moment to compile, then see a list of the commands you can use. + From your terminal, type `lucky -h`. This will display a few commands you can run; one in particular is the `tasks` command. + Now run `lucky tasks` and give it a moment to compile. This will display even more commands you can run. - For our next section, we will be generating a new "resource"; the "Fortune". In this context, a resource is a Model, + > This commands must compile because it includes any custom commands you've added as well as commands added by 3rd party dependencies (shards). + + For our next section, we will be generating a new "resource"; the `Fortune`. In this context, a resource is a Model, Action, Page, Component, Query, and Operation. Lucky breaks a resource down in to smaller class components which we will discuss over the tutorial. diff --git a/src/actions/guides/tutorial/02_assocations.cr b/src/actions/guides/tutorial/02_assocations.cr index d641dcda..665d8c77 100644 --- a/src/actions/guides/tutorial/02_assocations.cr +++ b/src/actions/guides/tutorial/02_assocations.cr @@ -9,7 +9,7 @@ class Guides::Tutorial::Associations < GuideAction <<-MD ## New Migrations - When we generated our migration, we didn't add a way to tie Fortunes to a specific User. It may be common + When we generated our migration, we didn't add a way to tie Fortunes to a specific `User`. It may be common that you will need to generate separate migrations to update models that already exist in your application. Let's try that now. @@ -36,7 +36,7 @@ class Guides::Tutorial::Associations < GuideAction # db/migrations/#{Time.utc.to_s("%Y%m%d%H%I%S")}_add_belongs_to_user_for_fortune.cr def migrate - # FYI: We will run in to an error. Be sure to keep reading before running any code + # NOTE: We will run into an error. Be sure to keep reading before running any code alter table_for(Fortune) do add_belongs_to user : User, on_delete: :cascade, fill_existing_with: :nothing end @@ -112,26 +112,26 @@ class Guides::Tutorial::Associations < GuideAction At the bottom of the `table` block, we will add this new code: - ```diff + ```crystal # src/models/user.cr table do column email : String column encrypted_password : String - + has_many fortunes : Fortune + has_many fortunes : Fortune # <--- Add this line end ``` Next we will update our `Fortune` model in `src/models/fortune.cr` with this code: - ```diff + ```crystal # src/models/fortune.cr table do column text : String - + belongs_to user : User + belongs_to user : User # <--- Add this line end ``` @@ -150,11 +150,11 @@ class Guides::Tutorial::Associations < GuideAction * Sign in, and try to create a fortune. Notice it fails * View your logs to see "Failed to save SaveFortune". * Use `lucky exec` to truncate all `User` records with the `UserQuery` object. - * Pass `user_id: current_user.id` to `SaveFortune.create` - * Then use your app to make a new user record, because we still need one 😄 We will update the forms later in the tutorial. + > Before continuing to the next section, create a new user account. We will need it in the next section. + MD end end diff --git a/src/actions/guides/tutorial/03_design.cr b/src/actions/guides/tutorial/03_design.cr index df316601..1e3ec036 100644 --- a/src/actions/guides/tutorial/03_design.cr +++ b/src/actions/guides/tutorial/03_design.cr @@ -46,12 +46,12 @@ class Guides::Tutorial::Design < GuideAction ## Updating the Layout - As mentioned previously, we currently have two separate layouts. One for when users are logged in `MainLayout`, and one for - when users are logged out `AuthLayout`. These files live in the root of your `src/pages/` directory. We will update our `AuthLayout` + As mentioned previously, we currently have two separate layouts. One for when users are logged-in `MainLayout`, and one for + when users are logged-out `AuthLayout`. These files live in the root of your `src/pages/` directory. We will update our `AuthLayout` to start so we can get a feel for writing HTML in Lucky. When it comes to writing HTML in Lucky, we use plain Crystal methods that generate HTML for us! - [Read the HTML guide](#{Guides::Frontend::RenderingHtml.path}) for more details. + Read the [Rendering HTML guide](#{Guides::Frontend::RenderingHtml.path}) for more details. ### Anatomy of the layout @@ -70,16 +70,16 @@ class Guides::Tutorial::Design < GuideAction ```crystal # src/pages/auth_layout.cr - html class: "h-100", lang: "en" do + html lang: "en" do mount Shared::LayoutHead, page_title: page_title - body class: "d-flex flex-column h-100" do + body do mount Shared::FlashMessages, context.flash - main class: "flex-shrink-0" do + main class: "main-content" do content end - footer class: "footer mt-auto py-3 bg-light" do + footer class: "footer" do div class: "container" do span "CloverApp", class: "text-muted" end @@ -95,38 +95,25 @@ class Guides::Tutorial::Design < GuideAction ## Adding a CSS framework - If you haven't guessed by now, we've started adding [Bootstrap](https://getbootstrap.com/) classes to our HTML. You're free - to use any (or no) CSS framework you wish. There are no limitations since Lucky includes [LaravelMix](https://laravel-mix.com/) - which just wraps Webpack. We will stick with Bootstrap just for the purposes of this Tutorial. + You have the flexibility to use any (or no) css framework you would like. Lucky comes with [Bun](https://bun.sh/) out of the box + allowing you to add in packages as you need. For the purposes of this tutorial, we are going to keep it very simple and use + [SimpleCSS](https://simplecss.org/) ### Installing a CSS framework - Lucky uses `yarn` by default, so this tutorial will as well. If you prefer a different installation you may use that. - - Before we install Bootstrap, we should shut down our server. (`ctrl-c`) Then from the terminal, we can run: + Before we install SimpleCSS, we should shut down our server. (`ctrl-c`) Then from the terminal, we can run: ```bash - yarn add bootstrap @popperjs/core + bun add simpledotcss ``` - > PopperJS is required for some of the Bootstrap components such as dropdowns and popovers to function correctly. + Next we will import SimpleCSS in our stylesheet. Open up `src/css/app.css`. You'll find some default normalize styles in here. - Next we will import Bootstrap in our stylesheet. Open up `src/css/app.scss`. You'll find some default normalize styles in here. Now that we're using - a CSS framework, all of these can go away! Replace everything with this code: + Add this to the top: ```scss - // src/css/app.scss - @import "bootstrap"; - ``` - - Now, import Bootstrap into `src/js/app.js` to ensure the Bootstrap components that require Javascript function correctly. - Open that file and add this code: - - ```diff - // src/js/app.js - require("@rails/ujs").start(); - - + import "bootstrap"; + // src/css/app.css + @import "simpledotcss/simple.min.css"; ``` Finally, restart the dev server from the terminal `lucky dev`. @@ -144,13 +131,13 @@ class Guides::Tutorial::Design < GuideAction ```crystal # src/pages/home/index_page.cr def content - div class: "px-4 py-5 my-5 text-center" do - h1 "CloverApp", class: "display-5 fw-bold" - div class: "col-lg-6 mx-auto" do - para "It's your Lucky day! See a fortune, and share the luck.", class: "lead mb-4" - div class: "d-grid gap-2 d-sm-flex justify-content-sm-center" do - link "Join", to: SignUps::New, class: "btn btn-primary btn-lg px-4 me-sm-3" - link "Login", to: SignIns::New, class: "btn btn-outline-secondary btn-lg px-4" + div do + h1 "CloverApp", class: "title" + div do + para "It's your Lucky day! See a fortune, and share the luck.", class: "tagline" + div class: "button-group" do + link "Join", to: SignUps::New, class: "btn-primary" + link "Login", to: SignIns::New, class: "btn-secondary" end end end @@ -176,7 +163,7 @@ class Guides::Tutorial::Design < GuideAction Try this: * Add a copyright note to your footer that always displays the current year. - * Create a custom CSS style using normal raw CSS in your `src/css/app.scss`. + * Create custom CSS styles using normal raw CSS in your `src/css/app.css`. * Apply that custom style to a tag on your Home Page. * Update the styles for your Login / Signup pages diff --git a/src/actions/guides/tutorial/04_using_components.cr b/src/actions/guides/tutorial/04_using_components.cr index d132d2bd..e88e3f76 100644 --- a/src/actions/guides/tutorial/04_using_components.cr +++ b/src/actions/guides/tutorial/04_using_components.cr @@ -37,7 +37,7 @@ class Guides::Tutorial::UsingComponents < GuideAction ```diff # src/pages/auth_layout.cr - - footer class: "footer mt-auto py-3 bg-light" do + - footer class: "footer" do - div class: "container" do - span "CloverApp", class: "text-muted" - end @@ -50,7 +50,7 @@ class Guides::Tutorial::UsingComponents < GuideAction ```crystal # src/components/shared/footer.cr def render - footer class: "footer mt-auto py-3 bg-light" do + footer class: "footer" do div class: "container" do span "CloverApp", class: "text-muted" end diff --git a/src/actions/guides/tutorial/05_operations_factories.cr b/src/actions/guides/tutorial/05_operations_factories.cr index b1786e59..3a2b56da 100644 --- a/src/actions/guides/tutorial/05_operations_factories.cr +++ b/src/actions/guides/tutorial/05_operations_factories.cr @@ -41,7 +41,7 @@ class Guides::Tutorial::OperationsFactories < GuideAction ``` You should now have a code editor open which may still show code from the last time we ran this. - Comment out any existing code and add this: + Comment out any code you previously added and add this below it: ```crystal SignUpUser.create(email: "mytest@test.com", password: "notsecret", password_confirmation: "not_secret") do |operation, saved_user| diff --git a/src/actions/guides/tutorial/06_queries.cr b/src/actions/guides/tutorial/06_queries.cr index 728c9852..5a67c4e8 100644 --- a/src/actions/guides/tutorial/06_queries.cr +++ b/src/actions/guides/tutorial/06_queries.cr @@ -96,22 +96,28 @@ class Guides::Tutorial::Queries < GuideAction ```crystal # src/pages/home/index_page.cr def content - div class: "px-4 py-5 my-5 text-center" do - # ... previous markup + div do + h1 "CloverApp", class: "title" + div do + para "It's your Lucky day! See a fortune, and share the luck.", class: "tagline" + div class: "button-group" do + link "Join", to: SignUps::New, class: "btn-primary" + link "Login", to: SignIns::New, class: "btn-secondary" + end + end end div class: "container" do - # Add this block of code here - div class: "list-group list-group-flush border-bottom scrollarea" do - fortunes.each do |fortune| - link to: Fortunes::Show.with(fortune.id), class: "list-group-item list-group-item-action py-3 lh-tight" do - div class: "d-flex w-100 align-items-center justify-content-between" do + # we're adding code here + fortunes.each do |fortune| + div class: "fortune-card" do + link to: Fortunes::Show.with(fortune.id) do + div class: "fortune-timestamp" do small time_ago_in_words(fortune.created_at), class: "text-muted" end - div fortune.text, class: "col-10 mb-1 small" + div fortune.text, class: "fortune-text" end end end - end end ``` @@ -131,7 +137,6 @@ class Guides::Tutorial::Queries < GuideAction * Update your `UserFactory` to generate a random `name`. * Update existing user records with a random name. (hint: search the guides (`ctrl-k`) for mention of "bulk updating") * Update the fortunes to display the user's name that wrote it. - MD end end