vites 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vites-0.1.1/LICENSE +17 -0
- vites-0.1.1/PKG-INFO +45 -0
- vites-0.1.1/README.md +32 -0
- vites-0.1.1/pyproject.toml +29 -0
- vites-0.1.1/setup.cfg +4 -0
- vites-0.1.1/src/mathpotlib/__init__.py +3 -0
- vites-0.1.1/src/mathpotlib/cli.py +56 -0
- vites-0.1.1/src/mathpotlib/texts/apiroutes.txt +81 -0
- vites-0.1.1/src/mathpotlib/texts/directiveslogin.txt +263 -0
- vites-0.1.1/src/mathpotlib/texts/formvalidate.txt +149 -0
- vites-0.1.1/src/mathpotlib/texts/mongocrud.txt +256 -0
- vites-0.1.1/src/mathpotlib/texts/nrouting.txt +118 -0
- vites-0.1.1/src/mathpotlib/texts/pinia.txt +145 -0
- vites-0.1.1/src/mathpotlib/texts/piniaapp.txt +257 -0
- vites-0.1.1/src/mathpotlib/texts/propdrilling.txt +248 -0
- vites-0.1.1/src/mathpotlib/texts/usefetch.txt +74 -0
- vites-0.1.1/src/mathpotlib/texts/vdirectives.txt +187 -0
- vites-0.1.1/src/mathpotlib/texts/vuemep.txt +704 -0
- vites-0.1.1/src/vites.egg-info/PKG-INFO +45 -0
- vites-0.1.1/src/vites.egg-info/SOURCES.txt +21 -0
- vites-0.1.1/src/vites.egg-info/dependency_links.txt +1 -0
- vites-0.1.1/src/vites.egg-info/entry_points.txt +2 -0
- vites-0.1.1/src/vites.egg-info/top_level.txt +1 -0
vites-0.1.1/LICENSE
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nikhil Gupta
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
vites-0.1.1/PKG-INFO
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: vites
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: A command-line library for downloading practical text notes.
|
|
5
|
+
Author: Nikhil Gupta
|
|
6
|
+
License: MIT
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Operating System :: OS Independent
|
|
9
|
+
Requires-Python: >=3.9
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Dynamic: license-file
|
|
13
|
+
|
|
14
|
+
# vites
|
|
15
|
+
|
|
16
|
+
A small Python package that lets you download bundled practical notes from the terminal.
|
|
17
|
+
|
|
18
|
+
## Install
|
|
19
|
+
```bash
|
|
20
|
+
python -m pip install vites
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## List available files
|
|
24
|
+
```bash
|
|
25
|
+
vites list
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Download a file
|
|
29
|
+
```bash
|
|
30
|
+
vites download vdirectives
|
|
31
|
+
vites download usefetch
|
|
32
|
+
vites download propdrilling
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The command saves the requested `.txt` file into your current working directory.
|
|
36
|
+
|
|
37
|
+
Choose a different destination filename/path with:
|
|
38
|
+
```bash
|
|
39
|
+
vites download vdirectives --output my-vue-directives.txt
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
You can also run:
|
|
43
|
+
```bash
|
|
44
|
+
python -m vites.cli download vdirectives
|
|
45
|
+
```
|
vites-0.1.1/README.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# vites
|
|
2
|
+
|
|
3
|
+
A small Python package that lets you download bundled practical notes from the terminal.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
```bash
|
|
7
|
+
python -m pip install vites
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## List available files
|
|
11
|
+
```bash
|
|
12
|
+
vites list
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Download a file
|
|
16
|
+
```bash
|
|
17
|
+
vites download vdirectives
|
|
18
|
+
vites download usefetch
|
|
19
|
+
vites download propdrilling
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The command saves the requested `.txt` file into your current working directory.
|
|
23
|
+
|
|
24
|
+
Choose a different destination filename/path with:
|
|
25
|
+
```bash
|
|
26
|
+
vites download vdirectives --output my-vue-directives.txt
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
You can also run:
|
|
30
|
+
```bash
|
|
31
|
+
python -m vites.cli download vdirectives
|
|
32
|
+
```
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "vites"
|
|
7
|
+
version = "0.1.1"
|
|
8
|
+
description = "A command-line library for downloading practical text notes."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "Nikhil Gupta" }]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Programming Language :: Python :: 3",
|
|
15
|
+
"Operating System :: OS Independent",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[project.scripts]
|
|
19
|
+
vites = "mathpotlib.cli:main"
|
|
20
|
+
|
|
21
|
+
[tool.setuptools]
|
|
22
|
+
package-dir = {"" = "src"}
|
|
23
|
+
include-package-data = true
|
|
24
|
+
|
|
25
|
+
[tool.setuptools.packages.find]
|
|
26
|
+
where = ["src"]
|
|
27
|
+
|
|
28
|
+
[tool.setuptools.package-data]
|
|
29
|
+
mathpotlib = ["texts/*.txt"]
|
vites-0.1.1/setup.cfg
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""Command-line interface for listing and downloading bundled text files."""
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import shutil
|
|
5
|
+
from importlib.resources import files
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
FILES = {
|
|
9
|
+
"nrouting": "nrouting.txt",
|
|
10
|
+
"usefetch": "usefetch.txt",
|
|
11
|
+
"apiroutes": "apiroutes.txt",
|
|
12
|
+
"mongocrud": "mongocrud.txt",
|
|
13
|
+
"pinia": "pinia.txt",
|
|
14
|
+
"formvalidate": "formvalidate.txt",
|
|
15
|
+
"piniaapp": "piniaapp.txt",
|
|
16
|
+
"vuemep": "vuemep.txt",
|
|
17
|
+
"vdirectives": "vdirectives.txt",
|
|
18
|
+
"propdrilling": "propdrilling.txt",
|
|
19
|
+
"directiveslogin": "directiveslogin.txt",
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
def main():
|
|
23
|
+
parser = argparse.ArgumentParser(
|
|
24
|
+
prog="vites",
|
|
25
|
+
description="Download practical text files from the mathpotlib package."
|
|
26
|
+
)
|
|
27
|
+
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
28
|
+
subparsers.add_parser("list", help="Show all available text-file names.")
|
|
29
|
+
|
|
30
|
+
download_parser = subparsers.add_parser(
|
|
31
|
+
"download", help="Copy one text file into the current directory."
|
|
32
|
+
)
|
|
33
|
+
download_parser.add_argument("name", help="Short file name, e.g. vdirectives")
|
|
34
|
+
download_parser.add_argument("-o", "--output", help="Optional output filename or path.")
|
|
35
|
+
|
|
36
|
+
args = parser.parse_args()
|
|
37
|
+
if args.command == "list":
|
|
38
|
+
print("Available vites text files:")
|
|
39
|
+
for name in FILES:
|
|
40
|
+
print(f" {name}")
|
|
41
|
+
return
|
|
42
|
+
|
|
43
|
+
name = args.name.lower()
|
|
44
|
+
if name not in FILES:
|
|
45
|
+
print(f"Unknown file: {args.name}")
|
|
46
|
+
print("Run 'vites list' to see available names.")
|
|
47
|
+
raise SystemExit(2)
|
|
48
|
+
|
|
49
|
+
resource = files("mathpotlib").joinpath("texts", FILES[name])
|
|
50
|
+
destination = Path(args.output) if args.output else Path(FILES[name])
|
|
51
|
+
with resource.open("rb") as source, destination.open("wb") as target:
|
|
52
|
+
shutil.copyfileobj(source, target)
|
|
53
|
+
print(f"Downloaded: {destination.resolve()}")
|
|
54
|
+
|
|
55
|
+
if __name__ == "__main__":
|
|
56
|
+
main()
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
NUXT PRACTICAL 3: NUXT API ROUTES
|
|
2
|
+
=================================================================
|
|
3
|
+
|
|
4
|
+
================================================
|
|
5
|
+
|
|
6
|
+
AIM:
|
|
7
|
+
Create a simple API inside Nuxt using server/api routes.
|
|
8
|
+
The example returns a list of products.
|
|
9
|
+
|
|
10
|
+
PROJECT STRUCTURE:
|
|
11
|
+
nuxt-api/
|
|
12
|
+
|
|
|
13
|
+
|-- app.vue
|
|
14
|
+
|-- pages/
|
|
15
|
+
| |-- index.vue
|
|
16
|
+
|-- server/
|
|
17
|
+
|-- api/
|
|
18
|
+
|-- products.get.js
|
|
19
|
+
|
|
20
|
+
STEP 1: Create the project
|
|
21
|
+
--------------------------
|
|
22
|
+
npx nuxi@latest init nuxt-api
|
|
23
|
+
cd nuxt-api
|
|
24
|
+
npm install
|
|
25
|
+
|
|
26
|
+
STEP 2: app.vue
|
|
27
|
+
---------------
|
|
28
|
+
<template>
|
|
29
|
+
<NuxtPage />
|
|
30
|
+
</template>
|
|
31
|
+
|
|
32
|
+
STEP 3: server/api/products.get.js
|
|
33
|
+
----------------------------------
|
|
34
|
+
export default defineEventHandler(() => {
|
|
35
|
+
return [
|
|
36
|
+
{ id: 1, name: 'Laptop', price: 50000 },
|
|
37
|
+
{ id: 2, name: 'Mobile', price: 20000 },
|
|
38
|
+
{ id: 3, name: 'Headphones', price: 2000 }
|
|
39
|
+
]
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
STEP 4: pages/index.vue
|
|
43
|
+
-----------------------
|
|
44
|
+
<script setup>
|
|
45
|
+
const { data: products, pending, error } = await useFetch('/api/products')
|
|
46
|
+
</script>
|
|
47
|
+
|
|
48
|
+
<template>
|
|
49
|
+
<div>
|
|
50
|
+
<h1>Products</h1>
|
|
51
|
+
|
|
52
|
+
<p v-if="pending">Loading...</p>
|
|
53
|
+
<p v-else-if="error">Could not load products.</p>
|
|
54
|
+
|
|
55
|
+
<div v-else>
|
|
56
|
+
<div v-for="product in products" :key="product.id">
|
|
57
|
+
<h3>{{ product.name }}</h3>
|
|
58
|
+
<p>Price: Rs. {{ product.price }}</p>
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
</template>
|
|
63
|
+
|
|
64
|
+
RUN:
|
|
65
|
+
npm run dev
|
|
66
|
+
|
|
67
|
+
Open:
|
|
68
|
+
http://localhost:3000
|
|
69
|
+
|
|
70
|
+
API endpoint:
|
|
71
|
+
http://localhost:3000/api/products
|
|
72
|
+
|
|
73
|
+
CONCEPT:
|
|
74
|
+
- Files inside server/api create API endpoints.
|
|
75
|
+
- products.get.js handles GET requests.
|
|
76
|
+
- /api/products is the endpoint URL.
|
|
77
|
+
- useFetch('/api/products') calls the Nuxt API route.
|
|
78
|
+
- This example uses a simple array, not a database.
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
================================================
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
Practical 1 – Vue.js Directives: Role-Based Login System
|
|
2
|
+
======================================================
|
|
3
|
+
|
|
4
|
+
Demonstrates: v-if, v-else-if, v-else, v-show, v-for, v-on (@click), and v-model.
|
|
5
|
+
|
|
6
|
+
1. PROJECT STRUCTURE
|
|
7
|
+
--------------------
|
|
8
|
+
Create the project:
|
|
9
|
+
npm create vue@latest
|
|
10
|
+
|
|
11
|
+
Project name: vue-project
|
|
12
|
+
|
|
13
|
+
vue-project/
|
|
14
|
+
├── public/
|
|
15
|
+
├── src/
|
|
16
|
+
│ ├── assets/
|
|
17
|
+
│ │ └── main.css
|
|
18
|
+
│ ├── App.vue
|
|
19
|
+
│ ├── main.js
|
|
20
|
+
│ └── users.json
|
|
21
|
+
├── index.html
|
|
22
|
+
├── package.json
|
|
23
|
+
└── vite.config.js
|
|
24
|
+
|
|
25
|
+
Store users.json inside src so Vue can import it.
|
|
26
|
+
|
|
27
|
+
2. FILE 1 – src/users.json
|
|
28
|
+
--------------------------
|
|
29
|
+
[
|
|
30
|
+
{
|
|
31
|
+
"id": 1,
|
|
32
|
+
"username": "admin",
|
|
33
|
+
"password": "admin",
|
|
34
|
+
"role": "Admin"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"id": 2,
|
|
38
|
+
"username": "Pratik",
|
|
39
|
+
"password": "12345",
|
|
40
|
+
"role": "Teacher"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"id": 3,
|
|
44
|
+
"username": "Kartik",
|
|
45
|
+
"password": "67890",
|
|
46
|
+
"role": "Student"
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
3. FILE 2 – src/App.vue
|
|
51
|
+
-----------------------
|
|
52
|
+
<template>
|
|
53
|
+
<div class="container">
|
|
54
|
+
<h2>Role Based Login</h2>
|
|
55
|
+
|
|
56
|
+
<!-- v-model -->
|
|
57
|
+
<input type="text" v-model="username" placeholder="Enter Username" />
|
|
58
|
+
<input type="password" v-model="password" placeholder="Enter Password" />
|
|
59
|
+
|
|
60
|
+
<!-- v-on -->
|
|
61
|
+
<button @click="login">Login</button>
|
|
62
|
+
<hr />
|
|
63
|
+
|
|
64
|
+
<!-- v-if -->
|
|
65
|
+
<div v-if="loggedIn">
|
|
66
|
+
<!-- Admin Component -->
|
|
67
|
+
<div v-if="currentUser.role === 'Admin'" class="admin">
|
|
68
|
+
<h3>Admin Login</h3>
|
|
69
|
+
<p>ID: {{ currentUser.id }}</p>
|
|
70
|
+
<p>Username: {{ currentUser.username }}</p>
|
|
71
|
+
<p>Role: {{ currentUser.role }}</p>
|
|
72
|
+
<!-- v-show -->
|
|
73
|
+
<p v-show="true">You have Full Access</p>
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<!-- Teacher Component -->
|
|
77
|
+
<div v-else-if="currentUser.role === 'Teacher'" class="teacher">
|
|
78
|
+
<h3>Teacher Login</h3>
|
|
79
|
+
<p>ID: {{ currentUser.id }}</p>
|
|
80
|
+
<p>Username: {{ currentUser.username }}</p>
|
|
81
|
+
<p>Role: {{ currentUser.role }}</p>
|
|
82
|
+
<p v-show="true">Manage Student Records</p>
|
|
83
|
+
</div>
|
|
84
|
+
|
|
85
|
+
<!-- Student Component -->
|
|
86
|
+
<div v-else class="student">
|
|
87
|
+
<h3>Student Login</h3>
|
|
88
|
+
<p>ID: {{ currentUser.id }}</p>
|
|
89
|
+
<p>Username: {{ currentUser.username }}</p>
|
|
90
|
+
<p>Role: {{ currentUser.role }}</p>
|
|
91
|
+
<p v-show="true">View Courses</p>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
<!-- v-else -->
|
|
96
|
+
<div v-else>
|
|
97
|
+
<p>Please Login...</p>
|
|
98
|
+
</div>
|
|
99
|
+
|
|
100
|
+
<hr />
|
|
101
|
+
<h3>Available Users</h3>
|
|
102
|
+
<!-- v-for -->
|
|
103
|
+
<ul>
|
|
104
|
+
<li v-for="user in users" :key="user.id">
|
|
105
|
+
{{ user.id }} - {{ user.username }} ({{ user.role }})
|
|
106
|
+
</li>
|
|
107
|
+
</ul>
|
|
108
|
+
</div>
|
|
109
|
+
</template>
|
|
110
|
+
|
|
111
|
+
<script setup>
|
|
112
|
+
import { ref } from "vue";
|
|
113
|
+
import users from "./users.json";
|
|
114
|
+
|
|
115
|
+
const username = ref("");
|
|
116
|
+
const password = ref("");
|
|
117
|
+
const loggedIn = ref(false);
|
|
118
|
+
const currentUser = ref({});
|
|
119
|
+
|
|
120
|
+
function login() {
|
|
121
|
+
const user = users.find(
|
|
122
|
+
u => u.username === username.value && u.password === password.value
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
if (user) {
|
|
126
|
+
currentUser.value = user;
|
|
127
|
+
loggedIn.value = true;
|
|
128
|
+
} else {
|
|
129
|
+
alert("Invalid Username or Password");
|
|
130
|
+
loggedIn.value = false;
|
|
131
|
+
currentUser.value = {};
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
</script>
|
|
135
|
+
|
|
136
|
+
<style scoped>
|
|
137
|
+
.container {
|
|
138
|
+
width: 400px;
|
|
139
|
+
margin: 30px auto;
|
|
140
|
+
padding: 20px;
|
|
141
|
+
text-align: center;
|
|
142
|
+
border: 2px solid #ccc;
|
|
143
|
+
border-radius: 10px;
|
|
144
|
+
background: #f4f4f4;
|
|
145
|
+
color: #222;
|
|
146
|
+
}
|
|
147
|
+
input {
|
|
148
|
+
width: 90%;
|
|
149
|
+
padding: 10px;
|
|
150
|
+
margin: 8px 0;
|
|
151
|
+
box-sizing: border-box;
|
|
152
|
+
}
|
|
153
|
+
button {
|
|
154
|
+
padding: 10px 20px;
|
|
155
|
+
background: royalblue;
|
|
156
|
+
color: white;
|
|
157
|
+
border: none;
|
|
158
|
+
cursor: pointer;
|
|
159
|
+
margin-top: 10px;
|
|
160
|
+
}
|
|
161
|
+
button:hover { background: blue; }
|
|
162
|
+
.admin {
|
|
163
|
+
background: #ffe5e5;
|
|
164
|
+
border: 2px solid red;
|
|
165
|
+
padding: 15px;
|
|
166
|
+
margin-top: 15px;
|
|
167
|
+
border-radius: 8px;
|
|
168
|
+
}
|
|
169
|
+
.teacher {
|
|
170
|
+
background: #e8ffe8;
|
|
171
|
+
border: 2px solid green;
|
|
172
|
+
padding: 15px;
|
|
173
|
+
margin-top: 15px;
|
|
174
|
+
border-radius: 8px;
|
|
175
|
+
}
|
|
176
|
+
.student {
|
|
177
|
+
background: #e6f0ff;
|
|
178
|
+
border: 2px solid blue;
|
|
179
|
+
padding: 15px;
|
|
180
|
+
margin-top: 15px;
|
|
181
|
+
border-radius: 8px;
|
|
182
|
+
}
|
|
183
|
+
ul { list-style: none; padding: 0; }
|
|
184
|
+
li {
|
|
185
|
+
background: white;
|
|
186
|
+
margin: 5px;
|
|
187
|
+
padding: 8px;
|
|
188
|
+
border-radius: 5px;
|
|
189
|
+
}
|
|
190
|
+
</style>
|
|
191
|
+
|
|
192
|
+
4. FILE 3 – src/main.js
|
|
193
|
+
-----------------------
|
|
194
|
+
import './assets/main.css'
|
|
195
|
+
|
|
196
|
+
import { createApp } from 'vue'
|
|
197
|
+
import App from './App.vue'
|
|
198
|
+
|
|
199
|
+
createApp(App).mount('#app')
|
|
200
|
+
|
|
201
|
+
5. FILE 4 – src/assets/main.css
|
|
202
|
+
-------------------------------
|
|
203
|
+
* {
|
|
204
|
+
box-sizing: border-box;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
body {
|
|
208
|
+
margin: 0;
|
|
209
|
+
padding: 0;
|
|
210
|
+
font-family: Arial, sans-serif;
|
|
211
|
+
background: #ffffff;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
6. RUN THE PROJECT
|
|
215
|
+
------------------
|
|
216
|
+
In the VS Code terminal inside vue-project:
|
|
217
|
+
npm install
|
|
218
|
+
npm run dev
|
|
219
|
+
|
|
220
|
+
Open the local URL Vite prints, usually:
|
|
221
|
+
http://localhost:5173/
|
|
222
|
+
|
|
223
|
+
7. LOGIN CREDENTIALS
|
|
224
|
+
--------------------
|
|
225
|
+
Role Username Password
|
|
226
|
+
Admin admin admin
|
|
227
|
+
Teacher Pratik 12345
|
|
228
|
+
Student Kartik 67890
|
|
229
|
+
|
|
230
|
+
8. EXPECTED OUTPUT
|
|
231
|
+
------------------
|
|
232
|
+
Admin Login: ID, username, Admin role, and Full Access.
|
|
233
|
+
Teacher Login: ID, username, Teacher role, and Manage Student Records.
|
|
234
|
+
Student Login: ID, username, Student role, and View Courses.
|
|
235
|
+
|
|
236
|
+
9. VUE DIRECTIVES DEMONSTRATED
|
|
237
|
+
------------------------------
|
|
238
|
+
v-model : Username and password inputs
|
|
239
|
+
v-on : @click="login"
|
|
240
|
+
v-if : Checks login status
|
|
241
|
+
v-else-if : Checks Teacher role
|
|
242
|
+
v-else : Displays Student or Please Login
|
|
243
|
+
v-show : Displays role-specific permissions
|
|
244
|
+
v-for : Displays available users
|
|
245
|
+
|
|
246
|
+
10. FINAL PROJECT STRUCTURE
|
|
247
|
+
---------------------------
|
|
248
|
+
vue-project/
|
|
249
|
+
├── src/
|
|
250
|
+
│ ├── assets/
|
|
251
|
+
│ │ └── main.css
|
|
252
|
+
│ ├── App.vue
|
|
253
|
+
│ ├── main.js
|
|
254
|
+
│ └── users.json
|
|
255
|
+
├── public/
|
|
256
|
+
├── index.html
|
|
257
|
+
├── package.json
|
|
258
|
+
└── vite.config.js
|
|
259
|
+
|
|
260
|
+
IMPLEMENTATION COMPLETE
|
|
261
|
+
|
|
262
|
+
Note: This is a practical demonstration, not production authentication.
|
|
263
|
+
Credentials are stored in a JSON file and should not be used for a real login system.
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
NUXT PRACTICAL 6: ERROR HANDLING AND VALIDATION IN NUXT FORMS
|
|
2
|
+
=================================================================
|
|
3
|
+
|
|
4
|
+
================================================
|
|
5
|
+
|
|
6
|
+
AIM:
|
|
7
|
+
Create a simple registration form with required-field checks,
|
|
8
|
+
email validation, password validation and error messages.
|
|
9
|
+
|
|
10
|
+
PROJECT STRUCTURE:
|
|
11
|
+
nuxt-form-validation/
|
|
12
|
+
|
|
|
13
|
+
|-- app.vue
|
|
14
|
+
|-- pages/
|
|
15
|
+
|-- index.vue
|
|
16
|
+
|
|
17
|
+
STEP 1: Create project
|
|
18
|
+
----------------------
|
|
19
|
+
npx nuxi@latest init nuxt-form-validation
|
|
20
|
+
cd nuxt-form-validation
|
|
21
|
+
npm install
|
|
22
|
+
|
|
23
|
+
STEP 2: app.vue
|
|
24
|
+
---------------
|
|
25
|
+
<template>
|
|
26
|
+
<NuxtPage />
|
|
27
|
+
</template>
|
|
28
|
+
|
|
29
|
+
STEP 3: pages/index.vue
|
|
30
|
+
-----------------------
|
|
31
|
+
<script setup>
|
|
32
|
+
const name = ref('')
|
|
33
|
+
const email = ref('')
|
|
34
|
+
const password = ref('')
|
|
35
|
+
|
|
36
|
+
const errors = ref({})
|
|
37
|
+
const successMessage = ref('')
|
|
38
|
+
|
|
39
|
+
function validateForm() {
|
|
40
|
+
errors.value = {}
|
|
41
|
+
successMessage.value = ''
|
|
42
|
+
|
|
43
|
+
if (!name.value.trim()) {
|
|
44
|
+
errors.value.name = 'Name is required'
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const emailPattern = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/
|
|
48
|
+
|
|
49
|
+
if (!email.value.trim()) {
|
|
50
|
+
errors.value.email = 'Email is required'
|
|
51
|
+
} else if (!emailPattern.test(email.value)) {
|
|
52
|
+
errors.value.email = 'Enter a valid email address'
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (!password.value) {
|
|
56
|
+
errors.value.password = 'Password is required'
|
|
57
|
+
} else if (password.value.length < 6) {
|
|
58
|
+
errors.value.password = 'Password must have at least 6 characters'
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return Object.keys(errors.value).length === 0
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function submitForm() {
|
|
65
|
+
if (!validateForm()) {
|
|
66
|
+
return
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
successMessage.value = 'Registration successful!'
|
|
70
|
+
|
|
71
|
+
name.value = ''
|
|
72
|
+
email.value = ''
|
|
73
|
+
password.value = ''
|
|
74
|
+
errors.value = {}
|
|
75
|
+
}
|
|
76
|
+
</script>
|
|
77
|
+
|
|
78
|
+
<template>
|
|
79
|
+
<div>
|
|
80
|
+
<h1>Registration Form</h1>
|
|
81
|
+
|
|
82
|
+
<form @submit.prevent="submitForm">
|
|
83
|
+
<div>
|
|
84
|
+
<label>Name</label>
|
|
85
|
+
<input v-model="name" type="text" placeholder="Enter name" />
|
|
86
|
+
<p v-if="errors.name" class="error">{{ errors.name }}</p>
|
|
87
|
+
</div>
|
|
88
|
+
|
|
89
|
+
<div>
|
|
90
|
+
<label>Email</label>
|
|
91
|
+
<input v-model="email" type="email" placeholder="Enter email" />
|
|
92
|
+
<p v-if="errors.email" class="error">{{ errors.email }}</p>
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
<div>
|
|
96
|
+
<label>Password</label>
|
|
97
|
+
<input v-model="password" type="password" placeholder="Enter password" />
|
|
98
|
+
<p v-if="errors.password" class="error">{{ errors.password }}</p>
|
|
99
|
+
</div>
|
|
100
|
+
|
|
101
|
+
<button type="submit">Register</button>
|
|
102
|
+
</form>
|
|
103
|
+
|
|
104
|
+
<p v-if="successMessage" class="success">
|
|
105
|
+
{{ successMessage }}
|
|
106
|
+
</p>
|
|
107
|
+
</div>
|
|
108
|
+
</template>
|
|
109
|
+
|
|
110
|
+
<style scoped>
|
|
111
|
+
div {
|
|
112
|
+
margin-bottom: 12px;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
input {
|
|
116
|
+
display: block;
|
|
117
|
+
margin-top: 5px;
|
|
118
|
+
padding: 8px;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.error {
|
|
122
|
+
color: red;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.success {
|
|
126
|
+
color: green;
|
|
127
|
+
}
|
|
128
|
+
</style>
|
|
129
|
+
|
|
130
|
+
RUN:
|
|
131
|
+
npm run dev
|
|
132
|
+
|
|
133
|
+
Open:
|
|
134
|
+
http://localhost:3000
|
|
135
|
+
|
|
136
|
+
CONCEPT:
|
|
137
|
+
- v-model connects form inputs to Vue state.
|
|
138
|
+
- validateForm() checks the entered values.
|
|
139
|
+
- errors stores validation messages.
|
|
140
|
+
- v-if displays errors only when they exist.
|
|
141
|
+
- @submit.prevent stops the browser's normal form submission.
|
|
142
|
+
- The success message appears only when validation passes.
|
|
143
|
+
|
|
144
|
+
IMPORTANT:
|
|
145
|
+
This is basic client-side validation for a classroom practical.
|
|
146
|
+
Real applications must also validate data on the server.
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
================================================
|