見出し画像

ChatGPT o1 miniで作る!プロンプトを簡単に管理できるシングルページWebアプリケーション【プロンプト+アプリのHTMLファイル+コード付】


はじめに

日常的に使うプロンプト(指示文)を簡単に管理・再利用できる便利なWebアプリケーションをo1-miniで作成します。
登録するプロンプトは、ブラウザのメモリに記憶されます。

o1-miniを使えば、コードを書かなくても、簡単なプロンプトで実用的なWebブラウザアプリケーション(サーバーは不要。PCだけで動きます)を一瞬で作ることができます。

このアプリを作るために使用したプロンプトは以下です。

役割: あなたはシングルページ Web アプリケーション開発の専⾨家です。
指⽰: よく使うプロンプトを記憶し、呼び出せる機能を持つ、便利なシングルペー ジ Web アプリケーションのコードを出⼒してください。
条件:
• フロントエンドのみで動作する Web アプリケーションにし てください。サーバーサイドの機能は使⽤しません
• スタイリッシュでモダンなデザインにしてください
• htmlには、使⽤⽅法と注意事項を記載してください
• 出⼒内容: htmlコードの中にCSS,JavaScriptコードを含めて ください
• 出⼒形式: コードブロックに出⼒してください

プログラミング初心者の方でも簡単に使えるように設計されたこのアプリケーションは、特別な設定やサーバーの知識がなくても、ブラウザだけで完璧に動作します。それでは、さっそくその魅力と使い方について詳しく見ていきましょう!

🌟 アプリケーションの特徴

  1. フロントエンドのみで動作

    • このアプリケーションは、インターネットブラウザ上で完結します。サーバーサイドの設定やバックエンドの知識は一切不要です。HTML、CSS、JavaScriptだけで動作するため、すぐに使い始めることができます。💻

  2. スタイリッシュでモダンなデザイン

    • 見た目も美しく、使いやすさを追求したデザインです。シンプルながらも洗練されたインターフェースで、直感的に操作できます。🎨✨

  3. プロンプトの登録・管理・再利用が簡単

    • よく使うプロンプトを簡単に登録し、一覧で管理できます。登録したプロンプトはクリック一つでクリップボードにコピーできるため、効率的に作業が進められます。📋🔗

  4. 編集機能付き

    • 一度登録したプロンプトも、いつでも編集が可能です。変更が必要な場合も簡単に対応できるので、柔軟にプロンプトを管理できます。✏️🔄

  5. エクスポートとインポート機能

    • 新たに追加されたエクスポート機能により、登録済みのプロンプトをJSONファイルとしてダウンロードできます。これを使えば、他のデバイスやブラウザに簡単にプロンプトを移行することが可能です。また、インポート機能を使えば、保存しておいたJSONファイルからプロンプトを復元したり、既存のプロンプトに追加したりできます。📤📥

  6. センタリングされたヘッダー

    • タイトルとエクスポート・インポートボタンが中央にバランス良く配置され、見た目がさらに洗練されました。これにより、ユーザーインターフェースがより整然とし、使いやすさが向上しています。⚖️✨

  7. ローカルストレージに保存

    • 登録したプロンプトはブラウザのローカルストレージに保存されます。他のデバイスやブラウザとは共有されませんが、エクスポートとインポート機能を使用して簡単に移行できます。🔒📁

🔧 使い方ガイド

1. プロンプトを登録する

アプリケーションを開くと、まずプロンプトを入力するフォームが表示されます。ここによく使うプロンプトを入力し、「登録」ボタンをクリックします。📝✨

2. 登録済みプロンプトの確認

登録されたプロンプトは、下部の「登録済みプロンプト」セクションに一覧表示されます。各プロンプトには「コピー」ボタンと「編集」ボタンが付いています。📂🔍

3. プロンプトをコピーする

必要なプロンプトをすぐに使用したいときは、「コピー」ボタンをクリック。クリップボードにプロンプトがコピーされるので、他のアプリケーションやドキュメントに貼り付けて使用できます。📋📌

4. プロンプトを編集する

登録済みのプロンプトに修正が必要な場合は、「編集」ボタンをクリック。ポップアップウィンドウが表示され、プロンプトを修正した後に「保存」ボタンを押すだけで変更が反映されます。✏️🔄

5. プロンプトをエクスポートする

ヘッダー部分の「エクスポート」ボタンをクリックします。現在登録されているプロンプトが prompts.json という名前のファイルとして自動的にダウンロードされます。このファイルは安全な場所に保存しておきましょう。💾📤

6. プロンプトをインポートする

ヘッダー部分の「インポート」ボタンをクリックします。表示されたモーダルウィンドウで「JSONファイルを選択」ボタンをクリックし、先ほどエクスポートした prompts.json ファイルを選択します。インポートモードとして「既存のプロンプトに追加」または「既存のプロンプトを置き換える」を選択し、「インポート」ボタンをクリックすると、プロンプトが追加または置き換えられます。📥🔄

💡 注意事項

  • データの保存場所

    • このアプリケーションはローカルストレージを使用してプロンプトを保存します。つまり、保存されたデータは現在使用しているブラウザとデバイスにのみ存在します。他のデバイスやブラウザでは共有されないため、必要に応じてエクスポート機能を使用してバックアップを取ることをおすすめします。🔒📁

  • エクスポートとインポートの活用

    • プロンプトを複数のデバイス間で共有したい場合や、データのバックアップを取りたい場合は、エクスポートとインポート機能を活用してください。エクスポートしたJSONファイルを安全な場所に保存しておけば、いつでもプロンプトを復元できます。📤📥

  • インターネット接続

    • フロントエンドのみで動作するため、基本的にはインターネット接続は不要です。ただし、アプリケーションを初めて読み込む際にはインターネット接続が必要です。🌐📶

デモ環境

こちらで試していただけます。当社サーバにアップロードしたアプリです。

🚀 まとめ

プログラミング初心者の方でも簡単に使えるこのプロンプトマネージャーは、日常の作業を効率化する強力なツールです。シンプルな操作性とモダンなデザインに加え、エクスポートとインポート機能が追加されたことで、プロンプトの管理がさらに便利になりました。
ぜひ一度試してみて、作業の効率化を実感してみてください!✨

もしご質問やフィードバックがありましたら、コメント欄にお気軽にお寄せください。それでは、素晴らしいプロンプトライフをお楽しみください!😊👍


📌 プロンプトマネージャーのダウンロード

コード

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>プロンプトマネージャー</title>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background-color: #f4f6f8;
            margin: 0;
            padding: 0;
            display: flex;
            flex-direction: column;
            align-items: center;
            min-height: 100vh;
        }

        header {
            background-color: #4A90E2;
            color: white;
            width: 100%;
            padding: 20px 40px;
            display: flex;
            justify-content: center; /* 中央揃えに変更 */
            align-items: center;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }

        header h1 {
            margin: 0;
            font-size: 24px;
            margin-right: 20px; /* タイトルとボタンの間にスペースを追加 */
            text-align: center;
        }

        .export-import {
            display: flex;
            gap: 10px;
        }

        .export-import button {
            padding: 8px 12px;
            background-color: #17a2b8;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
            transition: background-color 0.3s;
        }

        .export-import button:hover {
            background-color: #117a8b;
        }

        main {
            width: 90%;
            max-width: 800px;
            margin: 30px 0;
            background-color: white;
            padding: 20px 30px;
            border-radius: 8px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
        }

        h2 {
            margin-top: 0;
            color: #333;
        }

        .instructions {
            background-color: #eef;
            padding: 15px;
            border-radius: 5px;
            margin-bottom: 20px;
            font-size: 14px;
            color: #555;
        }

        form {
            display: flex;
            flex-direction: column;
            gap: 10px;
            margin-bottom: 30px;
        }

        textarea {
            resize: vertical;
            min-height: 80px;
            padding: 10px;
            border: 1px solid #ccc;
            border-radius: 4px;
            font-size: 14px;
            font-family: inherit;
        }

        button.submit-btn {
            padding: 10px 15px;
            background-color: #4A90E2;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
            transition: background-color 0.3s;
        }

        button.submit-btn:hover {
            background-color: #357ABD;
        }

        .prompt-list {
            list-style: none;
            padding: 0;
            margin: 0;
        }

        .prompt-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            background-color: #fafafa;
            padding: 15px;
            border: 1px solid #e0e0e0;
            border-radius: 5px;
            margin-bottom: 10px;
            transition: background-color 0.3s;
        }

        .prompt-item:hover {
            background-color: #f0f8ff;
        }

        .prompt-text {
            flex: 1;
            margin-right: 15px;
            white-space: pre-wrap;
            word-break: break-word;
        }

        .prompt-actions button {
            margin-left: 10px;
            background-color: #6c757d;
            padding: 6px 10px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 12px;
            color: white;
            transition: background-color 0.3s;
        }

        .prompt-actions button.copy-btn {
            background-color: #28a745;
        }

        .prompt-actions button.edit-btn {
            background-color: #ffc107;
        }

        .prompt-actions button:hover.copy-btn {
            background-color: #218838;
        }

        .prompt-actions button:hover.edit-btn {
            background-color: #e0a800;
        }

        /* Modal Styles */
        .modal {
            display: none; 
            position: fixed; 
            z-index: 1000; 
            left: 0;
            top: 0;
            width: 100%; 
            height: 100%; 
            overflow: auto; 
            background-color: rgba(0,0,0,0.5); 
        }

        .modal-content {
            background-color: #fff;
            margin: 10% auto; 
            padding: 20px;
            border: 1px solid #888;
            width: 80%; 
            max-width: 500px;
            border-radius: 8px;
            position: relative;
        }

        .close {
            color: #aaa;
            position: absolute;
            top: 10px;
            right: 20px;
            font-size: 28px;
            font-weight: bold;
            cursor: pointer;
        }

        .close:hover,
        .close:focus {
            color: black;
        }

        /* Import Modal Specific Styles */
        .import-section {
            display: flex;
            flex-direction: column;
            gap: 10px;
        }

        .import-section input {
            padding: 8px;
            border: 1px solid #ccc;
            border-radius: 4px;
        }

        .import-section label {
            font-weight: bold;
        }
    </style>
</head>
<body>
    <header>
        <h1>プロンプトマネージャー</h1>
        <div class="export-import">
            <button id="export-btn">エクスポート</button>
            <button id="import-btn">インポート</button>
        </div>
    </header>
    <main>
        <div class="instructions">
            <h2>使い方</h2>
            <p>下記のフォームによく使用するプロンプトを入力し、「登録」ボタンをクリックしてください。登録されたプロンプトは一覧に表示され、各プロンプトの「コピー」ボタンでクリップボードにコピーできます。また、「編集」ボタンでプロンプトを編集することも可能です。</p>
            <p><strong>注意事項:</strong> このアプリケーションはフロントエンドのみで動作し、プロンプトはブラウザのローカルストレージに保存されます。データは他のデバイスやブラウザとは共有されませんが、エクスポートとインポート機能を使用して簡単に移行できます。</p>
        </div>

        <form id="prompt-form">
            <textarea id="prompt-input" placeholder="ここにプロンプトを入力してください..." required></textarea>
            <button type="submit" class="submit-btn">登録</button>
        </form>

        <h2>登録済みプロンプト</h2>
        <ul class="prompt-list" id="prompt-list">
            <!-- プロンプトがここに表示されます -->
        </ul>
    </main>

    <!-- Edit Modal -->
    <div id="edit-modal" class="modal">
        <div class="modal-content">
            <span class="close">&times;</span>
            <h2>プロンプトを編集</h2>
            <form id="edit-form">
                <textarea id="edit-input" required></textarea>
                <button type="submit">保存</button>
            </form>
        </div>
    </div>

    <!-- Import Modal -->
    <div id="import-modal" class="modal">
        <div class="modal-content">
            <span class="close">&times;</span>
            <h2>プロンプトをインポート</h2>
            <form id="import-form">
                <div class="import-section">
                    <label for="import-file">JSONファイルを選択:</label>
                    <input type="file" id="import-file" accept="application/json" required>
                </div>
                <div class="import-section">
                    <label for="import-mode">インポートモード:</label>
                    <select id="import-mode">
                        <option value="merge">既存のプロンプトに追加</option>
                        <option value="replace">既存のプロンプトを置き換える</option>
                    </select>
                </div>
                <button type="submit">インポート</button>
            </form>
        </div>
    </div>

    <script>
        const promptForm = document.getElementById('prompt-form');
        const promptInput = document.getElementById('prompt-input');
        const promptList = document.getElementById('prompt-list');

        const editModal = document.getElementById('edit-modal');
        const closeEditModal = editModal.querySelector('.close');
        const editForm = document.getElementById('edit-form');
        const editInput = document.getElementById('edit-input');

        const importModal = document.getElementById('import-modal');
        const closeImportModal = importModal.querySelector('.close');
        const importForm = document.getElementById('import-form');
        const importFileInput = document.getElementById('import-file');
        const importModeSelect = document.getElementById('import-mode');

        const exportBtn = document.getElementById('export-btn');
        const importBtn = document.getElementById('import-btn');

        let prompts = [];
        let editIndex = null;

        // ローカルストレージからプロンプトを読み込む
        function loadPrompts() {
            const storedPrompts = localStorage.getItem('prompts');
            if (storedPrompts) {
                try {
                    prompts = JSON.parse(storedPrompts);
                    if (!Array.isArray(prompts)) {
                        prompts = [];
                    }
                } catch (e) {
                    console.error('プロンプトの読み込み中にエラーが発生しました:', e);
                    prompts = [];
                }
            }
            renderPrompts();
        }

        // プロンプトをローカルストレージに保存
        function savePrompts() {
            localStorage.setItem('prompts', JSON.stringify(prompts));
        }

        // プロンプトのリストをレンダリング
        function renderPrompts() {
            promptList.innerHTML = '';
            prompts.forEach((prompt, index) => {
                const li = document.createElement('li');
                li.className = 'prompt-item';

                const span = document.createElement('span');
                span.className = 'prompt-text';
                span.textContent = prompt;

                const actions = document.createElement('div');
                actions.className = 'prompt-actions';

                const copyBtn = document.createElement('button');
                copyBtn.textContent = 'コピー';
                copyBtn.className = 'copy-btn';
                copyBtn.addEventListener('click', () => copyPrompt(index));

                const editBtn = document.createElement('button');
                editBtn.textContent = '編集';
                editBtn.className = 'edit-btn';
                editBtn.addEventListener('click', () => openEditModal(index));

                actions.appendChild(copyBtn);
                actions.appendChild(editBtn);

                li.appendChild(span);
                li.appendChild(actions);

                promptList.appendChild(li);
            });
        }

        // プロンプトをコピー
        function copyPrompt(index) {
            const prompt = prompts[index];
            navigator.clipboard.writeText(prompt).then(() => {
                alert('プロンプトがコピーされました!');
            }).catch(err => {
                alert('コピーに失敗しました: ' + err);
            });
        }

        // プロンプトを追加
        promptForm.addEventListener('submit', (e) => {
            e.preventDefault();
            const newPrompt = promptInput.value.trim();
            if (newPrompt) {
                prompts.push(newPrompt);
                savePrompts();
                renderPrompts();
                promptInput.value = '';
            }
        });

        // 編集モーダルを開く
        function openEditModal(index) {
            editIndex = index;
            editInput.value = prompts[index];
            editModal.style.display = 'block';
        }

        // 編集モーダルを閉じる
        closeEditModal.onclick = function() {
            editModal.style.display = 'none';
            editIndex = null;
        }

        window.onclick = function(event) {
            if (event.target == editModal) {
                editModal.style.display = 'none';
                editIndex = null;
            }
            if (event.target == importModal) {
                importModal.style.display = 'none';
            }
        }

        // プロンプトを編集
        editForm.addEventListener('submit', (e) => {
            e.preventDefault();
            const updatedPrompt = editInput.value.trim();
            if (updatedPrompt && editIndex !== null) {
                prompts[editIndex] = updatedPrompt;
                savePrompts();
                renderPrompts();
                editModal.style.display = 'none';
                editIndex = null;
            }
        });

        // エクスポート機能
        exportBtn.addEventListener('click', () => {
            if (prompts.length === 0) {
                alert('エクスポートするプロンプトがありません。');
                return;
            }
            const dataStr = JSON.stringify(prompts, null, 2);
            const blob = new Blob([dataStr], { type: "application/json" });
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = 'prompts.json';
            a.click();
            URL.revokeObjectURL(url);
        });

        // インポートモーダルを開く
        importBtn.addEventListener('click', () => {
            importModal.style.display = 'block';
        });

        // インポートモーダルを閉じる
        closeImportModal.onclick = function() {
            importModal.style.display = 'none';
        }

        // インポート機能
        importForm.addEventListener('submit', (e) => {
            e.preventDefault();
            const file = importFileInput.files[0];
            if (!file) {
                alert('インポートするファイルを選択してください。');
                return;
            }

            const reader = new FileReader();
            reader.onload = function(event) {
                try {
                    const importedPrompts = JSON.parse(event.target.result);
                    if (!Array.isArray(importedPrompts)) {
                        throw new Error('インポートされたファイルは有効なプロンプトの配列ではありません。');
                    }

                    const importMode = importModeSelect.value;
                    if (importMode === 'replace') {
                        prompts = importedPrompts;
                    } else if (importMode === 'merge') {
                        prompts = prompts.concat(importedPrompts.filter(p => !prompts.includes(p)));
                    }

                    savePrompts();
                    renderPrompts();
                    alert('プロンプトのインポートが完了しました。');
                    importModal.style.display = 'none';
                    importForm.reset();
                } catch (error) {
                    console.error('インポート中にエラーが発生しました:', error);
                    alert('インポートに失敗しました: ' + error.message);
                }
            };
            reader.onerror = function() {
                alert('ファイルの読み込み中にエラーが発生しました。');
            };
            reader.readAsText(file);
        });

        // 初期ロード
        loadPrompts();
    </script>
</body>
</html>

この記事が役に立ったと思ったら、ぜひシェアをお願いします!👍
ChatGPTでWebアプリとGPTsを思い通りに作れるようになれば、事務作業の半分ぐらいを軽減できると思います!

ChatGPTでAIアプリを作って仕事で使いたい方と世界に公開したい方へ

いいなと思ったら応援しよう!