<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Prompt Organizer</title>

    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">

    <style>

        body {

            font-family: 'Inter', sans-serif;

            background-color: #f9f9f9;

            color: #333;

            margin: 0;

            padding: 0;

            display: flex;

            flex-direction: column;

            align-items: center;

            min-height: 100vh;

            box-sizing: border-box;

            padding-bottom: 70px; /* Space for fixed footer */

            position: relative; /* Needed for absolute positioning of footer */

        }

        #app-title {

            color: #4CAF50;

            margin-top: 2rem;

            margin-bottom: 2rem;

            text-align: center;

        }


        #prompt-list-container {

            width: 95%;

            max-width: 1200px;

            margin-bottom: 80px; /* Margin to prevent overlap with footer */

        }


        #prompt-list {

            display: grid;

            grid-template-columns: 1fr;

            gap: 1.5rem;

            margin-top: 1rem;

        }


        .prompt-card {

            background-color: #fff;

            padding: 1.5rem;

            border-radius: 0.5rem;

            box-shadow: 0 2px 5px rgba(0,0,0,0.1);

            transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out;

            display: flex;

            flex-direction: column;

            justify-content: space-between;

            height: 100%;

        }


        .prompt-card:hover {

            transform: translateY(-0.5rem);

            box-shadow: 0 4px 10px rgba(0,0,0,0.1);

        }


        .prompt-header {

            display: flex;

            justify-content: space-between;

            align-items: flex-start;

            margin-bottom: 1rem;

        }

        .prompt-header h3{

          margin: 0;

          color: #2c3e50;

        }


        .prompt-tags {

            display: flex;

            flex-wrap: wrap;

            gap: 0.5rem;

            margin-bottom: 1rem;

        }


        .prompt-tag {

            background-color: #e0e0e0;

            padding: 0.25rem 0.5rem;

            border-radius: 1rem;

            font-size: 0.8rem;

            color: #555;

        }

        .prompt-tag:hover {

            background-color: #d0d0d0;

        }


        .prompt-description {

            margin-bottom: 1rem;

            color: #444;

            line-height: 1.5;

        }


        .prompt-actions {

            display: flex;

            gap: 0.5rem;

            align-items: center; /* Vertically align items */

        }


        .edit-btn, .delete-btn {

            padding: 0.5rem 1rem;

            border-radius: 0.3rem;

            cursor: pointer;

            transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out;

            font-family: 'Inter', sans-serif;

            font-size: 0.9rem;

            display: flex; /* Use flexbox for icon alignment */

            align-items: center; /* Vertically center icon and text */

            gap: 0.5rem; /* Space between icon and text */

        }


        .edit-btn {

            background-color: #4CAF50;

            color: white;

        }


        .edit-btn:hover {

            background-color: #45a049;

        }


        .delete-btn {

            background-color: #f44336;

            color: white;

        }


        .delete-btn:hover {

            background-color: #d32f2f;

        }


        #add-prompt-btn {

            position: fixed; /* Fix button to bottom right */

            bottom: 1rem;

            right: 1rem;

            padding: 0.75rem 1.5rem;

            background-color: #007BFF;

            color: white;

            border: none;

            border-radius: 0.3rem;

            font-size: 1rem;

            cursor: pointer;

            transition: background-color 0.2s ease-in-out;

            font-family: 'Inter', sans-serif;

            display: flex; /* Use flexbox for icon alignment */

            align-items: center; /* Vertically center icon and text */

            gap: 0.5rem; /* Space between icon and text */

            box-shadow: 0 2px 5px rgba(0,0,0,0.1);

        }


        #add-prompt-btn:hover {

            background-color: #0056b3;

        }


        .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);

            justify-content: center;

            align-items: center;

        }


        .modal-content {

            background-color: #fff;

            padding: 2rem;

            border-radius: 0.5rem;

            width: 95%;

            max-width: 600px;

            position: relative;

            box-shadow: 0 4px 10px rgba(0,0,0,0.2);

        }


        .modal-header {

            display: flex;

            justify-content: space-between;

            align-items: center;

            margin-bottom: 1.5rem;

            border-bottom: 1px solid #ddd;

            padding-bottom: 1rem;

        }


        .modal-header h2 {

            margin: 0;

            color: #2c3e50;

        }


        .close-modal-btn {

            position: absolute;

            top: 1rem;

            right: 1rem;

            font-size: 1.5rem;

            cursor: pointer;

            color: #888;

            transition: color 0.2s ease-in-out;

            border: none;

            background: none;

            padding: 0;

        }


        .close-modal-btn:hover {

            color: #333;

        }



        .form-group {

            margin-bottom: 1.5rem;

        }


        .form-group label {

            display: block;

            margin-bottom: 0.5rem;

            color: #555;

            font-weight: 500;

            font-size: 0.9rem;

        }


        .form-group input, .form-group textarea {

            width: 100%;

            padding: 0.75rem;

            border: 1px solid #ddd;

            border-radius: 0.3rem;

            font-size: 1rem;

            font-family: 'Inter', sans-serif;

            transition: border-color 0.2s ease-in-out;

        }


        .form-group input:focus, .form-group textarea:focus {

            outline: none;

            border-color: #4CAF50;

        }


        .form-group textarea {

            resize: vertical;

            height: 100px;

        }


        #modal-save-btn {

            padding: 0.75rem 1.5rem;

            background-color: #4CAF50;

            color: white;

            border: none;

            border-radius: 0.3rem;

            font-size: 1rem;

            cursor: pointer;

            transition: background-color 0.2s ease-in-out;

            font-family: 'Inter', sans-serif;

            display: block;

            margin-left: auto;

            margin-top: 1rem;

        }


        #modal-save-btn:hover {

            background-color: #45a049;

        }


        #filter-controls {

            display: flex;

            flex-wrap: wrap;

            gap: 1rem;

            margin-bottom: 2rem;

            justify-content: space-between; /* Distribute items evenly */

            align-items: center; /* Vertically align items */

        }


        #filter-controls .input-group {

            display: flex;

            flex-direction: column;

            min-width: 200px; /* Ensure a minimum width for each group */

        }


        #filter-controls .input-group label {

            margin-bottom: 0.25rem;

            color: #555;

            font-weight: 500;

            font-size: 0.9rem;

        }


        #filter-controls .input-group input,

        #filter-controls .input-group select {

            padding: 0.75rem;

            border: 1px solid #ddd;

            border-radius: 0.3rem;

            font-size: 1rem;

            font-family: 'Inter', sans-serif;

            transition: border-color 0.2s ease-in-out;

            width: 100%; /* Make input and select fill their container */

            box-sizing: border-box; /* Include padding and border in element's total width and height */

        }


        #filter-controls .input-group input:focus,

        #filter-controls .input-group select:focus {

            outline: none;

            border-color: #4CAF50;

        }


        #no-prompts-message {

            text-align: center;

            color: #777;

            margin-top: 2rem;

            font-size: 1.2rem;

        }

        .icon {

            width: 1rem; /* Icon size */

            height: 1rem;

        }


        /* Styles for icons - using simple shapes, you can replace with actual SVG if desired */

        .add-icon {

            /* Plus sign */

            display: inline-block;

            width: 1rem;

            height: 1rem;

            border: 2px solid white;

            border-radius: 50%;

            position: relative;

        }

        .add-icon::before {

            content: '';

            position: absolute;

            top: 50%;

            left: 50%;

            width: 60%;

            height: 20%;

            background-color: white;

            transform: translate(-50%, -50%);

        }

        .add-icon::after {

            content: '';

            position: absolute;

            top: 50%;

            left: 50%;

            width: 20%;

            height: 60%;

            background-color: white;

            transform: translate(-50%, -50%);

        }


        .edit-icon {

              /* Pencil Icon */

            display: inline-block;

            width: 1rem;

            height: 1rem;

            position: relative;

        }


        .edit-icon::before {

            content: '';

            position: absolute;

            left: 25%;

            top: 10%;

            width: 60%;

            height: 8%;

            background-color: white;

            border-radius: 0.2rem;

            transform: rotate(45deg);

        }

        .edit-icon::after{

            content: '';

            position: absolute;

            left: 15%;

            top: 30%;

            width: 8%;

            height: 60%;

            background-color: white;

            border-radius: 0.2rem;


        }

         .delete-icon {

            /* Trash Can Icon */

            display: inline-block;

            width: 1rem;

            height: 1rem;

            position: relative;

        }


        .delete-icon::before {

            content: '';

            position: absolute;

            bottom: 20%;

            left: 20%;

            width: 60%;

            height: 10%;

            background-color: white;

            border-radius: 0.2rem;

        }

        .delete-icon::after{

            content: '';

            position: absolute;

            top: 20%;

            left: 40%;

            width: 20%;

            height: 70%;

            background-color: white;

            border-top-left-radius: 0.3rem;

            border-top-right-radius: 0.3rem;


        }

        .delete-icon_top{

            content: '';

            position: absolute;

            top: 10%;

            left: 30%;

            width: 40%;

            height: 10%;

            background-color: white;

            border-radius: 0.3rem;

        }

    </style>

</head>

<body>

    <h1 id="app-title">Prompt Organizer</h1>


    <div id="filter-controls">

        <div class="input-group">

            <label for="search-input">Search Prompts</label>

            <input type="text" id="search-input" placeholder="Enter keywords...">

        </div>

        <div class="input-group">

            <label for="tag-filter">Filter by Tag</label>

            <select id="tag-filter">

                <option value="">All Tags</option>

            </select>

        </div>

        <div class="input-group">

            <label for="sort-select">Sort by</label>

            <select id="sort-select">

                <option value="created-asc">Date Created (Asc)</option>

                <option value="created-desc">Date Created (Desc)</option>

                <option value="modified-asc">Date Modified (Asc)</option>

                <option value="modified-desc">Date Modified (Desc)</option>

            </select>

        </div>

    </div>


    <div id="prompt-list-container">

        <div id="prompt-list">

            </div>

        <p id="no-prompts-message" style="display:none;">No prompts found.</p>

    </div>


    <button id="add-prompt-btn">

        <span class="add-icon"></span>

        Add Prompt

    </button>


    <div id="prompt-modal" class="modal">

        <div class="modal-content">

            <div class="modal-header">

                <h2>Edit Prompt</h2>

                <button id="close-modal-btn" class="close-modal-btn">&times;</button>

            </div>

            <form id="edit-prompt-form">

                <div class="form-group">

                    <label for="prompt-title">Title</label>

                    <input type="text" id="prompt-title" placeholder="Enter prompt title" required>

                </div>

                <div class="form-group">

                    <label for="prompt-description">Description</label>

                    <textarea id="prompt-description" placeholder="Enter prompt description"></textarea>

                </div>

                <div class="form-group">

                    <label for="prompt-tags">Tags (comma-separated)</label>

                    <input type="text" id="prompt-tags" placeholder="Enter tags, separated by commas">

                </div>

                <div class="form-group">

                    <label for="prompt-text">Prompt</label>

                    <textarea id="prompt-text" placeholder="Enter your prompt here" required></textarea>

                </div>

                <button id="modal-save-btn" type="submit">Save Prompt</button>

            </form>

        </div>

    </div>


    <script>

        const promptList = document.getElementById('prompt-list');

        const addPromptBtn = document.getElementById('add-prompt-btn');

        const promptModal = document.getElementById('prompt-modal');

        const closeModalBtn = document.getElementById('close-modal-btn');

        const editPromptForm = document.getElementById('edit-prompt-form');

        const modalTitleInput = document.getElementById('prompt-title');

        const modalDescriptionInput = document.getElementById('prompt-description');

        const modalTagsInput = document.getElementById('prompt-tags');

        const modalTextInput = document.getElementById('prompt-text');

        const tagFilterSelect = document.getElementById('tag-filter');

        const searchInput = document.getElementById('search-input');

        const sortSelect = document.getElementById('sort-select');

        const noPromptsMessage = document.getElementById('no-prompts-message');


        let prompts = [];

        let editingIndex = null;


        // Helper Functions

        /**

         * Creates a tag element for display

         * @param {string} tag - The tag text

         * @returns {HTMLSpanElement} - The tag element

         */

        function createTagElement(tag) {

            const tagElement = document.createElement('span');

            tagElement.classList.add('prompt-tag');

            tagElement.textContent = tag;

            return tagElement;

        }


        /**

         * Renders the prompt list based on current filters and sorting

         */

        function renderPromptList() {

            const filteredPrompts = filterAndSortPrompts(prompts);

            promptList.innerHTML = ''; // Clear the list

            if (filteredPrompts.length === 0) {

                noPromptsMessage.style.display = 'block';

            } else {

                noPromptsMessage.style.display = 'none';

                filteredPrompts.forEach((prompt, index) => {

                    const promptCard = document.createElement('div');

                    promptCard.classList.add('prompt-card');


                    const promptHeader = document.createElement('div');

                    promptHeader.classList.add('prompt-header');

                    const titleElement = document.createElement('h3');

                    titleElement.textContent = prompt.title;


                    const actionsDiv = document.createElement('div');

                    actionsDiv.classList.add('prompt-actions');


                    const editButton = document.createElement('button');

                    editButton.classList.add('edit-btn');

                    editButton.innerHTML = `<span class="edit-icon"></span>Edit`;

                    editButton.addEventListener('click', () => openModal(index));


                    const deleteButton = document.createElement('button');

                    deleteButton.classList.add('delete-btn');

                    deleteButton.innerHTML = `<span class="delete-icon"></span>Delete`;

                    deleteButton.addEventListener('click', () => deletePrompt(index));


                    actionsDiv.appendChild(editButton);

                    actionsDiv.appendChild(deleteButton);

                    promptHeader.appendChild(titleElement);

                    promptHeader.appendChild(actionsDiv);


                    const tagsElement = document.createElement('div');

                    tagsElement.classList.add('prompt-tags');

                    prompt.tags.forEach(tag => {

                        tagsElement.appendChild(createTagElement(tag));

                    });


                    const descriptionElement = document.createElement('p');

                    descriptionElement.classList.add('prompt-description');

                    descriptionElement.textContent = prompt.description;


                    promptCard.appendChild(promptHeader);

                    promptCard.appendChild(tagsElement);

                    promptCard.appendChild(descriptionElement);


                    promptList.appendChild(promptCard);

                });

            }

        }


        /**

         * Filters and sorts prompts based on search, tag, and sort criteria

         * @param {Array<Prompt>} prompts - The array of prompts to filter and sort

         * @returns {Array<Prompt>} - The filtered and sorted array of prompts

         */

        function filterAndSortPrompts(prompts) {

            const searchTerm = searchInput.value.toLowerCase();

            const selectedTag = tagFilterSelect.value;

            const sortValue = sortSelect.value;


            let filteredPrompts = prompts;


            // Filter by search term

            if (searchTerm) {

                filteredPrompts = filteredPrompts.filter(prompt =>

                    prompt.title.toLowerCase().includes(searchTerm) ||

                    prompt.description.toLowerCase().includes(searchTerm) ||

                    prompt.text.toLowerCase().includes(searchTerm)

                );

            }


            // Filter by tag

            if (selectedTag) {

                filteredPrompts = filteredPrompts.filter(prompt =>

                    prompt.tags.includes(selectedTag)

                );

            }


            // Sort prompts

             if (sortValue === 'created-asc') {

                filteredPrompts.sort((a, b) => a.createdAt - b.createdAt);

            } else if (sortValue === 'created-desc') {

                filteredPrompts.sort((a, b) => b.createdAt - a.createdAt);

            } else if (sortValue === 'modified-asc') {

                filteredPrompts.sort((a, b) => a.modifiedAt - b.modifiedAt);

            } else if (sortValue === 'modified-desc') {

                filteredPrompts.sort((a, b) => b.modifiedAt - a.modifiedAt);

            }


            return filteredPrompts;

        }


        /**

         * Opens the modal for editing or adding a prompt

         * @param {number|null} index - The index of the prompt to edit, or null to add a new prompt

         */

        function openModal(index = null) {

            editingIndex = index;

            if (index !== null) {

                const prompt = prompts[index];

                modalTitleInput.value = prompt.title;

                modalDescriptionInput.value = prompt.description;

                modalTagsInput.value = prompt.tags.join(', ');

                modalTextInput.value = prompt.text;

            } else {

                modalTitleInput.value = '';

                modalDescriptionInput.value = '';

                modalTagsInput.value = '';

                modalTextInput.value = '';

            }

            promptModal.style.display = 'flex';

        }


        /**

         * Closes the modal

         */

        function closeModal() {

            promptModal.style.display = 'none';

        }


        /**

         * Saves the prompt data (new or edited)

         */

        function savePrompt() {

            const title = modalTitleInput.value.trim();

            const description = modalDescriptionInput.value.trim();

            const tags = modalTagsInput.value.split(',').map(tag => tag.trim()).filter(tag => tag);

            const text = modalTextInput.value.trim();


            if (!title || !text) {

                alert('Title and Prompt are required.'); // Basic validation

                return;

            }


            if (editingIndex !== null) {

                // Update existing prompt

                prompts[editingIndex].title = title;

                prompts[editingIndex].description = description;

                prompts[editingIndex].tags = tags;

                prompts[editingIndex].text = text;

                prompts[editingIndex].modifiedAt = new Date();

            } else {

                // Add new prompt

                const newPrompt = {

                    title,

                    description,

                    tags,

                    text,

                    createdAt: new Date(),

                    modifiedAt: new Date()

                };

                prompts.push(newPrompt);

            }

            savePromptsToLocalStorage();

            updateTagFilterOptions();

            renderPromptList();

            closeModal();

        }


        /**

         * Deletes a prompt

         * @param {number} index - The index of the prompt to delete

         */

        function deletePrompt(index) {

            if (confirm('Are you sure you want to delete this prompt?')) {

                prompts.splice(index, 1);

                savePromptsToLocalStorage();

                updateTagFilterOptions();

                renderPromptList();

            }

        }


        /**

         * Saves prompts to localStorage

         */

        function savePromptsToLocalStorage() {

            localStorage.setItem('prompts', JSON.stringify(prompts));

        }


        /**

         * Loads prompts from localStorage

         */

        function loadPromptsFromLocalStorage() {

            const savedPrompts = localStorage.getItem('prompts');

            if (savedPrompts) {

                try{

                    prompts = JSON.parse(savedPrompts);

                } catch(e){

                    console.error("Error parsing saved prompts", e);

                    prompts = [];

                }


            } else {

              // Initialize with default prompts only if no existing data

                const defaultPrompts = [

                    {

                        title: "Example Prompt 1",

                        description: "This is a sample prompt for generating creative content.",

                        tags: ["creative","example"],

                        text: "Write a short story about a cat exploring a new planet.",

                        createdAt: new Date(),

                        modifiedAt: new Date()

                    },

                    {

                        title: "Example Prompt 2",

                        description: "A prompt for summarizing a long article.",

                        tags: ["summary", "example"],

                        text: "Summarize the following article in three concise paragraphs: [article text here]",

                        createdAt: new Date(),

                        modifiedAt: new Date()

                    },

                     {

                        title: "Example Prompt 3",

                        description: "Prompt to generate marketing copy.",

                        tags: ["marketing", "example"],

                        text: "Write compelling marketing copy for a new brand of coffee, highlighting its unique flavor profile and ethical sourcing.",

                        createdAt: new Date(),

                        modifiedAt: new Date()

                    },

                ];

                prompts = defaultPrompts;

                savePromptsToLocalStorage(); //save default prompts

            }

        }


        /**

         * Updates the tag filter dropdown based on the available tags

         */

        function updateTagFilterOptions() {

            const allTags = new Set();

            prompts.forEach(prompt => {

                prompt.tags.forEach(tag => allTags.add(tag));

            });

            tagFilterSelect.innerHTML = '<option value="">All Tags</option>'; // Clear existing options

            allTags.forEach(tag => {

                const option = document.createElement('option');

                option.value = tag;

                option.textContent = tag;

                tagFilterSelect.appendChild(option);

            });

        }


        // Event Listeners

        addPromptBtn.addEventListener('click', openModal);

        closeModalBtn.addEventListener('click', closeModal);

        editPromptForm.addEventListener('submit', (event) => {

            event.preventDefault();

            savePrompt();

        });

        searchInput.addEventListener('input', renderPromptList);

        tagFilterSelect.addEventListener('change', renderPromptList);

        sortSelect.addEventListener('change', renderPromptList);


        // Initial setup

        loadPromptsFromLocalStorage();

        updateTagFilterOptions();

        renderPromptList();

    </script>

</body>

</html>