ui: i18n ko/en, auto-fill user id on auth, lang switch, UX polish

This commit is contained in:
user
2026-04-27 20:10:46 +09:00
parent e8b2c64564
commit 8dfe3b384e
4 changed files with 453 additions and 104 deletions

View File

@@ -10,7 +10,7 @@
<script>
window._tutorGoogleCallback = null;
window._tutorPendingGoogleResponse = null;
window.handleCredentialResponse = function(response) {
window.handleCredentialResponse = function (response) {
if (window._tutorGoogleCallback) {
window._tutorGoogleCallback(response);
} else {
@@ -22,56 +22,90 @@
<section id="login-view" class="login-view">
<div class="login-card">
<p class="eyebrow">Tutor Platform</p>
<h1>Interview practice</h1>
<p class="lede">Prove you are becoming more interview-ready after each short practice loop.</p>
<div class="login-divider" data-label="Account"></div>
<div class="login-header">
<p class="eyebrow" data-i18n="eyebrow">Tutor Platform</p>
<div class="lang-switch" role="group" aria-label="Language">
<button type="button" data-lang="ko" class="lang-btn is-active">KO</button>
<button type="button" data-lang="en" class="lang-btn">EN</button>
</div>
</div>
<h1 data-i18n="titleLogin">Interview practice</h1>
<p class="lede" data-i18n="subtitleLogin">
Prove you are becoming more interview-ready after each short practice loop.
</p>
<div class="login-divider" data-i18n="accountDivider" data-label="Account"></div>
<div id="auth-area" class="auth-area">
<div id="g_id_onload" data-client_id="13671390758-bp1ed6psn43bl86r8a9kv81o40nkea90.apps.googleusercontent.com" data-callback="handleCredentialResponse" data-auto_prompt="false"></div>
<div class="g_id_signin" data-type="standard" data-size="large" data-theme="outline" data-text="sign_in_with" data-shape="rectangular" data-logo_alignment="left"></div>
<div
id="g_id_onload"
data-client_id="13671390758-bp1ed6psn43bl86r8a9kv81o40nkea90.apps.googleusercontent.com"
data-callback="handleCredentialResponse"
data-auto_prompt="false"
></div>
<div
class="g_id_signin"
data-type="standard"
data-size="large"
data-theme="outline"
data-text="sign_in_with"
data-shape="rectangular"
data-logo_alignment="left"
></div>
</div>
<p id="login-error" class="login-error" role="alert"></p>
<p class="login-legal">By signing in, you agree to our <a href="#">Terms</a> and <a href="#">Privacy Policy</a>.</p>
<p class="login-legal" data-i18n="legalLogin">
By signing in, you agree to our <a href="#">Terms</a> and
<a href="#">Privacy Policy</a>.
</p>
</div>
</section>
<main id="workspace-view" class="workspace" style="display:none;">
<main id="workspace-view" class="workspace" style="display: none">
<aside class="setup-pane" aria-label="Diagnostic setup">
<p class="eyebrow">Tutor Platform</p>
<h1>Interview practice</h1>
<p class="lede">Start a focused backend interview loop and turn one answer into evidence.</p>
<div class="workspace-header">
<p class="eyebrow" data-i18n="eyebrow">Tutor Platform</p>
<div class="lang-switch" role="group" aria-label="Language">
<button type="button" data-lang="ko" class="lang-btn is-active">KO</button>
<button type="button" data-lang="en" class="lang-btn">EN</button>
</div>
</div>
<h1 data-i18n="titleWorkspace">Interview practice</h1>
<p class="lede" data-i18n="subtitleWorkspace">
Start a focused backend interview loop and turn one answer into evidence.
</p>
<div class="user-bar">
<div id="user-info" class="user-info"></div>
<button id="logout-button" class="small-button" type="button">Sign out</button>
<button id="logout-button" class="small-button" type="button" data-i18n="signOut">
Sign out
</button>
</div>
<form id="session-form" class="stacked-form">
<label>
User ID
<input id="user-id" name="user_id" value="demo-user" autocomplete="off" />
<span data-i18n="userId">User ID</span>
<input id="user-id" name="user_id" value="" readonly autocomplete="off" />
</label>
<label>
Target role
<span data-i18n="targetRole">Target role</span>
<input id="target-role" name="target_role" value="junior backend developer" />
</label>
<label>
Stack
<span data-i18n="stack">Stack</span>
<input id="stack" name="stack" value="go, postgres" />
</label>
<label>
Timeline
<span data-i18n="timeline">Timeline</span>
<input id="timeline" name="interview_timeline" value="30 days" />
</label>
<button id="start-button" type="submit">
<span class="btn-text">Start diagnostic</span>
<span class="btn-text" data-i18n="startDiagnostic">Start diagnostic</span>
<span class="btn-spinner" aria-hidden="true"></span>
</button>
</form>
<p id="status-line" class="status-line" role="status">
<span class="status-icon" aria-hidden="true"></span>
<span class="status-text">Ready</span>
<span class="status-text" data-i18n="ready">Ready</span>
</p>
<p id="error-line" class="error-line" role="alert"></p>
</aside>
@@ -79,19 +113,26 @@
<section class="practice-pane" aria-label="Diagnostic practice">
<div class="section-heading">
<div>
<p class="eyebrow">Diagnostic</p>
<h2 id="session-title">No active session</h2>
<p class="eyebrow" data-i18n="diagnosticEyebrow">Diagnostic</p>
<h2 id="session-title" data-i18n="noActiveSession">No active session</h2>
</div>
</div>
<div id="questions" class="question-list empty-state">
<span class="empty-hint">Start a diagnostic session to load interview questions.</span>
<span class="empty-hint" data-i18n="emptyQuestions"
>Start a diagnostic session to load interview questions.</span
>
</div>
<form id="answer-form" class="answer-form">
<label for="answer-text">Answer</label>
<textarea id="answer-text" rows="7" placeholder="Select a question, then answer with concrete production reasoning."></textarea>
<label for="answer-text" data-i18n="answerLabel">Answer</label>
<textarea
id="answer-text"
rows="7"
data-i18n-placeholder="answerPlaceholder"
placeholder="Select a question, then answer with concrete production reasoning."
></textarea>
<button id="answer-button" type="submit" disabled>
<span class="btn-text">Submit answer</span>
<span class="btn-text" data-i18n="submitAnswer">Submit answer</span>
<span class="btn-spinner" aria-hidden="true"></span>
</button>
</form>
@@ -99,43 +140,47 @@
<section class="content-workspace" aria-label="Material and asset workspace">
<div class="section-heading">
<div>
<p class="eyebrow">Content operations</p>
<h2>Source to asset prompt</h2>
<p class="eyebrow" data-i18n="contentEyebrow">Content operations</p>
<h2 data-i18n="contentTitle">Source to asset prompt</h2>
</div>
</div>
<form id="material-form" class="material-form">
<label>
Material title
<span data-i18n="materialTitle">Material title</span>
<input id="material-title" value="Backend interview notes" />
</label>
<label>
Source type
<span data-i18n="sourceType">Source type</span>
<input id="material-source" value="markdown" />
</label>
<label class="wide-field">
Source material
<textarea id="material-body" rows="5">Idempotent API retries need transactions. Cache invalidation uses TTL tradeoffs and database indexes support query plans.</textarea>
<span data-i18n="sourceMaterial">Source material</span>
<textarea id="material-body" rows="5">
Idempotent API retries need transactions. Cache invalidation uses TTL tradeoffs and database indexes support query plans.</textarea
>
</label>
<button id="material-button" type="submit">
<span class="btn-text">Ingest material</span>
<span class="btn-text" data-i18n="ingestMaterial">Ingest material</span>
<span class="btn-spinner" aria-hidden="true"></span>
</button>
</form>
<div id="ontology" class="ontology-view empty-state">
<span class="empty-hint">Ingest material to inspect ontology candidates.</span>
<span class="empty-hint" data-i18n="emptyOntology"
>Ingest material to inspect ontology candidates.</span
>
</div>
<form id="asset-form" class="asset-form">
<label>
Concept
<span data-i18n="concept">Concept</span>
<select id="asset-concept" disabled>
<option value="">Select a concept</option>
<option value="" data-i18n="concept">Select a concept</option>
</select>
</label>
<label>
Asset type
<span data-i18n="assetType">Asset type</span>
<select id="asset-type">
<option value="diagram">Diagram</option>
<option value="lesson_slice">Lesson slice</option>
@@ -144,13 +189,15 @@
</select>
</label>
<button id="asset-button" type="submit" disabled>
<span class="btn-text">Generate prompt</span>
<span class="btn-text" data-i18n="generatePrompt">Generate prompt</span>
<span class="btn-spinner" aria-hidden="true"></span>
</button>
</form>
<div id="asset-output" class="ontology-view empty-state">
<span class="empty-hint">Generate a prompt to inspect model key, review state, and evidence.</span>
<span class="empty-hint" data-i18n="emptyAsset"
>Generate a prompt to inspect model key, review state, and evidence.</span
>
</div>
</section>
</section>
@@ -158,25 +205,32 @@
<aside class="feedback-pane" aria-label="Feedback">
<div class="section-heading">
<div>
<p class="eyebrow">Feedback</p>
<h2>Rubric result</h2>
<p class="eyebrow" data-i18n="feedbackEyebrow">Feedback</p>
<h2 data-i18n="rubricResult">Rubric result</h2>
</div>
</div>
<div id="feedback" class="feedback empty-state">
<span class="empty-hint">Submit an answer to see grade, evidence, and follow-up.</span>
<span class="empty-hint" data-i18n="emptyFeedback"
>Submit an answer to see grade, evidence, and follow-up.</span
>
</div>
<div class="section-heading progress-heading">
<div>
<p class="eyebrow">Progress</p>
<h2>Learning state</h2>
<p class="eyebrow" data-i18n="progressEyebrow">Progress</p>
<h2 data-i18n="learningState">Learning state</h2>
</div>
<button id="refresh-progress" class="small-button" type="button" disabled>Refresh</button>
<button id="refresh-progress" class="small-button" type="button" disabled data-i18n="refresh">
Refresh
</button>
</div>
<div id="progress" class="feedback empty-state">
<span class="empty-hint">Answer once to update learner memory and readiness.</span>
<span class="empty-hint" data-i18n="emptyProgress"
>Answer once to update learner memory and readiness.</span
>
</div>
</aside>
</main>
<script src="/assets/i18n.js"></script>
<script src="/assets/app.js" type="module"></script>
</body>
</html>