Untitled

 avatar
user_0279522
plain_text
24 days ago
7.8 kB
3
Indexable
import React, { useState, useRef } from 'react';

const TextEditor = () => {
  const [content, setContent] = useState('');
  const [fontSize, setFontSize] = useState(16);
  const [fontFamily, setFontFamily] = useState('Arial');
  const [textAlign, setTextAlign] = useState('left');
  const [isBold, setIsBold] = useState(false);
  const [isItalic, setIsItalic] = useState(false);
  const [isUnderlined, setIsUnderlined] = useState(false);
  const [textColor, setTextColor] = useState('#000000');
  const editorRef = useRef(null);
  
  const handleContentChange = (e) => {
    setContent(e.target.value);
  };
  
  const handleFontSizeChange = (e) => {
    setFontSize(parseInt(e.target.value));
  };
  
  const handleFontFamilyChange = (e) => {
    setFontFamily(e.target.value);
  };
  
  const handleTextAlignChange = (alignment) => {
    setTextAlign(alignment);
  };
  
  const handleBoldToggle = () => {
    setIsBold(!isBold);
  };
  
  const handleItalicToggle = () => {
    setIsItalic(!isItalic);
  };
  
  const handleUnderlineToggle = () => {
    setIsUnderlined(!isUnderlined);
  };
  
  const handleColorChange = (e) => {
    setTextColor(e.target.value);
  };
  
  const handlePrint = () => {
    const printWindow = window.open('', '_blank');
    printWindow.document.write(`
      <html>
        <head>
          <title>Document imprimé</title>
          <style>
            body {
              font-family: ${fontFamily};
              font-size: ${fontSize}px;
              color: ${textColor};
              text-align: ${textAlign};
              font-weight: ${isBold ? 'bold' : 'normal'};
              font-style: ${isItalic ? 'italic' : 'normal'};
              text-decoration: ${isUnderlined ? 'underline' : 'none'};
            }
          </style>
        </head>
        <body>
          ${content.replace(/\n/g, '<br>')}
        </body>
      </html>
    `);
    printWindow.document.close();
    printWindow.print();
  };
  
  const handleSave = () => {
    // Créer un objet Blob avec le contenu
    const documentData = {
      content,
      style: {
        fontFamily,
        fontSize,
        textAlign,
        isBold,
        isItalic,
        isUnderlined,
        textColor
      }
    };
    
    const blob = new Blob([JSON.stringify(documentData)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    
    // Créer un lien de téléchargement et cliquer dessus
    const link = document.createElement('a');
    link.href = url;
    link.download = 'document.json';
    document.body.appendChild(link);
    link.click();
    
    // Nettoyer
    URL.revokeObjectURL(url);
    document.body.removeChild(link);
  };
  
  // Styles for editor
  const editorStyle = {
    fontFamily,
    fontSize: `${fontSize}px`,
    fontWeight: isBold ? 'bold' : 'normal',
    fontStyle: isItalic ? 'italic' : 'normal',
    textDecoration: isUnderlined ? 'underline' : 'none',
    textAlign,
    color: textColor,
    width: '100%',
    minHeight: '400px',
    padding: '10px',
    boxSizing: 'border-box',
    border: '1px solid #ccc',
    outline: 'none',
    resize: 'vertical',
    overflowY: 'auto',
    backgroundColor: 'white'
  };
  
  return (
    <div className="w-full max-w-4xl mx-auto bg-white rounded-lg shadow-lg p-4">
      <div className="bg-gray-100 p-2 rounded-lg mb-4">
        <div className="flex flex-wrap gap-2 mb-2">
          {/* Font Family */}
          <select 
            value={fontFamily} 
            onChange={handleFontFamilyChange}
            className="border rounded px-2 py-1 text-sm"
          >
            <option value="Arial">Arial</option>
            <option value="Times New Roman">Times New Roman</option>
            <option value="Courier New">Courier New</option>
            <option value="Georgia">Georgia</option>
            <option value="Verdana">Verdana</option>
            <option value="Tahoma">Tahoma</option>
          </select>
          
          {/* Font Size */}
          <select 
            value={fontSize} 
            onChange={handleFontSizeChange}
            className="border rounded px-2 py-1 text-sm"
          >
            {[8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72].map(size => (
              <option key={size} value={size}>{size}</option>
            ))}
          </select>
          
          {/* Text Color */}
          <input 
            type="color" 
            value={textColor} 
            onChange={handleColorChange}
            className="border rounded px-1 py-1 h-8 w-8"
          />
          
          {/* Formatting buttons */}
          <button 
            onClick={handleBoldToggle} 
            className={`px-2 py-1 border rounded ${isBold ? 'bg-gray-300' : 'bg-white'}`}
            title="Gras"
          >
            <strong>G</strong>
          </button>
          
          <button 
            onClick={handleItalicToggle} 
            className={`px-2 py-1 border rounded ${isItalic ? 'bg-gray-300' : 'bg-white'}`}
            title="Italique"
          >
            <em>I</em>
          </button>
          
          <button 
            onClick={handleUnderlineToggle} 
            className={`px-2 py-1 border rounded ${isUnderlined ? 'bg-gray-300' : 'bg-white'}`}
            title="Souligné"
          >
            <u>S</u>
          </button>
          
          {/* Text Alignment */}
          <button 
            onClick={() => handleTextAlignChange('left')} 
            className={`px-2 py-1 border rounded ${textAlign === 'left' ? 'bg-gray-300' : 'bg-white'}`}
            title="Aligner à gauche"
          >
            ⟵
          </button>
          
          <button 
            onClick={() => handleTextAlignChange('center')} 
            className={`px-2 py-1 border rounded ${textAlign === 'center' ? 'bg-gray-300' : 'bg-white'}`}
            title="Centrer"
          >
            ↔
          </button>
          
          <button 
            onClick={() => handleTextAlignChange('right')} 
            className={`px-2 py-1 border rounded ${textAlign === 'right' ? 'bg-gray-300' : 'bg-white'}`}
            title="Aligner à droite"
          >
            ⟶
          </button>
          
          <button 
            onClick={() => handleTextAlignChange('justify')} 
            className={`px-2 py-1 border rounded ${textAlign === 'justify' ? 'bg-gray-300' : 'bg-white'}`}
            title="Justifier"
          >
            ⇌
          </button>
          
          {/* Save button */}
          <button 
            onClick={handleSave} 
            className="px-2 py-1 border rounded bg-green-600 text-white ml-auto mr-2"
            title="Sauvegarder"
          >
            Sauvegarder
          </button>
          
          {/* Print button */}
          <button 
            onClick={handlePrint} 
            className="px-2 py-1 border rounded bg-blue-600 text-white"
            title="Imprimer"
          >
            Imprimer
          </button>
        </div>
      </div>
      
      <textarea
        ref={editorRef}
        style={editorStyle}
        value={content}
        onChange={handleContentChange}
        placeholder="Commencez à saisir votre texte ici..."
        className="rounded"
      />
      
      <div className="mt-4 text-gray-500 text-xs">
        <p>Caractères: {content.length} | Mots: {content.trim() ? content.trim().split(/\s+/).length : 0}</p>
      </div>
    </div>
  );
};

export default TextEditor;
Editor is loading...
Leave a Comment