File size: 4,864 Bytes
e058d03
 
 
 
8b65a0f
 
 
 
 
fe844e6
e058d03
34d6b36
e058d03
 
 
 
 
 
 
34d6b36
e058d03
 
 
 
 
34d6b36
 
e058d03
 
 
fe844e6
e058d03
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34d6b36
e058d03
 
 
 
 
 
 
 
 
 
 
 
 
 
 
641c44a
fe844e6
8b65a0f
e058d03
8b65a0f
e058d03
8b65a0f
e058d03
 
8b65a0f
e058d03
8b65a0f
 
 
e058d03
 
8b65a0f
 
 
e058d03
8b65a0f
e058d03
8b65a0f
 
 
 
fe844e6
 
 
 
 
 
 
 
e058d03
8b65a0f
34d6b36
641c44a
8b65a0f
e058d03
 
 
 
641c44a
e058d03
8b65a0f
e058d03
 
 
 
 
 
 
fe844e6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8b65a0f
e058d03
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
'use client';

import { useState, useEffect } from 'react';
import { ArticleGenerationModal, ArticleGenerationParams } from './ArticleGenerationModal';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';

interface ArticleProps {
  className?: string;
  sourceArticle: string;
  onSourceArticleChange: (text: string) => void;
  isSourceLocked: boolean;
  onSourceLockedChange: (locked: boolean) => void;
}

export function Article({
  className = '',
  sourceArticle,
  onSourceArticleChange,
  isSourceLocked,
  onSourceLockedChange,
}: ArticleProps) {

  const [wordCount, setWordCount] = useState(0);
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [isGeneratingArticle, setIsGeneratingArticle] = useState(false);
  const [isExpandOpen, setIsExpandOpen] = useState(false);

  const updateWordCount = (text: string) => {
    const words = text.trim().split(/\s+/).length;
    setWordCount(text.trim() === '' ? 0 : words);
  };

  useEffect(() => {
    updateWordCount(sourceArticle);
  }, [sourceArticle]);

  const handleSourceArticleChange = (text: string) => {
    if (!isSourceLocked) {
      onSourceArticleChange(text);
    }
  };

  const handleGenerateArticle = async (params: ArticleGenerationParams) => {
    setIsGeneratingArticle(true);
    try {
      // Call the API to generate article
      const response = await fetch('/api/generate-article', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(params),
      });

      if (response.ok) {
        const { article } = await response.json();
        onSourceArticleChange(article);
        setIsModalOpen(false);
      } else {
        console.error('Failed to generate article');
      }
    } catch (error) {
      console.error('Error generating article:', error);
    } finally {
      setIsGeneratingArticle(false);
    }
  };

  return (
    <Card className={`flex flex-col h-full ${className}`}>
      <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-4 px-6 pt-2">
        <CardTitle className="text-lg font-semibold">
          πŸ“„ Source Article
        </CardTitle>
        <div className="flex items-center space-x-4">
          <Button
            onClick={() => setIsModalOpen(true)}
            disabled={isSourceLocked}
            size="sm"
          >
            ✨ Generate
          </Button>
          <span className="text-sm text-muted-foreground">
            {wordCount} words
          </span>
          <div className="flex items-center space-x-2">
            <Checkbox
              id="lock-source"
              checked={isSourceLocked}
              onCheckedChange={onSourceLockedChange}
            />
            <Label htmlFor="lock-source" className="text-sm cursor-pointer">
              πŸ”’ Lock
            </Label>
          </div>
          <Button
            onClick={() => setIsExpandOpen(true)}
            disabled={isSourceLocked}
            variant="outline"
            size="sm"
          >
            β€’ Expand
          </Button>
        </div>
      </CardHeader>

      <CardContent className="flex-1 px-6 pb-6 overflow-hidden">
        <Textarea
          value={sourceArticle}
          onChange={(e) => handleSourceArticleChange(e.target.value)}
          placeholder="Paste or type your source article here (articles, passages, etc.)..."
          disabled={isSourceLocked}
          className="w-full h-full resize-none"
        />
      </CardContent>

      <ArticleGenerationModal
        isOpen={isModalOpen}
        onClose={() => setIsModalOpen(false)}
        onGenerate={handleGenerateArticle}
        isGenerating={isGeneratingArticle}
      />

      {/* Full-screen editor dialog for comfortable editing */}
      <Dialog open={isExpandOpen} onOpenChange={setIsExpandOpen}>
        <DialogContent className="w-[98vw] sm:max-w-none md:max-w-[90vw] h-[70vh] max-h-[95vh] p-0 flex flex-col">
          <DialogHeader className="px-6 pt-6 pb-2">
            <DialogTitle>πŸ“„ Edit Source Article</DialogTitle>
          </DialogHeader>
          <div className="flex-1 px-6 pb-6">
            <Textarea
              value={sourceArticle}
              onChange={(e) => handleSourceArticleChange(e.target.value)}
              placeholder="Paste or type your source article here (articles, passages, etc.)..."
              disabled={isSourceLocked}
              className="w-full h-full resize-none"
            />
          </div>
        </DialogContent>
      </Dialog>
    </Card>
  );
}