040 #21

Merged
cereci5049 merged 1 commit from ayushman into main 2024-08-14 20:05:34 +02:00
11 changed files with 330 additions and 59 deletions

14
Dockerfile Normal file
View file

@ -0,0 +1,14 @@
FROM nimlang/nim:2.0.8-alpine
# RUN apk add sqlite-dev
ENV PORT 8080
EXPOSE 8080
WORKDIR /a3
COPY . .
RUN nimble install -y
ENTRYPOINT [ "nim", "c", "-d:ssl", "-r", "src/hh1.nim" ]

View file

@ -14,5 +14,4 @@ bin = @["hh1"]
requires "nim >= 2.0.8"
requires "https://github.com/ire4ever1190/mike >= 1.3.3"
requires "nimja"
requires "https://codeberg.org/13thab/turso-nim"
requires "https://github.com/euantorano/dotenv.nim"
requires "https://codeberg.org/13thab/turso-nim"

47
src/controller/login.nim Normal file
View file

@ -0,0 +1,47 @@
import
mike,
json,
httpClient,
../lib/[mics, htmx],
../db/users,
../model/rand
proc htmxLogin*(ctx: Context) =
var
form = ctx.urlForm
em =form["email"]
ps=form["password"]
val: Validity
validity = initTable[string, Validity]()
ctx &= initCookie("user2", "$(%* temp[1])")
if em.len==0 or ps.len==0:
for a, b in form:
if form[a] == "":
val.name = ""
val.message = "Field is Required"
val.mark = "is-invalid"
validity[a] = val
else:
val.name = b
val.message = ""
val.mark = ""
validity[a] = val
ctx.send(htmxLogin(validity, ""))
let conn=newTurso()
var temp=getUser(conn, em, ps)
if temp[0] == true:
ctx &= initCookie("user1", $(%* temp[1]))
echo $(%* temp[1])
echo ctx.cookies
ctx.response.headers.add("HX-Redirect", "/")
else:
for a, b in form:
val.name = b
val.message = ""
val.mark = ""
validity[a] = val
ctx.send(htmxLogin(validity, "Invalid Email or Password"))

View file

@ -9,7 +9,7 @@ import
proc signup*(ctx: Context): string=
if ctx.httpMethod == HttpGet:
var
user1 = ctx.cookies.getOrDefault("user1", "none")
user1 = ctx.cookies.getOrDefault("user1", "")
user = getUserFromCookie(user1)
compileTemplateFile(".." / "view" / "signup.nimja", baseDir = getScriptDir())
elif ctx.httpMethod == HttpPost:

Binary file not shown.

View file

@ -1,7 +1,8 @@
import
./users,
./[users, products],
../lib/mics
var conn = newTurso()
setupUsers(conn)
setupUsers(conn)
setupProducts(conn)

View file

@ -0,0 +1,22 @@
import
turso,
strformat,
json,
strutils,
../model/model
proc setupProducts*(conn: Turso) =
conn.execute("""
CREATE TABLE IF NOT EXISTS Products (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
description TEXT,
price REAL,
quantity INTEGER,
sellerId INTEGER,
createdAt TEXT DEFAULT CURRENT_TIMESTAMP NOT NULL,
updatedAt TEXT DEFAULT CURRENT_TIMESTAMP NOT NULL,
imageLink TEXT,
FOREIGN KEY (sellerId) REFERENCES Users(idd)
)
""")

View file

@ -7,21 +7,21 @@ import
proc setupUsers*(conn: Turso) =
conn.execute("""
CREATE TABLE IF NOT EXISTS users (
CREATE TABLE IF NOT EXISTS Users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
first_name VARCHAR(255) NOT NULL,
last_name VARCHAR(255) NOT NULL,
firstName VARCHAR(255) NOT NULL,
lastName VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
phone VARCHAR(255) NOT NULL,
password VARCHAR(255) NOT NULL,
created_at TEXT DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated_at TEXT DEFAULT CURRENT_TIMESTAMP NOT NULL,
access_level INTEGER NOT NULL
createdAt TEXT DEFAULT CURRENT_TIMESTAMP NOT NULL,
updatedAt TEXT DEFAULT CURRENT_TIMESTAMP NOT NULL,
accessLevel INTEGER NOT NULL
)
""")
proc createPost*(conn: Turso, user: User)=
conn.execute(fmt"""INSERT INTO users (first_name, last_name, email, phone, password, access_level) VALUES ("{user.firstName}", "{user.lastName}", "{user.email}", "{user.phone}", "{user.password}", {user.accessLevel});""")
conn.execute(fmt"""INSERT INTO users (firstName, lastName, email, phone, password, accessLevel) VALUES ("{user.firstName}", "{user.lastName}", "{user.email}", "{user.phone}", "{user.password}", {user.accessLevel});""")
proc getUser*(conn: Turso, email: string, password: string): (bool, User)=
echo "h1"

View file

@ -4,10 +4,14 @@ import
strutils,
json,
strformat,
httpClient,
dotenv,
./lib/[mics, htmx],
./db/users,
./model/[model, rand],
./controller/signup
./controller/[signup, login]
load()
"/^path" -> before[post, get]:
var path2 = ctx.pathParams["path"]
@ -22,38 +26,38 @@ import
"/shop" -> get:
var
user1 = ctx.cookies.getOrDefault("user1", "none")
user1 = ctx.cookies.getOrDefault("user1", "")
user = getUserFromCookie(user1)
compileTemplateFile("view" / "shop.nimja", baseDir = getScriptDir())
"/contact" -> get:
var
user1 = ctx.cookies.getOrDefault("user1", "none")
user1 = ctx.cookies.getOrDefault("user1", "")
user = getUserFromCookie(user1)
compileTemplateFile("view" / "contact.nimja", baseDir = getScriptDir())
"/cart" -> get:
var
user1 = ctx.cookies.getOrDefault("user1", "none")
user1 = ctx.cookies.getOrDefault("user1", "")
user = getUserFromCookie(user1)
compileTemplateFile("view" / "cart.nimja", baseDir = getScriptDir())
"/checkout" -> get:
var
user1 = ctx.cookies.getOrDefault("user1", "none")
user1 = ctx.cookies.getOrDefault("user1", "")
user = getUserFromCookie(user1)
compileTemplateFile("view" / "checkout.nimja", baseDir = getScriptDir())
"/shop/:id" -> get:
var
prodId = capitalizeAscii(ctx.pathParams["id"])
user1 = ctx.cookies.getOrDefault("user1", "none")
user1 = ctx.cookies.getOrDefault("user1", "")
user = getUserFromCookie(user1)
compileTemplateFile("view" / "shop-detail.nimja", baseDir = getScriptDir())
"/testimonial" -> get:
var
user1 = ctx.cookies.getOrDefault("user1", "none")
user1 = ctx.cookies.getOrDefault("user1", "")
user = getUserFromCookie(user1)
compileTemplateFile("view" / "testimonial.nimja", baseDir = getScriptDir())
@ -61,48 +65,11 @@ import
"/login" -> get:
var
user1 = ctx.cookies.getOrDefault("user1", "none")
user1 = ctx.cookies.getOrDefault("user1", "")
user = getUserFromCookie(user1)
compileTemplateFile("view" / "login.nimja", baseDir = getScriptDir())
"/htmx/login" -> post:
var
form = ctx.urlForm
em =form["email"]
ps=form["password"]
val: Validity
validity = initTable[string, Validity]()
ctx &= initCookie("user2", "$(%* temp[1])")
if em.len==0 or ps.len==0:
for a, b in form:
if form[a] == "":
val.name = ""
val.message = "Field is Required"
val.mark = "is-invalid"
validity[a] = val
else:
val.name = b
val.message = ""
val.mark = ""
validity[a] = val
ctx.send(htmxLogin(validity, ""))
let conn=newTurso()
var temp=getUser(conn, em, ps)
if temp[0] == true:
ctx &= initCookie("user1", $(%* temp[1]))
echo $(%* temp[1])
echo ctx.cookies
ctx.response.headers.add("HX-Redirect", "/")
else:
for a, b in form:
val.name = b
val.message = ""
val.mark = ""
validity[a] = val
ctx.send(htmxLogin(validity, "Invalid Email or Password"))
"/htmx/login" -> post: ctx.htmxLogin()
"/htmx/email" -> post:
var
@ -130,10 +97,36 @@ import
"/:path" -> get:
var
user1 = ctx.cookies.getOrDefault("user1", "none")
user1 = ctx.cookies.getOrDefault("user1", "")
user = getUserFromCookie(user1)
compileTemplateFile("view" / "404.nimja", baseDir = getScriptDir())
"/hi" -> get:
var
user1 = ctx.cookies.getOrDefault("user1", "")
user = getUserFromCookie(user1)
uploadcare_pub_key = getEnv("UPLOAD_CARE_PUBLIC_KEY")
compileTemplateFile("view" / "hi.nimja", baseDir = getScriptDir())
"/delete-hi" -> post:
var
client = newHttpClient()
uploadcare_pub_key = getEnv("UPLOAD_CARE_PUBLIC_KEY")
uploadcare_secret_key = getEnv("UPLOAD_CARE_SECRET_KEY")
client.headers = newHttpHeaders({"Authorization": fmt"Uploadcare.Simple {uploadcare_pub_key}:{uploadcare_secret_key}"})
var form = ctx.urlForm
echo form
var img_uuid = form["img1"]
echo img_uuid
echo fmt"https://api.uploadcare.com/files/{img_uuid}/storage/"
try:
let response = client.request(fmt"https://api.uploadcare.com/files/{img_uuid}/storage/", httpMethod = HttpDelete)
echo response.status
finally:
client.close()
var js = parseJson("""{"status": "success"}""")
ctx.send(js)
servePublic("src/public", "/static")
run()

155
src/view/hi.nimja Normal file
View file

@ -0,0 +1,155 @@
{% extends "view/partials/_master.nimja" %}
{% block css %}
<link rel="stylesheet" href="/static/css/hi.css">
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@uploadcare/blocks@0.48.0/web/lr-file-uploader-regular.min.css"
/>
{% endblock %}
{% block content %}
<div class="container">
<div class="row">
<div class="col">
<h1>Upload Product Image</h1>
<script type="module">
import * as LR from "https://cdn.jsdelivr.net/npm/@uploadcare/blocks@0.48.0/web/lr-file-uploader-regular.min.js";
LR.registerBlocks(LR);
</script>
<lr-config
ctx-name="my-uploader"
pubkey="{{uploadcare_pub_key}}"
max-local-file-size-bytes="10000000"
multiple="false"
img-only="true"
source-list="local, camera, dropbox, gdrive, gphotos"
></lr-config>
<lr-file-uploader-regular
ctx-name="my-uploader"
class="my-config"
>
</lr-file-uploader-regular>
<!-- The provider node is used to listen to the change event -->
<lr-upload-ctx-provider
ctx-name="my-uploader"
id="my-uploader-provider"
></lr-upload-ctx-provider>
<div id="previews"></div>
<script>
const providerNode = document.getElementById('my-uploader-provider');
const previewsNode = document.getElementById('previews');
providerNode.addEventListener('change', event => {
renderFiles(event.detail.allEntries.filter((file) => file.status === 'success'));
});
let url = "";
let uuid = "";
function renderFiles(files) {
const renderedFiles = files.map(file => {
const imgNode = document.createElement('img');
console.log(file);
imgNode.setAttribute('src', file.cdnUrl);
imgNode.setAttribute('alt', file.fileInfo.originalFilename);
imgNode.setAttribute('width', '100');
imgNode.setAttribute('height', '100');
url = file.cdnUrl;
uuid = file.uuid;
return imgNode;
});
console.log(...renderedFiles);
let formData = new FormData();
formData.append('img', url);
formData.append('img1', uuid);
console.log(formData);
let data = new URLSearchParams(formData);
// data.append('img', url);
// data.append('img1', uuid);
console.log(data);
let btnNode = document.createElement('button');
btnNode.setAttribute('id', 'b4');
btnNode.setAttribute('type', 'submit');
btnNode.setAttribute('class', 'btn btn-primary');
btnNode.addEventListener('click', function() {
console.log('Delete');
console.log(url);
console.log(uuid);
fetch('/delete-hi', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: data,
})
.then((response) => response.json())
.then((data) => {
console.log('Success:', data);
// remove the image and the buttons from the preview
previewsNode.replaceChildren();
})
.catch((error) => {
console.error('Error:', error);
});
});
// btnNode.addEventListener('click', function() {
// console.log('Delete');
// console.log(url);
// console.log(uuid);
// });
// btnNode.addEventListener('click', function() {
// console.log('Submit');
// console.log(url);
// console.log(uuid);
// });
btnNode.innerHTML = 'Delete';
let btnNode1 = document.createElement('button');
btnNode1.setAttribute('id', 'b4');
btnNode1.setAttribute('type', 'submit');
btnNode1.setAttribute('class', 'btn btn-primary');
btnNode1.innerHTML = 'Submit';
btnNode1.addEventListener('click', function() {
console.log('Submit');
console.log(url);
console.log(uuid);
fetch('/jj', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
img: url,
}),
})
.then((response) => response.json())
.then((data) => {
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
});
});
previewsNode.replaceChildren(...renderedFiles, btnNode, btnNode1);
}
// TODO: Add a button to delete the image from the server
// TODO: Add a button to submit the image url to the server
</script>
</div>
</div>
</div>
{% endblock %}

40
src/view/jj.nimja Normal file
View file

@ -0,0 +1,40 @@
{% extends "view/partials/_master.nimja" %}
{% block content %}
<div class="container">
<div class="row">
<div class="col">
<h1 class="mt-5">Login</h1>
<form method="post" id="input_form" class="" novalidate>
<label class="text-danger"></label>
<div class="form-group mt-5">
<label for="email">Email:</label>
<label class="text-danger"></label>
<input type="email" name="email" id="email" class="form-control" required autocomplete="off" value="">
</div>
<div class="form-group">
<label for="password">Password:</label>
<label class="text-danger"></label>
<input type="password" name="password" id="password" class="form-control" required autocomplete="off" value="">
</div>
<div class="form-group">
<input type="file" id="img" name="img" accept="image/*">
</div>
<hr>
<button id="b4" type="submit" class="btn btn-primary">Submit</button>
<a id="b4" href="/signup" class="btn btn-outline-primary">Sign Up</a>
<hr>
</form>
</div>
</div>
</div>
{% endblock %}