diff --git a/src/components/conversion-input.tsx b/src/components/conversion-input.tsx
new file mode 100644
index 0000000..7e560a5
--- /dev/null
+++ b/src/components/conversion-input.tsx
@@ -0,0 +1,111 @@
+import { RefObject, forwardRef, useState } from 'react';
+
+import { cn } from '@/utils/cn';
+import { ClipboardEdit, Paperclip, Upload } from 'lucide-react';
+import { buttonVariants } from './ui/button';
+import { Textarea } from './ui/text-area';
+
+type ConversionInputProps = {
+ onFromContentsChange: (e: React.ChangeEvent
) => void;
+ acceptableFileExtensions?: string
+}
+
+const ConversionInput = forwardRef(({ onFromContentsChange, acceptableFileExtensions = '', ...props }, ref) => {
+ // Idealy we would just want this is as a formatted variable. But due to next.js hydration, we need to use state
+ const [isDragActive, setIsDragActive] = useState(false)
+
+ const textAreaRef = (ref as RefObject).current
+ const handleFile = (file: File) => {
+ console.log()
+ const reader = new FileReader();
+ reader.readAsText(file, "UTF-8");
+ reader.onload = function (evt) {
+ if (evt.target) {
+ const result = evt.target.result as string
+ onFromContentsChange({
+ target: {
+ value: result
+ }
+ } as React.ChangeEvent)
+
+ if (textAreaRef) {
+ textAreaRef.value = result
+ }
+ }
+ }
+ reader.onerror = function (evt) {
+ console.error(evt.target?.error)
+ }
+ setIsDragActive(false)
+ }
+
+ const handleDrop = (e: React.DragEvent) => {
+ e.preventDefault()
+ e.stopPropagation()
+ if (e && e.dataTransfer && e.dataTransfer.files) {
+ const file = e.dataTransfer.files?.[0]
+ if (file) {
+ handleFile(file)
+ }
+ }
+ }
+
+
+ return (
+
+
+ {
+ textAreaRef?.value === '' && (
+ isDragActive ? (
+ <>
+
+
+ Drop it to convert!
+
+ >
+ ) : (
+ <>
+
+
+ Drag and drop or Paste in the contents of a{acceptableFileExtensions} file here
+
+
{
+ const file = e.target.files?.[0]
+ if (file) {
+ handleFile(file)
+ }
+ }}
+ />
+
+ >
+ )
+ )
+ }
+
+
+ )
+})
+
+ConversionInput.displayName = 'ConversionInput'
+
+export default ConversionInput
\ No newline at end of file
diff --git a/src/components/conversion-layout.tsx b/src/components/conversion-layout.tsx
index b2ca77a..8501432 100644
--- a/src/components/conversion-layout.tsx
+++ b/src/components/conversion-layout.tsx
@@ -1,9 +1,8 @@
/* eslint-disable react-hooks/rules-of-hooks */
"use client"
-import { forwardRef, useRef } from "react";
+import { forwardRef } from "react";
import ShowHide from "@/components/ui/show-hide";
-import { Textarea } from "@/components/ui/text-area";
import { cn } from "@/utils/cn";
import React from 'react';
import ConversionPageHeader, { ConversionPageHeaderProps } from "./conversion-page-header";
@@ -12,19 +11,19 @@ type ConversionLayoutProps = ConversionPageHeaderProps & {
collapsed: boolean;
secondEditor: React.ReactNode;
children: React.ReactNode | React.ReactNodeArray;
- onFromContentsChange: (e: React.ChangeEvent) => void;
+ inputSection: React.ReactNode;
}
-const ConversionLayout = forwardRef(({
+const ConversionLayout = forwardRef(({
collapsed,
children,
- onFromContentsChange,
secondEditor,
+ inputSection,
...conversionPageHeaderProps
}, ref) => {
- const inputRef = ref || useRef(null)
return (
(
collapsed ? 'w-1/2' : 'w-full',
)}
>
-
+ {inputSection}
,
- VariantProps { }
+ VariantProps {
+ as?: JSX.Element
+}
const Button = React.forwardRef(
- ({ className, variant, size, ...props }, ref) => {
- return (
-
- );
+ ({ className, variant, size, as, ...props }, ref) => {
+ const genProps = {
+ className: cn(buttonVariants({ variant, size, className })),
+ ref: ref,
+ ...props,
+ }
+ if (as !== undefined) {
+ return React.cloneElement(as, genProps)
+ } else {
+ return (
+
+ );
+ }
}
);
Button.displayName = "Button";
diff --git a/src/utils/string.ts b/src/utils/string.ts
new file mode 100644
index 0000000..c859c48
--- /dev/null
+++ b/src/utils/string.ts
@@ -0,0 +1,10 @@
+/* eslint-disable @typescript-eslint/no-non-null-assertion */
+export const listWordsInSentenceFormat = (
+ words: string[],
+ conjunction = "or"
+): string => {
+ if (words.length === 0) return "";
+ if (words.length === 1) return words[0]!;
+ const lastWord = words.pop();
+ return [words.join(", "), lastWord].join(` ${conjunction} `);
+};