AdminLoginForm's submit button had disabled hardcoded as static markup, not
bound to component state. The early inline <script> (before WASM boots)
flipped it via raw DOM mutation, but when the WASM runtime later resumed the
prerendered component, Blazor's own first render re-asserted the static
disabled from the markup - silently undoing the JS fix. The second
bindLoginForm() call from OnAfterRenderAsync then bailed out immediately on
the one-shot "already bound" guard, so nothing ever re-enabled it.
Fix: bind disabled to a real isReady field flipped in OnAfterRenderAsync so
Blazor owns that attribute going forward, and make the JS-side enable
idempotent (runs on every call, not gated behind the bind-once guard) as a
second line of defense.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Admin: replace the global @rendermode on <Routes>/<Router> with per-page
render mode. Login.razor now prerenders (form visible before WASM loads);
every other [Authorize] page stays prerender: false to avoid the
AuthorizeRouteView blank-render regression from earlier attempts. Adds a
"준비 중" -> "로그인" splash tied to WASM boot completion, and lets the
authenticated-shell loading overlay stay up until AdminShell actually renders.
- Contact.cshtml: fix the "Agree" checkbox missing value="true" - a checked
box sent the browser-default "on", which bool model binding can't parse,
so ModelState.IsValid silently went false and OnPostAsync returned a blank
form with no visible error on every submission. Validation summary widened
from ModelOnly to All so this class of failure isn't silent again.
- TelegramInquiryNotificationService: read Telegram:InquiryChatId (falling
back to ChatId) instead of only ChatId, matching the channel routing
CLAUDE.md documents and deploy.yml already provisions as separate secrets.
- Reconcile CLAUDE.md's self-contradicting Phase 8 prerender notes (Phase 9),
rewrite validate_admin_render.sh for the per-page design, and add a
SmartAdmin 5.5 design reference section to DOUZONE_UX_GUIDE.md for future
admin screens (existing screens unchanged, tracked as WBS P4-03).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Added Google Analytics tracking code (ID: G-25KRKY45D7) to homepage layout.
This enables:
- User behavior tracking
- Traffic analysis
- Conversion tracking
- Audience insights
Placed in <head> section to ensure tracking for all pages.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Problem: 'Assembly already defined' error when AddAdditionalAssemblies registers the same assembly twice
- MapRazorComponents<TaxBaik.WasmClient.Components.Admin.App>() automatically loads TaxBaik.Web.Client assembly
- All Page/Shared components in same assembly are auto-discovered
- AddAdditionalAssemblies with same assembly causes duplicate registration error
Solution: Remove AddAdditionalAssemblies - not needed for components in same assembly
This fixes the ObjectDisposedException crash on deployment.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Root component alone cannot load all routed WASM components.
AddAdditionalAssemblies is essential for:
- App.razor discovery
- Routes.razor registration
- All Page components in TaxBaik.WasmClient assembly
This fixes the ObjectDisposedException and Kestrel binding failures.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
MapRazorComponents<TaxBaik.WasmClient.Components.Admin.App>() automatically includes
the root component's assembly, so AddAdditionalAssemblies() was causing duplication.
Also remove VersionInfo @inject from App.razor since WebAssembly components
cannot access server DI container. Use hardcoded 'unknown' for version.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Problem: Client JavaScript/Blazor WebAssembly errors were logged but NOT sent to Telegram because ClientLogsController used LogWarning instead of LogError.
Solution: ClientLogsController now checks entry.Level:
- level='error' → LogError → Telegram alert ✓
- level='warning'/'info' → LogWarning → Log file only
Result: Browser console errors now trigger Telegram notifications:
- Blazor WebAssembly init failures
- JavaScript exceptions
- Unhandled promise rejections
- Custom client errors
This closes the monitoring gap for client-side issues.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Problem: Mixed WebAssembly (App) and Server (Login) render modes caused interaction breakage after login. Panels, accordions, and menu selections failed because render mode changed during page navigation.
Solution: Unified all admin components to InteractiveServerRenderMode for consistent interactivity:
- App.razor: Routes and HeadOutlet use InteractiveServerRenderMode
- Login.razor: Already uses InteractiveServerRenderMode
- Program.cs: Removed WebAssembly component registration
Updated validation script to require Server mode instead of WebAssembly for admin shell.
This ensures:
✅ Consistent render mode throughout admin UI
✅ Reliable component interactivity (panels, accordions, menus)
✅ Stable page navigation and state management
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Revert to InteractiveWebAssemblyRenderMode for App.razor as required by validation script.
Add back AddInteractiveWebAssemblyComponents and AddInteractiveWebAssemblyRenderMode.
Fix assembly reference to use TaxBaik.WasmClient._Imports (RootNamespace of TaxBaik.Web.Client project).
This mixed render mode architecture allows:
- App.razor: WebAssembly shell for client-side routing
- Login.razor: Server-side prerender for authentication
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Update Login component to use Blazor Server instead of WebAssembly rendering mode for consistency with the admin UI architecture.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- App.razor: Change Routes from InteractiveWebAssemblyRenderMode to InteractiveServerRenderMode (admin requires Blazor Server, not WebAssembly)
- Program.cs: Remove unnecessary AddInteractiveWebAssemblyRenderMode() and AddInteractiveWebAssemblyComponents() registrations
- Program.cs: Remove broken TaxBaik.WasmClient reference from MapRazorComponents (actual project is TaxBaik.Web.Client)
The 500 error was caused by conflicting render modes and a non-existent assembly reference. Admin pages now correctly use Blazor Server interactivity.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Add EasyMDE 2.18.0 CDN to App.razor
- Add Marked.js for markdown preview rendering
- Replace MudTextField with EasyMDE editor in BlogCreate.razor
- Replace MudTextField with EasyMDE editor in BlogEdit.razor
- Add JavaScript interop for editor initialization and content sync
- Support markdown syntax highlighting and formatting toolbar
Features:
✅ Bold, italic, strikethrough
✅ Headings (H1-H6)
✅ Code blocks and inline code
✅ Lists (ordered/unordered)
✅ Links and images
✅ Tables
✅ Quotes
✅ Horizontal rules
✅ Real-time preview (side-by-side mode)
✅ Full-screen editing
✅ Markdown guide
The editor syncs content with Blazor form on save.
Markdown syntax is preserved in database and rendered as HTML on blog pages.
- Add Markdig NuGet package (0.38.0)
- Convert blog content from markdown to HTML in Post.cshtml.cs
- Display rendered HTML content instead of raw text
- Add comprehensive markdown styling (h1-h6, lists, tables, code, etc.)
- Use TaxBaik color scheme for markdown elements
Blog posts now render properly:
✅ Headings (#, ##, ###)
✅ Bold/italic text (**text**, *text*)
✅ Lists (-, *, ordered)
✅ Tables
✅ Code blocks
✅ Blockquotes
✅ Links
Styling follows TaxBaik brand:
- Primary color for headings
- Warm typography (Noto Sans KR)
- Consistent spacing and borders
- Mobile-responsive design
- Add breadcrumb navigation to About and Services pages
- Add back-to-home buttons on all secondary pages
- Enhance footer with full site menu (Home, About, Services, Blog, Contact)
- Add related-pages section at bottom of Services page
- Improve visual hierarchy and page interconnection
Makes it easy for users to navigate between all major sections and always
know how to return to home or explore related pages.
Add breadcrumb navigation and back-to-home button to make About page
navigation clear and user-friendly. Also add related-pages section at
bottom linking to Home, Services, and Blog.
Addresses: users getting lost on About page with no clear way back.
Replace bloated multi-section layout with streamlined structure:
- Remove online-trust, About, customer-type sections from homepage
- Restore 3-service-group simplicity (business-tax, real-estate-tax, family-asset)
- Elevate blog section for SEO priority (post homepage hero)
- Move full About content to dedicated /about page (linked from hero banner)
- Replace customer-type segmentation with blog category tagging
Improves mobile readability, reduces scrolling fatigue, and aligns homepage
to core business goals (blog SEO + service clarity). About page now hosts
the full story with expertise details.
Adds an online-consulting trust strip below the hero, replaces the plain
credential row with a personal bio + expertise section, expands the
service cards from 3 broad categories to 5 specific offerings plus a
consult CTA card, and adds a customer-segment section so visitors can
self-identify their situation. Layout follows existing Bootstrap
responsive grid conventions used elsewhere on the page.