├── MyApp
├── App_Data
│ ├── .gitkeep
│ └── README.md
├── wwwroot
│ ├── admin
│ │ └── sections
│ │ │ ├── index.mjs
│ │ │ └── Bookings.mjs
│ ├── posts
│ │ ├── razor-ssg-new-blog-features.mjs
│ │ ├── components
│ │ │ ├── HelloApi.mjs
│ │ │ ├── ChartJs.mjs
│ │ │ └── VueComponentLibrary.mjs
│ │ └── javascript.mjs
│ ├── tailwind
│ │ └── README.txt
│ ├── pages
│ │ ├── Account
│ │ │ └── Manage
│ │ │ │ └── EnableAuthenticator.mjs
│ │ ├── Counter.mjs
│ │ └── Bookings.mjs
│ ├── lib
│ │ └── typings
│ │ │ ├── vue
│ │ │ └── index.d.ts
│ │ │ └── @vue
│ │ │ └── compiler-dom.d.ts
│ ├── img
│ │ ├── logo.svg
│ │ └── profiles
│ │ │ ├── user3.svg
│ │ │ └── user2.svg
│ └── css
│ │ ├── lite-yt-embed.css
│ │ └── highlight.css
├── Components
│ ├── Account
│ │ ├── Pages
│ │ │ ├── _Imports.razor
│ │ │ ├── Manage
│ │ │ │ ├── _Imports.razor
│ │ │ │ ├── ApiKeys.razor
│ │ │ │ ├── PersonalData.razor
│ │ │ │ ├── ResetAuthenticator.razor
│ │ │ │ ├── ManageNavPages.cs
│ │ │ │ ├── Disable2fa.razor
│ │ │ │ ├── GenerateRecoveryCodes.razor
│ │ │ │ ├── Index.razor
│ │ │ │ └── DeletePersonalData.razor
│ │ │ ├── Logout.razor
│ │ │ ├── InvalidUser.razor
│ │ │ ├── InvalidPasswordReset.razor
│ │ │ ├── Lockout.razor
│ │ │ ├── ForgotPasswordConfirmation.razor
│ │ │ ├── ResetPasswordConfirmation.razor
│ │ │ ├── AccessDenied.razor
│ │ │ ├── ConfirmEmail.razor
│ │ │ ├── ConfirmEmailChange.razor
│ │ │ ├── RegisterConfirmation.razor
│ │ │ ├── ResendEmailConfirmation.razor
│ │ │ ├── ForgotPassword.razor
│ │ │ └── LoginWithRecoveryCode.razor
│ │ ├── Shared
│ │ │ ├── RedirectToLogin.razor
│ │ │ ├── ManageLayout.razor
│ │ │ ├── AccountLayout.razor
│ │ │ ├── ShowRecoveryCodes.razor
│ │ │ ├── ExternalLoginPicker.razor
│ │ │ ├── ManageNavMenu.razor
│ │ │ └── StatusMessage.razor
│ │ ├── IdentityUserAccessor.cs
│ │ ├── IdentityNoOpEmailSender.cs
│ │ ├── IdentityRevalidatingAuthenticationStateProvider.cs
│ │ └── IdentityRedirectManager.cs
│ ├── Pages
│ │ ├── Admin.razor
│ │ ├── Counter.razor
│ │ ├── Videos.razor
│ │ ├── Docs.razor
│ │ ├── Posts
│ │ │ ├── Author.razor
│ │ │ ├── Index.razor
│ │ │ ├── Year.razor
│ │ │ └── Tagged.razor
│ │ ├── Error.razor
│ │ ├── Weather.razor
│ │ ├── Profile.razor
│ │ ├── Secure
│ │ │ └── Bookings.razor
│ │ └── Home.razor
│ ├── Shared
│ │ ├── SrcVuePage.razor
│ │ ├── SrcRazorPage.razor
│ │ ├── BlogTitle.razor
│ │ ├── ShellCommand.razor
│ │ ├── FormLoading.razor
│ │ ├── Footer.razor
│ │ ├── BlogPosts.razor
│ │ └── VideoGroup.razor
│ ├── Routes.razor
│ ├── _Imports.razor
│ ├── App.razor
│ └── Layout
│ │ └── AdminLayout.razor
├── tailwind.config.js
├── _includes
│ └── component-links.md
├── _posts
│ ├── config.json
│ └── authors.json
├── _videos
│ ├── vue
│ │ ├── admin.md
│ │ ├── modern.md
│ │ ├── components.md
│ │ └── autoquerygrid.md
│ └── blazor
│ │ ├── tailwind.md
│ │ ├── components.md
│ │ ├── admin.md
│ │ ├── blazor-vue.md
│ │ ├── darkmode.md
│ │ ├── universal.md
│ │ └── blazor.md
├── appsettings.json
├── AppComponentBase.cs
├── appsettings.Development.json
├── Configure.Auth.cs
├── package.json
├── tsconfig.json
├── Configure.AutoQuery.cs
├── Configure.OpenApi.cs
├── Configure.HealthChecks.cs
├── Properties
│ └── launchSettings.json
├── Configure.Db.cs
├── Configure.RequestLogs.cs
├── Configure.AI.Chat.cs
├── Configure.Markdown.cs
├── Markdown.Videos.cs
├── Configure.ApiKeys.cs
├── _pages
│ └── about.md
├── Markdown.Meta.cs
├── Migrations
│ └── Migration1000.cs
├── MyApp.csproj
├── Program.cs
├── Configure.AppHost.cs
└── MarkdownTagHelper.cs
├── .kamal
├── hooks
│ ├── docker-setup.sample
│ ├── post-proxy-reboot.sample
│ ├── pre-proxy-reboot.sample
│ ├── post-deploy.sample
│ ├── pre-connect.sample
│ ├── pre-build.sample
│ └── pre-deploy.sample
└── secrets
├── MyApp.ServiceModel
├── Types
│ └── README.md
├── Roles.cs
├── Hello.cs
├── AppRoles.cs
├── MyApp.ServiceModel.csproj
└── User.cs
├── MyApp.slnx
├── MyApp.ServiceInterface
├── Data
│ ├── ApplicationDbContext.cs
│ ├── ApplicationUser.cs
│ └── CustomUserSession.cs
├── MyApp.ServiceInterface.csproj
├── MyServices.cs
└── EmailServices.cs
├── .vscode
├── tasks.json
└── launch.json
├── README.md
├── MyApp.Tests
├── UnitTest.cs
├── MyApp.Tests.csproj
├── IntegrationTest.cs
└── MigrationTasks.cs
├── load-env.sh
├── .github
└── workflows
│ └── build.yml
└── config
└── deploy.yml
/MyApp/App_Data/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.kamal/hooks/docker-setup.sample:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | echo "Docker set up on $KAMAL_HOSTS..."
4 |
--------------------------------------------------------------------------------
/.kamal/hooks/post-proxy-reboot.sample:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | echo "Rebooted kamal-proxy on $KAMAL_HOSTS"
4 |
--------------------------------------------------------------------------------
/.kamal/hooks/pre-proxy-reboot.sample:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | echo "Rebooting kamal-proxy on $KAMAL_HOSTS..."
4 |
--------------------------------------------------------------------------------
/MyApp/wwwroot/admin/sections/index.mjs:
--------------------------------------------------------------------------------
1 | import Bookings from './Bookings.mjs'
2 | export {
3 | Bookings,
4 | }
--------------------------------------------------------------------------------
/MyApp/Components/Account/Pages/_Imports.razor:
--------------------------------------------------------------------------------
1 | @using MyApp.Components.Account.Shared
2 | @layout AccountLayout
3 |
--------------------------------------------------------------------------------
/MyApp/Components/Account/Pages/Manage/_Imports.razor:
--------------------------------------------------------------------------------
1 | @layout ManageLayout
2 | @attribute [Microsoft.AspNetCore.Authorization.Authorize]
3 |
--------------------------------------------------------------------------------
/MyApp/wwwroot/posts/razor-ssg-new-blog-features.mjs:
--------------------------------------------------------------------------------
1 | import ChartJs from './components/ChartJs.mjs'
2 |
3 | export default {
4 | components: { ChartJs }
5 | }
6 |
--------------------------------------------------------------------------------
/MyApp/Components/Pages/Admin.razor:
--------------------------------------------------------------------------------
1 | @page "/admin"
2 | @layout Layout.AdminLayout
3 |
4 |
You have successfully signed out.
9 |10 | The password reset link is invalid. 11 |
12 | 13 |This account has been locked out, please try again later.
10 |9 | Please check your email to reset your password. 10 |
11 |6 | @BlazorHtml.Raw(Heading) 7 |
8 |Current count: {{currentCount}}
6 | 7 |
9 | Your password has been reset. Please
10 | You do not have access to this resource. 11 |
12 |Loading...
8 | } 9 | else 10 | { 11 | @Body 12 | } 13 | 14 | @code { 15 | [CascadingParameter] 16 | private HttpContext? HttpContext { get; set; } 17 | 18 | protected override void OnParametersSet() 19 | { 20 | if (HttpContext is null) 21 | { 22 | // If this code runs, we're currently rendering in interactive mode, so there is no HttpContext. 23 | // The identity pages need to set cookies, so they require an HttpContext. To achieve this we 24 | // must transition back from interactive mode to a server-rendered page. 25 | NavigationManager.Refresh(forceReload: true); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /MyApp/wwwroot/posts/components/ChartJs.mjs: -------------------------------------------------------------------------------- 1 | import { ref, onMounted } from "vue" 2 | import { addScript } from "@servicestack/client" 3 | 4 | const loadJs = addScript('https://cdn.jsdelivr.net/npm/chart.js/dist/chart.umd.min.js') 5 | 6 | export default { 7 | template:``, 8 | props:['type','data','options'], 9 | setup(props) { 10 | const chart = ref() 11 | onMounted(async () => { 12 | await loadJs 13 | 14 | const options = props.options || { 15 | responsive: true, 16 | legend: { 17 | position: "top" 18 | } 19 | } 20 | new Chart(chart.value, { 21 | type: props.type || "bar", 22 | data: props.data, 23 | options, 24 | }) 25 | 26 | }) 27 | return { chart } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /MyApp.ServiceInterface/MyApp.ServiceInterface.csproj: -------------------------------------------------------------------------------- 1 |7 | Put these codes in a safe place. 8 |
9 |10 | If you lose your device and don't have the recovery codes you will lose access to your account. 11 |
12 |@RecoveryCodes[row]
18 |
19 | @RecoveryCodes[row + 1]
22 |
23 |