-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from sahal-git/V2
initial
- Loading branch information
Showing
74 changed files
with
12,498 additions
and
307 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"extends": "next/core-web-vitals" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
|
||
# testing | ||
/coverage | ||
|
||
# next.js | ||
/.next/ | ||
/out/ | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
*.pem | ||
|
||
# debug | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
# local env files | ||
.env*.local | ||
|
||
# vercel | ||
.vercel | ||
|
||
# typescript | ||
*.tsbuildinfo | ||
next-env.d.ts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { Card } from "@/components/ui/card"; | ||
import { Frame, Sparkles, Shield, Zap } from "lucide-react"; | ||
|
||
export default function About() { | ||
return ( | ||
<div className="container mx-auto px-4 py-16"> | ||
<div className="max-w-4xl mx-auto"> | ||
<h1 className="text-4xl font-bold mb-6">About SAAZ FRAMER</h1> | ||
<p className="text-lg text-muted-foreground mb-12"> | ||
SAAZ FRAMER is a professional image framing tool designed for photographers, artists, and creative professionals who want to enhance their work with beautiful frames and watermarks. | ||
</p> | ||
|
||
<div className="grid md:grid-cols-2 gap-8"> | ||
<Card className="p-6"> | ||
<div className="flex flex-col items-center text-center"> | ||
<div className="p-3 rounded-lg bg-primary/10 mb-4"> | ||
<Sparkles className="w-6 h-6 text-primary" /> | ||
</div> | ||
<h2 className="text-xl font-semibold mb-2">Professional Quality</h2> | ||
<p className="text-muted-foreground"> | ||
Create stunning, high-quality framed images that stand out in any portfolio or gallery. | ||
</p> | ||
</div> | ||
</Card> | ||
|
||
<Card className="p-6"> | ||
<div className="flex flex-col items-center text-center"> | ||
<div className="p-3 rounded-lg bg-primary/10 mb-4"> | ||
<Shield className="w-6 h-6 text-primary" /> | ||
</div> | ||
<h2 className="text-xl font-semibold mb-2">Protect Your Work</h2> | ||
<p className="text-muted-foreground"> | ||
Add custom watermarks to protect your intellectual property while maintaining image quality. | ||
</p> | ||
</div> | ||
</Card> | ||
|
||
<Card className="p-6"> | ||
<div className="flex flex-col items-center text-center"> | ||
<div className="p-3 rounded-lg bg-primary/10 mb-4"> | ||
<Zap className="w-6 h-6 text-primary" /> | ||
</div> | ||
<h2 className="text-xl font-semibold mb-2">Fast & Easy</h2> | ||
<p className="text-muted-foreground"> | ||
Intuitive interface designed for efficiency, letting you create beautiful frames in minutes. | ||
</p> | ||
</div> | ||
</Card> | ||
|
||
<Card className="p-6"> | ||
<div className="flex flex-col items-center text-center"> | ||
<div className="p-3 rounded-lg bg-primary/10 mb-4"> | ||
<Frame className="w-6 h-6 text-primary" /> | ||
</div> | ||
<h2 className="text-xl font-semibold mb-2">Custom Frames</h2> | ||
<p className="text-muted-foreground"> | ||
Use our premium frame collection or upload your own custom frames for unique results. | ||
</p> | ||
</div> | ||
</Card> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
"use client"; | ||
|
||
import { useState } from "react"; | ||
import { Upload, Settings, Save } from "lucide-react"; | ||
import { Button } from "@/components/ui/button"; | ||
import { Card } from "@/components/ui/card"; | ||
import { Input } from "@/components/ui/input"; | ||
import { Label } from "@/components/ui/label"; | ||
import { Separator } from "@/components/ui/separator"; | ||
import { Slider } from "@/components/ui/slider"; | ||
import { toast } from "sonner"; | ||
|
||
export default function Admin() { | ||
const [frameImage, setFrameImage] = useState<string | null>(null); | ||
const [opacity, setOpacity] = useState([0.8]); | ||
const [scale, setScale] = useState([1]); | ||
|
||
const handleFrameUpload = (e: React.ChangeEvent<HTMLInputElement>) => { | ||
const file = e.target.files?.[0]; | ||
if (!file) return; | ||
|
||
if (!file.type.startsWith("image/")) { | ||
toast.error("Please upload an image file"); | ||
return; | ||
} | ||
|
||
const reader = new FileReader(); | ||
reader.onload = (event) => { | ||
setFrameImage(event.target?.result as string); | ||
toast.success("Frame uploaded successfully"); | ||
}; | ||
reader.readAsDataURL(file); | ||
}; | ||
|
||
const saveSettings = () => { | ||
// Save settings to localStorage | ||
const settings = { | ||
frameImage, | ||
opacity: opacity[0], | ||
scale: scale[0], | ||
}; | ||
localStorage.setItem("saazFramerSettings", JSON.stringify(settings)); | ||
toast.success("Settings saved successfully"); | ||
}; | ||
|
||
return ( | ||
<div className="container mx-auto px-4 py-8"> | ||
<div className="max-w-4xl mx-auto"> | ||
<h1 className="text-3xl font-bold mb-8">Admin Settings</h1> | ||
|
||
<div className="grid md:grid-cols-2 gap-8"> | ||
{/* Left Column - Settings */} | ||
<Card className="p-6"> | ||
<h2 className="text-xl font-semibold mb-4">Frame Settings</h2> | ||
|
||
<div className="space-y-6"> | ||
<div> | ||
<Label htmlFor="frameUpload">Default Frame Image</Label> | ||
<Input | ||
id="frameUpload" | ||
type="file" | ||
accept="image/*" | ||
onChange={handleFrameUpload} | ||
className="mt-2" | ||
/> | ||
</div> | ||
|
||
<Separator /> | ||
|
||
<div className="space-y-4"> | ||
<div> | ||
<Label>Frame Opacity</Label> | ||
<Slider | ||
value={opacity} | ||
onValueChange={setOpacity} | ||
min={0} | ||
max={1} | ||
step={0.1} | ||
className="mt-2" | ||
/> | ||
</div> | ||
|
||
<div> | ||
<Label>Frame Scale</Label> | ||
<Slider | ||
value={scale} | ||
onValueChange={setScale} | ||
min={0.5} | ||
max={2} | ||
step={0.1} | ||
className="mt-2" | ||
/> | ||
</div> | ||
</div> | ||
|
||
<Button onClick={saveSettings} className="w-full"> | ||
<Save className="w-4 h-4 mr-2" /> | ||
Save Settings | ||
</Button> | ||
</div> | ||
</Card> | ||
|
||
{/* Right Column - Preview */} | ||
<Card className="p-6"> | ||
<h2 className="text-xl font-semibold mb-4">Frame Preview</h2> | ||
|
||
<div className="aspect-square bg-muted rounded-lg flex items-center justify-center"> | ||
{!frameImage ? ( | ||
<div className="text-center p-8"> | ||
<Settings className="w-12 h-12 mx-auto mb-4 text-muted-foreground" /> | ||
<p className="text-muted-foreground"> | ||
Upload a frame to see preview | ||
</p> | ||
</div> | ||
) : ( | ||
<div className="relative w-full h-full"> | ||
<img | ||
src={frameImage} | ||
alt="Frame Preview" | ||
className="absolute inset-0 w-full h-full object-contain" | ||
style={{ | ||
opacity: opacity[0], | ||
transform: `scale(${scale[0]})`, | ||
}} | ||
/> | ||
</div> | ||
)} | ||
</div> | ||
</Card> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
"use client"; | ||
|
||
import { Card } from "@/components/ui/card"; | ||
import { Button } from "@/components/ui/button"; | ||
import { Input } from "@/components/ui/input"; | ||
import { Label } from "@/components/ui/label"; | ||
import { Textarea } from "@/components/ui/textarea"; | ||
import { toast } from "sonner"; | ||
import { Mail, MessageSquare, Send } from "lucide-react"; | ||
|
||
export default function Contact() { | ||
const handleSubmit = (e: React.FormEvent) => { | ||
e.preventDefault(); | ||
const formData = new FormData(e.target as HTMLFormElement); | ||
const data = { | ||
name: formData.get('name'), | ||
email: formData.get('email'), | ||
message: formData.get('message'), | ||
}; | ||
|
||
// Send email using mailto link | ||
const subject = encodeURIComponent('SAAZ Framer'); | ||
const body = encodeURIComponent(` | ||
Name: ${data.name} | ||
Email: ${data.email} | ||
Message: | ||
${data.message} | ||
`); | ||
window.location.href = `mailto:[email protected]?subject=${subject}&body=${body}`; | ||
|
||
toast.success("Opening your email client..."); | ||
}; | ||
|
||
return ( | ||
<div className="container mx-auto px-4 py-16"> | ||
<div className="max-w-2xl mx-auto"> | ||
<h1 className="text-4xl font-bold mb-6">Contact Us</h1> | ||
<p className="text-lg text-muted-foreground mb-12"> | ||
Have questions or feedback? We'd love to hear from you. Send us a message and we'll respond as soon as possible. | ||
</p> | ||
|
||
<Card className="p-6"> | ||
<form onSubmit={handleSubmit} className="space-y-6"> | ||
<div className="space-y-2"> | ||
<Label htmlFor="name">Name</Label> | ||
<Input id="name" name="name" placeholder="Your name" required /> | ||
</div> | ||
|
||
<div className="space-y-2"> | ||
<Label htmlFor="email">Email</Label> | ||
<Input id="email" name="email" type="email" placeholder="[email protected]" required /> | ||
</div> | ||
|
||
<div className="space-y-2"> | ||
<Label htmlFor="message">Message</Label> | ||
<Textarea | ||
id="message" | ||
name="message" | ||
placeholder="Your message..." | ||
className="min-h-[150px]" | ||
required | ||
/> | ||
</div> | ||
|
||
<Button type="submit" className="w-full"> | ||
<Send className="w-4 h-4 mr-2" /> | ||
Send Message | ||
</Button> | ||
</form> | ||
</Card> | ||
|
||
<div className="mt-12 grid sm:grid-cols-2 gap-6"> | ||
<Card className="p-6"> | ||
<div className="flex items-center gap-4"> | ||
<Mail className="w-6 h-6 text-primary" /> | ||
<div> | ||
<h2 className="font-semibold">Email Us</h2> | ||
<p className="text-sm text-muted-foreground">[email protected]</p> | ||
</div> | ||
</div> | ||
</Card> | ||
|
||
<Card className="p-6"> | ||
<a | ||
href="https://instagram.com/sa.halk" | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
className="flex items-center gap-4" | ||
> | ||
<MessageSquare className="w-6 h-6 text-primary" /> | ||
<div> | ||
<h2 className="font-semibold">Live Chat</h2> | ||
<p className="text-sm text-muted-foreground">Chat on Instagram @sa.halk</p> | ||
</div> | ||
</a> | ||
</Card> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} |
Oops, something went wrong.