144 lines
5.0 KiB
JavaScript
144 lines
5.0 KiB
JavaScript
import { html, css, LitElement } from '../../assets/lit-core-2.7.4.min.js';
|
|
import { unifiedPageStyles } from './sharedPageStyles.js';
|
|
|
|
export class AICustomizeView extends LitElement {
|
|
static styles = [
|
|
unifiedPageStyles,
|
|
css`
|
|
.unified-page {
|
|
height: 100%;
|
|
}
|
|
.unified-wrap {
|
|
height: 100%;
|
|
}
|
|
section.surface {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
.form-grid {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
.form-group.vertical {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
textarea.control {
|
|
flex: 1;
|
|
resize: none;
|
|
overflow-y: auto;
|
|
min-height: 0;
|
|
}
|
|
`,
|
|
];
|
|
|
|
static properties = {
|
|
selectedProfile: { type: String },
|
|
onProfileChange: { type: Function },
|
|
_context: { state: true },
|
|
_providerMode: { state: true },
|
|
};
|
|
|
|
constructor() {
|
|
super();
|
|
this.selectedProfile = 'interview';
|
|
this.onProfileChange = () => {};
|
|
this._context = '';
|
|
this._providerMode = 'byok';
|
|
this._loadFromStorage();
|
|
}
|
|
|
|
async _loadFromStorage() {
|
|
try {
|
|
const prefs = await cheatingDaddy.storage.getPreferences();
|
|
this._context = prefs.customPrompt || '';
|
|
this._providerMode = prefs.providerMode || 'byok';
|
|
this.requestUpdate();
|
|
} catch (error) {
|
|
console.error('Error loading AI customize storage:', error);
|
|
}
|
|
}
|
|
|
|
_handleProfileChange(e) {
|
|
this.onProfileChange(e.target.value);
|
|
}
|
|
|
|
async _handleProviderModeChange(e) {
|
|
this._providerMode = e.target.value;
|
|
await cheatingDaddy.storage.updatePreference('providerMode', this._providerMode);
|
|
this.requestUpdate();
|
|
}
|
|
|
|
async _saveContext(val) {
|
|
this._context = val;
|
|
await cheatingDaddy.storage.updatePreference('customPrompt', val);
|
|
}
|
|
|
|
_getProfileName(profile) {
|
|
const names = {
|
|
interview: 'Job Interview',
|
|
sales: 'Sales Call',
|
|
meeting: 'Business Meeting',
|
|
presentation: 'Presentation',
|
|
negotiation: 'Negotiation',
|
|
exam: 'Exam Assistant',
|
|
};
|
|
return names[profile] || profile;
|
|
}
|
|
|
|
render() {
|
|
const profiles = [
|
|
{ value: 'interview', label: 'Job Interview' },
|
|
{ value: 'sales', label: 'Sales Call' },
|
|
{ value: 'meeting', label: 'Business Meeting' },
|
|
{ value: 'presentation', label: 'Presentation' },
|
|
{ value: 'negotiation', label: 'Negotiation' },
|
|
{ value: 'exam', label: 'Exam Assistant' },
|
|
];
|
|
|
|
return html`
|
|
<div class="unified-page">
|
|
<div class="unified-wrap">
|
|
<div>
|
|
<div class="page-title">AI Context</div>
|
|
</div>
|
|
|
|
<section class="surface">
|
|
<div class="form-grid">
|
|
<div class="form-group">
|
|
<label class="form-label">Regime</label>
|
|
<select class="control" .value=${this._providerMode} @change=${this._handleProviderModeChange}>
|
|
<option value="byok">BYOK (API Keys)</option>
|
|
<option value="local">Local AI (Ollama)</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label">Profile</label>
|
|
<select class="control" .value=${this.selectedProfile} @change=${this._handleProfileChange}>
|
|
${profiles.map(profile => html`<option value=${profile.value}>${profile.label}</option>`)}
|
|
</select>
|
|
</div>
|
|
<div class="form-group vertical">
|
|
<label class="form-label">Custom Instructions</label>
|
|
<textarea
|
|
class="control"
|
|
placeholder="Resume details, role requirements, constraints..."
|
|
.value=${this._context}
|
|
@input=${e => this._saveContext(e.target.value)}
|
|
></textarea>
|
|
<div class="form-help">Sent as context at session start. Keep it short.</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
</div>
|
|
</div>
|
|
`;
|
|
}
|
|
}
|
|
|
|
customElements.define('ai-customize-view', AICustomizeView);
|