プロジェクト

全般

プロフィール

機能 #7 » line-ai-webui-preview.html

Redmine Admin, 2025-05-10 18:32

 
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LINE風 AI WebUI</title>
<style>
/* リセットとベーススタイル */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
body {
background-color: #f9f9f9;
color: #333;
font-size: 14px;
height: 100vh;
overflow: hidden;
}
/* LINE風カラースキーム */
:root {
--line-green: #06C755;
--line-green-dark: #05b14c;
--text-primary: #333333;
--text-secondary: #8c8c8c;
--bg-default: #f9f9f9;
--bg-paper: #ffffff;
--bg-chat-user: #ffffff;
--bg-chat-ai: #f5f5f5;
--divider: #e6e6e6;
}
/* レイアウト */
.app-container {
display: flex;
height: 100vh;
}
/* サイドバー */
.sidebar {
width: 240px;
background-color: var(--bg-paper);
border-right: 1px solid var(--divider);
display: flex;
flex-direction: column;
height: 100%;
flex-shrink: 0;
}

.sidebar-header {
padding: 16px;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid var(--divider);
}
.sidebar-content {
flex-grow: 1;
overflow-y: auto;
padding: 8px;
}

.sidebar-footer {
padding: 16px;
text-align: center;
border-top: 1px solid var(--divider);
color: var(--text-secondary);
font-size: 12px;
}

/* メインコンテンツ */
.main-content {
flex-grow: 1;
display: flex;
flex-direction: column;
height: 100%;
position: relative;
}

.top-bar {
height: 48px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 16px;
background-color: var(--bg-paper);
border-bottom: 1px solid var(--divider);
}

.content-area {
flex-grow: 1;
overflow-y: auto;
padding: 16px;
display: flex;
flex-direction: column;
}

/* 右サイドバー */
.right-sidebar {
width: 340px;
background-color: var(--bg-paper);
border-left: 1px solid var(--divider);
display: flex;
flex-direction: column;
height: 100%;
flex-shrink: 0;
}

.right-sidebar-header {
height: 48px;
display: flex;
align-items: center;
justify-content: center;
border-bottom: 1px solid var(--divider);
}

.right-sidebar-content {
flex-grow: 1;
padding: 16px;
overflow-y: auto;
display: flex;
flex-direction: column;
}

/* ナビゲーションメニュー */
.nav-menu {
list-style-type: none;
}

.nav-menu-item {
display: flex;
align-items: center;
padding: 12px 16px;
border-radius: 8px;
margin: 4px 0;
cursor: pointer;
color: var(--text-primary);
font-weight: 500;
}

.nav-menu-item:hover {
background-color: rgba(6, 199, 85, 0.1);
}

.nav-menu-item.active {
background-color: var(--line-green);
color: white;
}

.nav-menu-item svg {
margin-right: 12px;
}

/* チャットUI */
.chat-container {
flex-grow: 1;
display: flex;
flex-direction: column;
height: 100%;
}

.chat-messages {
flex-grow: 1;
overflow-y: auto;
padding: 16px;
}

.message {
display: flex;
margin-bottom: 16px;
}

.message.user {
flex-direction: row-reverse;
}

.avatar {
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: white;
margin: 0 8px;
flex-shrink: 0;
}

.avatar.user {
background-color: var(--line-green);
}

.avatar.ai {
background-color: var(--text-secondary);
}

.message-bubble {
max-width: 70%;
padding: 12px 16px;
border-radius: 12px;
position: relative;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}

.user .message-bubble {
background-color: var(--bg-chat-user);
margin-right: 12px;
border: 1px solid var(--divider);
}

.ai .message-bubble {
background-color: var(--bg-chat-ai);
margin-left: 12px;
}

.message-time {
font-size: 12px;
color: var(--text-secondary);
margin-top: 4px;
text-align: right;
}

.ai .message-time {
text-align: left;
}

.chat-input {
display: flex;
align-items: center;
padding: 12px 16px;
background-color: var(--bg-paper);
border-radius: 24px;
margin: 16px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.chat-input input {
flex-grow: 1;
border: none;
outline: none;
background: transparent;
font-size: 14px;
padding: 0 12px;
}

.btn-icon {
width: 36px;
height: 36px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
background: none;
border: none;
cursor: pointer;
color: var(--text-secondary);
}

.btn-icon:hover {
background-color: rgba(0, 0, 0, 0.05);
}

.btn-icon.primary {
color: var(--line-green);
}

/* コードエディタエリア */
.code-editor {
background-color: #1e1e1e;
color: #d4d4d4;
padding: 16px;
border-radius: 8px;
font-family: 'Fira Code', monospace;
margin-bottom: 16px;
white-space: pre-wrap;
height: 60%;
overflow-y: auto;
}

/* タブ */
.tabs {
display: flex;
border-bottom: 1px solid var(--divider);
}

.tab {
padding: 12px 16px;
font-weight: 500;
cursor: pointer;
border-bottom: 2px solid transparent;
flex-grow: 1;
text-align: center;
}

.tab.active {
border-bottom-color: var(--line-green);
color: var(--line-green);
}

/* コンソール */
.console {
background-color: #1e1e1e;
color: #d4d4d4;
padding: 16px;
border-radius: 8px;
font-family: 'Fira Code', monospace;
margin-top: 16px;
height: 30%;
overflow-y: auto;
}

.console-line {
line-height: 1.5;
}

.console-command {
color: #61dafb;
}

.console-output {
color: #f1f1f1;
}

.console-error {
color: #ff6b6b;
}

.console-info {
color: #ffa726;
}

/* ユーティリティ */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 8px 16px;
border-radius: 8px;
font-weight: 500;
cursor: pointer;
border: none;
outline: none;
font-size: 14px;
transition: background-color 0.2s;
}

.btn-primary {
background-color: var(--line-green);
color: white;
}

.btn-primary:hover {
background-color: var(--line-green-dark);
}

.btn-outlined {
background-color: transparent;
border: 1px solid var(--line-green);
color: var(--line-green);
}

.btn-outlined:hover {
background-color: rgba(6, 199, 85, 0.04);
}

.icon {
height: 24px;
width: 24px;
display: inline-flex;
align-items: center;
justify-content: center;
}

.typing-indicator {
display: flex;
align-items: center;
margin-top: 8px;
}

.typing-indicator span {
width: 8px;
height: 8px;
background-color: var(--text-secondary);
border-radius: 50%;
display: inline-block;
margin-right: 4px;
animation: bounce 1.5s infinite ease-in-out;
}

.typing-indicator span:nth-child(2) {
animation-delay: 0.2s;
}

.typing-indicator span:nth-child(3) {
animation-delay: 0.4s;
}

@keyframes bounce {
0%, 80%, 100% { transform: translateY(0); }
40% { transform: translateY(-8px); }
}
</style>
</head>
<body>
<div class="app-container">
<!-- 左サイドバー -->
<aside class="sidebar">
<div class="sidebar-header">
<div style="font-weight: 600; font-size: 16px;">AI WebUI</div>
</div>
<div class="sidebar-content">
<ul class="nav-menu">
<li class="nav-menu-item active">
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
<path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z"></path>
</svg>
チャット
</li>
<li class="nav-menu-item">
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
<path d="M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"></path>
</svg>
ファイルエクスプローラー
</li>
<li class="nav-menu-item">
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
<path d="M20 4H4c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 14H4V8h16v10z"></path>
</svg>
コンソール
</li>
<li class="nav-menu-item">
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17h-2v-2h2v2zm2.07-7.75l-.9.92C13.45 12.9 13 13.5 13 15h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z"></path>
</svg>
API設定
</li>
<li class="nav-menu-item">
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
<path d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"></path>
</svg>
設定
</li>
</ul>
</div>
<div class="sidebar-footer">
© 2025 AI WebUI - v0.1.0
</div>
</aside>

<!-- メインコンテンツ -->
<main class="main-content">
<div class="top-bar">
<div style="display: flex; align-items: center;">
<button class="btn-icon">
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
<path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"></path>
</svg>
</button>
<div style="font-weight: 600; margin-left: 8px;">チャット</div>
</div>
<div style="display: flex; align-items: center;">
<button class="btn-icon">
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
<path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"></path>
</svg>
</button>
<button class="btn-icon">
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
<path d="M9 16h6v-6h4l-7-7-7 7h4v6zm-4 2h14v2H5v-2z"></path>
</svg>
</button>
<button class="btn-icon">
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 2A10 10 0 0 0 2 12c0 4.42 2.87 8.17 6.84 9.5.5.08.66-.23.66-.5v-1.69c-2.77.6-3.36-1.34-3.36-1.34-.46-1.16-1.11-1.47-1.11-1.47-.91-.62.07-.6.07-.6 1 .07 1.53 1.03 1.53 1.03.87 1.52 2.34 1.07 2.91.83.09-.65.35-1.09.63-1.34-2.22-.25-4.55-1.11-4.55-4.92 0-1.11.38-2 1.03-2.71-.1-.25-.45-1.29.1-2.64 0 0 .84-.27 2.75 1.02.79-.22 1.65-.33 2.5-.33.85 0 1.71.11 2.5.33 1.91-1.29 2.75-1.02 2.75-1.02.55 1.35.2 2.39.1 2.64.65.71 1.03 1.6 1.03 2.71 0 3.82-2.34 4.66-4.57 4.91.36.31.69.92.69 1.85V21c0 .27.16.59.67.5C19.14 20.16 22 16.42 22 12A10 10 0 0 0 12 2z"></path>
</svg>
</button>
<button class="btn-icon">
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
<path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"></path>
</svg>
</button>
</div>
</div>

<div class="content-area">
<div class="chat-container">
<div class="chat-messages">
<!-- AIメッセージ -->
<div class="message ai">
<div class="avatar ai">
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
<path d="M20 9V7c0-1.1-.9-2-2-2h-3c0-1.66-1.34-3-3-3S9 3.34 9 5H6c-1.1 0-2 .9-2 2v2c-1.66 0-3 1.34-3 3s1.34 3 3 3v4c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2v-4c1.66 0 3-1.34 3-3s-1.34-3-3-3zm-2 10H6V7h12v12zm-9-6c-.83 0-1.5-.67-1.5-1.5S8.17 10 9 10s1.5.67 1.5 1.5S9.83 13 9 13zm7.5-1.5c0 .83-.67 1.5-1.5 1.5s-1.5-.67-1.5-1.5.67-1.5 1.5-1.5 1.5.67 1.5 1.5zM8 15h8v2H8v-2z"></path>
</svg>
</div>
<div class="message-bubble">
<div>こんにちは!AIアシスタントです。何かお手伝いできることはありますか?</div>
<div class="message-time">14:30</div>
</div>
</div>

<!-- ユーザーメッセージ -->
<div class="message user">
<div class="avatar user">
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"></path>
</svg>
</div>
<div class="message-bubble">
<div>このアプリではどのような機能が使えますか?</div>
<div class="message-time">14:31</div>
</div>
</div>

<!-- AIメッセージ -->
<div class="message ai">
<div class="avatar ai">
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
<path d="M20 9V7c0-1.1-.9-2-2-2h-3c0-1.66-1.34-3-3-3S9 3.34 9 5H6c-1.1 0-2 .9-2 2v2c-1.66 0-3 1.34-3 3s1.34 3 3 3v4c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2v-4c1.66 0 3-1.34 3-3s-1.34-3-3-3zm-2 10H6V7h12v12zm-9-6c-.83 0-1.5-.67-1.5-1.5S8.17 10 9 10s1.5.67 1.5 1.5S9.83 13 9 13zm7.5-1.5c0 .83-.67 1.5-1.5 1.5s-1.5-.67-1.5-1.5.67-1.5 1.5-1.5 1.5.67 1.5 1.5zM8 15h8v2H8v-2z"></path>
</svg>
</div>
<div class="message-bubble">
<div>
このアプリでは以下の機能が利用できます:<br><br>
1. AIとのチャット機能<br>
2. ファイルエクスプローラー(ローカルファイル操作)<br>
3. SSH/FTPによるリモートサーバー接続<br>
4. コードエディタとプレビュー<br>
5. コンソールコマンド実行<br>
6. API設定管理(OpenAI、Anthropicなど)<br><br>
右側のサイドバーにはコードエディタやコンソール出力が表示されます。何か特定の機能について詳しく知りたいことはありますか?
</div>
<div class="message-time">14:32</div>
</div>
</div>

<!-- ユーザーメッセージ -->
<div class="message user">
<div class="avatar user">
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"></path>
</svg>
</div>
<div class="message-bubble">
<div>SSH接続してみたいです。シンプルなNode.jsアプリのコード例を教えてください。</div>
<div class="message-time">14:33</div>
</div>
</div>

<!-- AI応答中... -->
<div class="message ai">
<div class="avatar ai">
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
<path d="M20 9V7c0-1.1-.9-2-2-2h-3c0-1.66-1.34-3-3-3S9 3.34 9 5H6c-1.1 0-2 .9-2 2v2c-1.66 0-3 1.34-3 3s1.34 3 3 3v4c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2v-4c1.66 0 3-1.34 3-3s-1.34-3-3-3zm-2 10H6V7h12v12zm-9-6c-.83 0-1.5-.67-1.5-1.5S8.17 10 9 10s1.5.67 1.5 1.5S9.83 13 9 13zm7.5-1.5c0 .83-.67 1.5-1.5 1.5s-1.5-.67-1.5-1.5.67-1.5 1.5-1.5 1.5.67 1.5 1.5zM8 15h8v2H8v-2z"></path>
</svg>
</div>
<div class="typing-indicator">
<span></span>
<span></span>
<span></span>
</div>
</div>
</div>
<div class="chat-input">
<button class="btn-icon">
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
<path d="M16.5 6v11.5c0 2.21-1.79 4-4 4s-4-1.79-4-4V5c0-1.38 1.12-2.5 2.5-2.5s2.5 1.12 2.5 2.5v10.5c0 .55-.45 1-1 1s-1-.45-1-1V6H10v9.5c0 1.38 1.12 2.5 2.5 2.5s2.5-1.12 2.5-2.5V5c0-2.21-1.79-4-4-4S7 2.79 7 5v12.5c0 3.04 2.46 5.5 5.5 5.5s5.5-2.46 5.5-5.5V6h-1.5z"></path>
</svg>
</button>
<input type="text" placeholder="メッセージを入力..." />
<button class="btn-icon primary">
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
<path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"></path>
</svg>
</button>
</div>
</div>
</div>
</main>

<!-- 右サイドバー -->
<aside class="right-sidebar">
<div class="tabs">
<div class="tab active">コード</div>
<div class="tab">コンソール</div>
<div class="tab">プレビュー</div>
</div>
<div class="right-sidebar-content">
<div class="code-editor">
<span style="color: #569cd6;">const</span> { <span style="color: #9cdcfe;">NodeSSH</span> } = <span style="color: #569cd6;">require</span>(<span style="color: #ce9178;">'node-ssh'</span>);
<span style="color: #569cd6;">const</span> <span style="color: #9cdcfe;">ssh</span> = <span style="color: #569cd6;">new</span> <span style="color: #4ec9b0;">NodeSSH</span>();

<span style="color: #6a9955;">// SSHサーバーに接続</span>
<span style="color: #569cd6;">async</span> <span style="color: #569cd6;">function</span> <span style="color: #dcdcaa;">connectToServer</span>() {
<span style="color: #c586c0;">try</span> {
<span style="color: #c586c0;">await</span> ssh.<span style="color: #dcdcaa;">connect</span>({
<span style="color: #9cdcfe;">host</span>: <span style="color: #ce9178;">'example.com'</span>,
<span style="color: #9cdcfe;">username</span>: <span style="color: #ce9178;">'username'</span>,
<span style="color: #9cdcfe;">password</span>: <span style="color: #ce9178;">'password'</span>,
<span style="color: #9cdcfe;">port</span>: <span style="color: #b5cea8;">22</span>,
});
console.<span style="color: #dcdcaa;">log</span>(<span style="color: #ce9178;">'SSH接続に成功しました'</span>);
<span style="color: #6a9955;">// コマンド実行</span>
<span style="color: #569cd6;">const</span> <span style="color: #9cdcfe;">result</span> = <span style="color: #c586c0;">await</span> ssh.<span style="color: #dcdcaa;">execCommand</span>(<span style="color: #ce9178;">'ls -la'</span>);
console.<span style="color: #dcdcaa;">log</span>(<span style="color: #ce9178;">'STDOUT: '</span> + result.stdout);
console.<span style="color: #dcdcaa;">log</span>(<span style="color: #ce9178;">'STDERR: '</span> + result.stderr);
<span style="color: #6a9955;">// 接続を閉じる</span>
ssh.<span style="color: #dcdcaa;">dispose</span>();
} <span style="color: #c586c0;">catch</span> (error) {
console.<span style="color: #dcdcaa;">error</span>(<span style="color: #ce9178;">'SSH接続エラー:'</span>, error);
}
}

<span style="color: #dcdcaa;">connectToServer</span>();
</div>

<div class="console">
<div class="console-line console-info">$ node ssh-example.js</div>
<div class="console-line console-output">SSH接続中...</div>
<div class="console-line console-output">SSH接続に成功しました</div>
<div class="console-line console-output">STDOUT: total 120</div>
<div class="console-line console-output">drwxr-xr-x 12 user staff 384 May 10 14:30 .</div>
<div class="console-line console-output">drwxr-xr-x 5 user staff 160 May 9 09:15 ..</div>
<div class="console-line console-output">-rw-r--r-- 1 user staff 386 May 10 14:28 package.json</div>
<div class="console-line console-output">-rw-r--r-- 1 user staff 4.2K May 10 13:45 server.js</div>
<div class="console-line console-output">drwxr-xr-x 11 user staff 352 May 10 12:30 node_modules</div>
<div class="console-line console-output">-rw-r--r-- 1 user staff 1.8K May 10 11:22 README.md</div>
<div class="console-line console-output">STDERR: </div>
<div class="console-line console-output">SSH接続を切断しました</div>
</div>
</div>
</aside>
</div>
</body>
</html>
(2-2/4)