build
@@ -1,5 +1,4 @@
|
||||
node_modules
|
||||
build
|
||||
coverage
|
||||
.vscode
|
||||
.DS_STORE
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const User_1 = __importDefault(global[Symbol.for('ioc.use')]("App/Models/User"));
|
||||
const CreateUserValidator_1 = __importDefault(global[Symbol.for('ioc.use')]("App/Validators/CreateUserValidator"));
|
||||
class AuthController {
|
||||
async login({ view }) {
|
||||
return view.render('auth/login');
|
||||
}
|
||||
async doLogin({ request, auth, response, session }) {
|
||||
const email = request.input('email');
|
||||
const password = request.input('password');
|
||||
try {
|
||||
await auth.use('web').attempt(email, password);
|
||||
response.redirect().toRoute('home');
|
||||
}
|
||||
catch {
|
||||
session.flash({ error: 'Identifiants incorrects' });
|
||||
response.redirect().toRoute('login');
|
||||
}
|
||||
}
|
||||
async signup({ view }) {
|
||||
return view.render('auth/signup');
|
||||
}
|
||||
async doSignup({ request, response, auth }) {
|
||||
const playload = await request.validate(CreateUserValidator_1.default);
|
||||
await User_1.default.create(playload);
|
||||
try {
|
||||
await auth.use('web').attempt(playload.email, playload.password);
|
||||
response.redirect().toRoute('home');
|
||||
}
|
||||
catch {
|
||||
response.redirect().toRoute('login');
|
||||
}
|
||||
}
|
||||
async logout({ auth, response }) {
|
||||
await auth.logout();
|
||||
return response.redirect().back();
|
||||
}
|
||||
}
|
||||
exports.default = AuthController;
|
||||
//# sourceMappingURL=AuthController.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"AuthController.js","sourceRoot":"","sources":["../../../../app/Controllers/Http/AuthController.ts"],"names":[],"mappings":";;;;;AACA,iFAAmC;AACnC,mHAAqE;AAGrE,MAAqB,cAAc;IAEjC,KAAK,CAAC,KAAK,CAAC,EAAE,IAAI,EAAuB;QACvC,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;IAClC,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAuB;QACrE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACpC,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;QAE1C,IAAI;YACF,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;YAC9C,QAAQ,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;SACpC;QAAC,MAAM;YACN,OAAO,CAAC,KAAK,CAAC,EAAC,KAAK,EAAE,yBAAyB,EAAC,CAAC,CAAA;YACjD,QAAQ,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;SACrC;IACH,CAAC;IAGD,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAuB;QACxC,OAAO,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAA;IACnC,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAuB;QAC7D,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,6BAAmB,CAAC,CAAA;QAC5D,MAAM,cAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QAC3B,IAAI;YACF,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAA;YAChE,QAAQ,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;SACpC;QAAC,MAAM;YACN,QAAQ,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;SACrC;IACH,CAAC;IAGD,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAsB;QACjD,MAAM,IAAI,CAAC,MAAM,EAAE,CAAA;QACnB,OAAO,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAA;IACpC,CAAC;CACD;AAxCD,iCAwCC"}
|
||||
@@ -0,0 +1,36 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const ModifPseudoValidator_1 = __importDefault(global[Symbol.for('ioc.use')]("App/Validators/ModifPseudoValidator"));
|
||||
const ModifEmailValidator_1 = __importDefault(global[Symbol.for('ioc.use')]("App/Validators/ModifEmailValidator"));
|
||||
class CompteController {
|
||||
async index({ view }) {
|
||||
return view.render('compte');
|
||||
}
|
||||
async modifpseudo({ request, auth, session, response }) {
|
||||
const user = auth.user;
|
||||
await request.validate(ModifPseudoValidator_1.default);
|
||||
user.pseudo = request.input('pseudo');
|
||||
await user.save();
|
||||
session.flash({ success: "Username updated successfully" });
|
||||
response.redirect().back();
|
||||
}
|
||||
async modifemail({ request, auth, session, response }) {
|
||||
const user = auth.user;
|
||||
await request.validate(ModifEmailValidator_1.default);
|
||||
user.email = request.input('email');
|
||||
await user.save();
|
||||
session.flash({ success: "Email updated successfully" });
|
||||
response.redirect().back();
|
||||
}
|
||||
async delete({ auth, response }) {
|
||||
const user = auth.user;
|
||||
await user.delete();
|
||||
await auth.logout();
|
||||
response.redirect().toRoute('home');
|
||||
}
|
||||
}
|
||||
exports.default = CompteController;
|
||||
//# sourceMappingURL=CompteController.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"CompteController.js","sourceRoot":"","sources":["../../../../app/Controllers/Http/CompteController.ts"],"names":[],"mappings":";;;;;AACA,qHAAsE;AACtE,mHAAoE;AAEpE,MAAqB,gBAAgB;IAEnC,KAAK,CAAC,KAAK,CAAC,EAAE,IAAI,EAAuB;QACvC,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IAC9B,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAuB;QACzE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;QAEtB,MAAM,OAAO,CAAC,QAAQ,CAAC,8BAAoB,CAAC,CAAA;QAE5C,IAAK,CAAC,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;QACtC,MAAM,IAAK,CAAC,IAAI,EAAE,CAAA;QAClB,OAAO,CAAC,KAAK,CAAC,EAAC,OAAO,EAAE,+BAA+B,EAAC,CAAC,CAAA;QACzD,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAA;IAC5B,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAuB;QACxE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;QAEtB,MAAM,OAAO,CAAC,QAAQ,CAAC,6BAAmB,CAAC,CAAA;QAE3C,IAAK,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACpC,MAAM,IAAK,CAAC,IAAI,EAAE,CAAA;QAClB,OAAO,CAAC,KAAK,CAAC,EAAC,OAAO,EAAE,4BAA4B,EAAC,CAAC,CAAA;QACtD,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAA;IAC5B,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAuB;QAClD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;QACtB,MAAM,IAAK,CAAC,MAAM,EAAE,CAAA;QACpB,MAAM,IAAI,CAAC,MAAM,EAAE,CAAA;QACnB,QAAQ,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IACrC,CAAC;CAEF;AAnCD,mCAmCC"}
|
||||
@@ -0,0 +1,26 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const standalone_1 = require("@adonisjs/auth/build/standalone");
|
||||
class AuthMiddleware {
|
||||
constructor() {
|
||||
this.redirectTo = 'auth/login';
|
||||
}
|
||||
async authenticate(auth, guards) {
|
||||
let guardLastAttempted;
|
||||
for (let guard of guards) {
|
||||
guardLastAttempted = guard;
|
||||
if (await auth.use(guard).check()) {
|
||||
auth.defaultGuard = guard;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
throw new standalone_1.AuthenticationException('Unauthorized access', 'E_UNAUTHORIZED_ACCESS', guardLastAttempted, this.redirectTo);
|
||||
}
|
||||
async handle({ auth }, next, customGuards) {
|
||||
const guards = customGuards.length ? customGuards : [auth.name];
|
||||
await this.authenticate(auth, guards);
|
||||
await next();
|
||||
}
|
||||
}
|
||||
exports.default = AuthMiddleware;
|
||||
//# sourceMappingURL=Auth.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"Auth.js","sourceRoot":"","sources":["../../../app/Middleware/Auth.ts"],"names":[],"mappings":";;AAAA,gEAAyE;AAWzE,MAAqB,cAAc;IAAnC;QAIY,eAAU,GAAG,YAAY,CAAA;IA4DrC,CAAC;IAlDW,KAAK,CAAC,YAAY,CAAC,IAAiC,EAAE,MAA4B;QAO1F,IAAI,kBAAsC,CAAA;QAE1C,KAAK,IAAI,KAAK,IAAI,MAAM,EAAE;YACxB,kBAAkB,GAAG,KAAK,CAAA;YAE1B,IAAI,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gBAMjC,IAAI,CAAC,YAAY,GAAG,KAAK,CAAA;gBACzB,OAAO,IAAI,CAAA;aACZ;SACF;QAKD,MAAM,IAAI,oCAAuB,CAC/B,qBAAqB,EACrB,uBAAuB,EACvB,kBAAkB,EAClB,IAAI,CAAC,UAAU,CAChB,CAAA;IACH,CAAC;IAKM,KAAK,CAAC,MAAM,CACjB,EAAE,IAAI,EAAuB,EAC7B,IAAyB,EACzB,YAAkC;QAMlC,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC/D,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QACrC,MAAM,IAAI,EAAE,CAAA;IACd,CAAC;CACF;AAhED,iCAgEC"}
|
||||
@@ -0,0 +1,10 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
class SilentAuthMiddleware {
|
||||
async handle({ auth }, next) {
|
||||
await auth.check();
|
||||
await next();
|
||||
}
|
||||
}
|
||||
exports.default = SilentAuthMiddleware;
|
||||
//# sourceMappingURL=SilentAuth.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"SilentAuth.js","sourceRoot":"","sources":["../../../app/Middleware/SilentAuth.ts"],"names":[],"mappings":";;AAQA,MAAqB,oBAAoB;IAIhC,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAuB,EAAE,IAAyB;QAK1E,MAAM,IAAI,CAAC,KAAK,EAAE,CAAA;QAClB,MAAM,IAAI,EAAE,CAAA;IACd,CAAC;CACF;AAZD,uCAYC"}
|
||||
@@ -0,0 +1,76 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const luxon_1 = require("luxon");
|
||||
const Hash_1 = __importDefault(global[Symbol.for('ioc.use')]("Adonis/Core/Hash"));
|
||||
const Orm_1 = global[Symbol.for('ioc.use')]("Adonis/Lucid/Orm");
|
||||
const ResponsiveAttachment_1 = global[Symbol.for('ioc.use')]("Adonis/Addons/ResponsiveAttachment");
|
||||
class User extends Orm_1.BaseModel {
|
||||
get avatarUrl() {
|
||||
if (this.avatar) {
|
||||
return '/uploads/' + this.avatar.breakpoints.small.name;
|
||||
}
|
||||
return 'https://source.boringavatars.com/beam/40/${this.email}?colors=001449,012677,005BC5,00B4FC,17F9FF';
|
||||
}
|
||||
static async hashPassword(user) {
|
||||
if (user.$dirty.password) {
|
||||
user.password = await Hash_1.default.make(user.password);
|
||||
}
|
||||
}
|
||||
}
|
||||
__decorate([
|
||||
(0, Orm_1.column)({ isPrimary: true }),
|
||||
__metadata("design:type", Number)
|
||||
], User.prototype, "id", void 0);
|
||||
__decorate([
|
||||
(0, Orm_1.column)(),
|
||||
__metadata("design:type", String)
|
||||
], User.prototype, "pseudo", void 0);
|
||||
__decorate([
|
||||
(0, Orm_1.column)(),
|
||||
__metadata("design:type", String)
|
||||
], User.prototype, "email", void 0);
|
||||
__decorate([
|
||||
(0, Orm_1.column)({ serializeAs: null }),
|
||||
__metadata("design:type", String)
|
||||
], User.prototype, "password", void 0);
|
||||
__decorate([
|
||||
(0, Orm_1.column)(),
|
||||
__metadata("design:type", Object)
|
||||
], User.prototype, "rememberMeToken", void 0);
|
||||
__decorate([
|
||||
Orm_1.column.dateTime({ autoCreate: true }),
|
||||
__metadata("design:type", luxon_1.DateTime)
|
||||
], User.prototype, "createdAt", void 0);
|
||||
__decorate([
|
||||
Orm_1.column.dateTime({ autoCreate: true, autoUpdate: true }),
|
||||
__metadata("design:type", luxon_1.DateTime)
|
||||
], User.prototype, "updatedAt", void 0);
|
||||
__decorate([
|
||||
(0, ResponsiveAttachment_1.responsiveAttachment)({ preComputeUrls: true }),
|
||||
__metadata("design:type", Object)
|
||||
], User.prototype, "avatar", void 0);
|
||||
__decorate([
|
||||
(0, Orm_1.computed)(),
|
||||
__metadata("design:type", Object),
|
||||
__metadata("design:paramtypes", [])
|
||||
], User.prototype, "avatarUrl", null);
|
||||
__decorate([
|
||||
(0, Orm_1.beforeSave)(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [User]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], User, "hashPassword", null);
|
||||
exports.default = User;
|
||||
//# sourceMappingURL=User.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"User.js","sourceRoot":"","sources":["../../../app/Models/User.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,iCAAgC;AAChC,kFAAwC;AACxC,gEAA+E;AAC/E,mGAA4G;AAE5G,MAAqB,IAAK,SAAQ,eAAS;IA0BzC,IAAW,SAAS;QAClB,IAAI,IAAI,CAAC,MAAM,EAAE;YACf,OAAO,WAAW,GAAC,IAAI,CAAC,MAAM,CAAC,WAAY,CAAC,KAAK,CAAC,IAAI,CAAA;SACvD;QACD,OAAO,kGAAkG,CAAA;IAC3G,CAAC;IAGM,MAAM,CAAC,KAAK,CAAC,YAAY,CAAE,IAAU;QAC1C,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE;YACxB,IAAI,CAAC,QAAQ,GAAG,MAAM,cAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;SAC/C;IACH,CAAC;CACF;AArCC;IADC,IAAA,YAAM,EAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;;gCACX;AAGjB;IADC,IAAA,YAAM,GAAE;;oCACY;AAGrB;IADC,IAAA,YAAM,GAAE;;mCACW;AAGpB;IADC,IAAA,YAAM,EAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;;sCACP;AAGvB;IADC,IAAA,YAAM,GAAE;;6CAC4B;AAGrC;IADC,YAAM,CAAC,QAAQ,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;8BACpB,gBAAQ;uCAAA;AAG1B;IADC,YAAM,CAAC,QAAQ,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;8BACtC,gBAAQ;uCAAA;AAG1B;IADC,IAAA,2CAAoB,EAAC,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC;;oCACJ;AAG3C;IADC,IAAA,cAAQ,GAAE;;;qCAMV;AAGD;IADC,IAAA,gBAAU,GAAE;;qCAC2B,IAAI;;8BAI3C;AAtCH,uBAuCC"}
|
||||
@@ -0,0 +1,21 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const Validator_1 = global[Symbol.for('ioc.use')]("Adonis/Core/Validator");
|
||||
class CreateUserValidator {
|
||||
constructor(ctx) {
|
||||
this.ctx = ctx;
|
||||
this.schema = Validator_1.schema.create({
|
||||
pseudo: Validator_1.schema.string(),
|
||||
email: Validator_1.schema.string({}, [Validator_1.rules.email(), Validator_1.rules.unique({ table: 'users', column: 'email' })]),
|
||||
password: Validator_1.schema.string({}, [Validator_1.rules.minLength(4), Validator_1.rules.confirmed()])
|
||||
});
|
||||
this.messages = {
|
||||
required: 'The {{ field }} is required to create a new account',
|
||||
'email.email': 'Vous devez saisir un email dans le champ email',
|
||||
'email.unique': 'Email is already in use',
|
||||
'password.minLength': 'The password must be at least 4 characters long'
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.default = CreateUserValidator;
|
||||
//# sourceMappingURL=CreateUserValidator.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"CreateUserValidator.js","sourceRoot":"","sources":["../../../app/Validators/CreateUserValidator.ts"],"names":[],"mappings":";;AAAA,2EAA0E;AAG1E,MAAqB,mBAAmB;IACtC,YAAsB,GAAwB;QAAxB,QAAG,GAAH,GAAG,CAAqB;QAqBvC,WAAM,GAAG,kBAAM,CAAC,MAAM,CAAC;YAC5B,MAAM,EAAE,kBAAM,CAAC,MAAM,EAAE;YACvB,KAAK,EAAE,kBAAM,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,iBAAK,CAAC,KAAK,EAAE,EAAE,iBAAK,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAE,CAAC;YAC7F,QAAQ,EAAE,kBAAM,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,iBAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,iBAAK,CAAC,SAAS,EAAE,CAAE,CAAC;SACtE,CAAC,CAAA;QAaK,aAAQ,GAAmB;YAChC,QAAQ,EAAE,qDAAqD;YAC/D,aAAa,EAAE,gDAAgD;YAC/D,cAAc,EAAE,yBAAyB;YACzC,oBAAoB,EAAE,iDAAiD;SACxE,CAAA;IA3CgD,CAAC;CA4CnD;AA7CD,sCA6CC"}
|
||||
@@ -0,0 +1,18 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const Validator_1 = global[Symbol.for('ioc.use')]("Adonis/Core/Validator");
|
||||
class ModifEmailValidator {
|
||||
constructor(ctx) {
|
||||
this.ctx = ctx;
|
||||
this.schema = Validator_1.schema.create({
|
||||
email: Validator_1.schema.string({}, [Validator_1.rules.email(), Validator_1.rules.unique({ table: 'users', column: 'email' })])
|
||||
});
|
||||
this.messages = {
|
||||
required: 'The {{ field }} is required to modifie email',
|
||||
'email.email': 'You must enter an email in the email field',
|
||||
'email.unique': 'Email is already in use'
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.default = ModifEmailValidator;
|
||||
//# sourceMappingURL=ModifEmailValidator.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"ModifEmailValidator.js","sourceRoot":"","sources":["../../../app/Validators/ModifEmailValidator.ts"],"names":[],"mappings":";;AAAA,2EAA0E;AAG1E,MAAqB,mBAAmB;IACtC,YAAsB,GAAwB;QAAxB,QAAG,GAAH,GAAG,CAAqB;QAqBvC,WAAM,GAAG,kBAAM,CAAC,MAAM,CAAC;YAC5B,KAAK,EAAE,kBAAM,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,iBAAK,CAAC,KAAK,EAAE,EAAE,iBAAK,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAE,CAAC;SAC9F,CAAC,CAAA;QAaK,aAAQ,GAAmB;YAChC,QAAQ,EAAE,8CAA8C;YACxD,aAAa,EAAE,4CAA4C;YAC3D,cAAc,EAAE,yBAAyB;SAC1C,CAAA;IAxCgD,CAAC;CAyCnD;AA1CD,sCA0CC"}
|
||||
@@ -0,0 +1,17 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const Validator_1 = global[Symbol.for('ioc.use')]("Adonis/Core/Validator");
|
||||
class ModifPseudoValidator {
|
||||
constructor(ctx) {
|
||||
this.ctx = ctx;
|
||||
this.schema = Validator_1.schema.create({
|
||||
pseudo: Validator_1.schema.string({}, [Validator_1.rules.minLength(3)])
|
||||
});
|
||||
this.messages = {
|
||||
required: 'The {{ field }} is required to modifie pseudo',
|
||||
'pseudo.minLength': 'The pseudo must be at least 3 characters long'
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.default = ModifPseudoValidator;
|
||||
//# sourceMappingURL=ModifPseudoValidator.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"ModifPseudoValidator.js","sourceRoot":"","sources":["../../../app/Validators/ModifPseudoValidator.ts"],"names":[],"mappings":";;AAAA,2EAA0E;AAG1E,MAAqB,oBAAoB;IACvC,YAAsB,GAAwB;QAAxB,QAAG,GAAH,GAAG,CAAqB;QAqBvC,WAAM,GAAG,kBAAM,CAAC,MAAM,CAAC;YAC5B,MAAM,EAAE,kBAAM,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,iBAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;SAChD,CAAC,CAAA;QAaK,aAAQ,GAAmB;YAChC,QAAQ,EAAE,+CAA+C;YACzD,kBAAkB,EAAE,+CAA+C;SACpE,CAAA;IAvCgD,CAAC;CAwCnD;AAzCD,uCAyCC"}
|
||||
@@ -0,0 +1,41 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const authConfig = {
|
||||
guard: 'web',
|
||||
guards: {
|
||||
web: {
|
||||
driver: 'session',
|
||||
provider: {
|
||||
driver: 'lucid',
|
||||
identifierKey: 'id',
|
||||
uids: ['email'],
|
||||
model: () => Promise.resolve().then(() => __importStar(global[Symbol.for('ioc.use')]('App/Models/User'))),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
exports.default = authConfig;
|
||||
//# sourceMappingURL=auth.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../config/auth.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAkBA,MAAM,UAAU,GAAe;IAC7B,KAAK,EAAE,KAAK;IACZ,MAAM,EAAE;QAWN,GAAG,EAAE;YACH,MAAM,EAAE,SAAS;YAEjB,QAAQ,EAAE;gBASR,MAAM,EAAE,OAAO;gBAWf,aAAa,EAAE,IAAI;gBAYnB,IAAI,EAAE,CAAC,OAAO,CAAC;gBAaf,KAAK,EAAE,GAAG,EAAE,yEAAQ,iBAAiB,GAAC;aACvC;SACF;KACF;CACF,CAAA;AAED,kBAAe,UAAU,CAAA"}
|
||||
@@ -0,0 +1,31 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const Env_1 = __importDefault(global[Symbol.for('ioc.use')]("Adonis/Core/Env"));
|
||||
const Application_1 = __importDefault(global[Symbol.for('ioc.use')]("Adonis/Core/Application"));
|
||||
const databaseConfig = {
|
||||
connection: Env_1.default.get('DB_CONNECTION'),
|
||||
connections: {
|
||||
sqlite: {
|
||||
client: 'sqlite',
|
||||
connection: {
|
||||
filename: Application_1.default.tmpPath('db.sqlite3'),
|
||||
},
|
||||
pool: {
|
||||
afterCreate: (conn, cb) => {
|
||||
conn.run('PRAGMA foreign_keys=true', cb);
|
||||
}
|
||||
},
|
||||
migrations: {
|
||||
naturalSort: true,
|
||||
},
|
||||
useNullAsDefault: true,
|
||||
healthCheck: false,
|
||||
debug: false,
|
||||
},
|
||||
}
|
||||
};
|
||||
exports.default = databaseConfig;
|
||||
//# sourceMappingURL=database.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../config/database.ts"],"names":[],"mappings":";;;;;AAOA,gFAAsC;AACtC,gGAAsD;AAGtD,MAAM,cAAc,GAAmB;IAWrC,UAAU,EAAE,aAAG,CAAC,GAAG,CAAC,eAAe,CAAC;IAEpC,WAAW,EAAE;QAYX,MAAM,EAAE;YACN,MAAM,EAAE,QAAQ;YAChB,UAAU,EAAE;gBACV,QAAQ,EAAE,qBAAW,CAAC,OAAO,CAAC,YAAY,CAAC;aAC5C;YACD,IAAI,EAAE;gBACJ,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE;oBACxB,IAAI,CAAC,GAAG,CAAC,0BAA0B,EAAE,EAAE,CAAC,CAAA;gBAC1C,CAAC;aACF;YACD,UAAU,EAAE;gBACV,WAAW,EAAE,IAAI;aAClB;YACD,gBAAgB,EAAE,IAAI;YACtB,WAAW,EAAE,KAAK;YAClB,KAAK,EAAE,KAAK;SACb;KAEF;CACF,CAAA;AAED,kBAAe,cAAc,CAAA"}
|
||||
@@ -0,0 +1,3 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=auth.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../contracts/auth.ts"],"names":[],"mappings":""}
|
||||
@@ -0,0 +1 @@
|
||||
//# sourceMappingURL=index.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../database/factories/index.ts"],"names":[],"mappings":""}
|
||||
@@ -0,0 +1,29 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const Schema_1 = __importDefault(global[Symbol.for('ioc.use')]("Adonis/Lucid/Schema"));
|
||||
class default_1 extends Schema_1.default {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.tableName = 'users';
|
||||
}
|
||||
async up() {
|
||||
this.schema.createTable(this.tableName, (table) => {
|
||||
table.increments('id').primary();
|
||||
table.string('pseudo', 50).notNullable();
|
||||
table.string('email', 255).notNullable().unique();
|
||||
table.string('password', 180).notNullable();
|
||||
table.json('avatar');
|
||||
table.string('remember_me_token').nullable();
|
||||
table.timestamp('created_at', { useTz: true }).notNullable();
|
||||
table.timestamp('updated_at', { useTz: true }).notNullable();
|
||||
});
|
||||
}
|
||||
async down() {
|
||||
this.schema.dropTable(this.tableName);
|
||||
}
|
||||
}
|
||||
exports.default = default_1;
|
||||
//# sourceMappingURL=1701712115317_users.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"1701712115317_users.js","sourceRoot":"","sources":["../../../database/migrations/1701712115317_users.ts"],"names":[],"mappings":";;;;;AAAA,uFAAiD;AAEjD,eAAqB,SAAQ,gBAAU;IAAvC;;QACY,cAAS,GAAG,OAAO,CAAA;IAoB/B,CAAC;IAlBQ,KAAK,CAAC,EAAE;QACb,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;YAChD,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAA;YAEhC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAA;YACxC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,MAAM,EAAE,CAAA;YACjD,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAA;YAC3C,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YAEpB,KAAK,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,QAAQ,EAAE,CAAA;YAC5C,KAAK,CAAC,SAAS,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAA;YAC5D,KAAK,CAAC,SAAS,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAA;QAC9D,CAAC,CAAC,CAAA;IACJ,CAAC;IAEM,KAAK,CAAC,IAAI;QACf,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IACvC,CAAC;CACF;AArBD,4BAqBC"}
|
||||
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 185 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 310 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 25 KiB |
@@ -0,0 +1,46 @@
|
||||
@layout('layouts/main')
|
||||
@set('title', 'Login')
|
||||
|
||||
@section('body')
|
||||
|
||||
<div class="flex min-h-full flex-col justify-center px-6 py-12 lg:px-8">
|
||||
<div class="sm:mx-auto sm:w-full sm:max-w-sm">
|
||||
<img class="mx-auto h-10 w-auto" src="/favicon.ico">
|
||||
<h2 class="mt-10 text-center text-2xl font-bold leading-9 tracking-tight">Sign in to your account</h2>
|
||||
</div>
|
||||
|
||||
<div class="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
|
||||
|
||||
@component('components/form/form', {
|
||||
'action': '',
|
||||
'method': 'post',
|
||||
})
|
||||
@!component('components/form/field', {
|
||||
'label': 'E-mail :',
|
||||
'name': 'email',
|
||||
'type': 'email',
|
||||
'required': true,
|
||||
'placeholder': 'exemple@mail.com',
|
||||
})
|
||||
@!component('components/form/field', {
|
||||
'label': 'Mot de passe :',
|
||||
'name': 'password',
|
||||
'type': 'password',
|
||||
'required': true,
|
||||
'placeholder': 'Votre mot de passe',
|
||||
})
|
||||
@!component('components/form/button', {
|
||||
'type': 'submit',
|
||||
'text': 'Envoyer',
|
||||
'style': 'flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600',
|
||||
})
|
||||
@end
|
||||
|
||||
<p class="mt-10 text-center text-sm text-gray-500">
|
||||
Not a member?
|
||||
<a href="{{ route('signup') }}" class="font-semibold leading-6 text-indigo-600 hover:text-indigo-500">Create your account</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,60 @@
|
||||
@layout('layouts/main')
|
||||
@set('title', 'Signup')
|
||||
|
||||
@section('body')
|
||||
|
||||
<div class="flex min-h-full flex-col justify-center px-6 py-12 lg:px-8">
|
||||
<div class="sm:mx-auto sm:w-full sm:max-w-sm">
|
||||
<img class="mx-auto h-10 w-auto" src="/favicon.ico">
|
||||
<h2 class="mt-10 text-center text-2xl font-bold leading-9 tracking-tight">Create your account</h2>
|
||||
</div>
|
||||
|
||||
<div class="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
|
||||
|
||||
@component('components/form/form', {
|
||||
'action': '',
|
||||
'method': 'post',
|
||||
})
|
||||
@!component('components/form/field', {
|
||||
'label': 'Pseudo :',
|
||||
'name': 'pseudo',
|
||||
'type': 'text',
|
||||
'required': true,
|
||||
'placeholder': 'Votre nom',
|
||||
})
|
||||
@!component('components/form/field', {
|
||||
'label': 'E-mail :',
|
||||
'name': 'email',
|
||||
'type': 'email',
|
||||
'required': true,
|
||||
'placeholder': 'exemple@mail.com',
|
||||
})
|
||||
@!component('components/form/field', {
|
||||
'label': 'Mot de passe :',
|
||||
'name': 'password',
|
||||
'type': 'password',
|
||||
'required': true,
|
||||
'placeholder': 'Votre mot de passe',
|
||||
})
|
||||
@!component('components/form/field', {
|
||||
'label': 'Confirmer le mot de passe :',
|
||||
'name': 'password_confirmation',
|
||||
'type': 'password',
|
||||
'required': true,
|
||||
'placeholder': 'Votre mot de passe',
|
||||
})
|
||||
@!component('components/form/button', {
|
||||
'type': 'submit',
|
||||
'text': 'Envoyer',
|
||||
'style': 'flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600',
|
||||
})
|
||||
@end
|
||||
|
||||
<p class="mt-10 text-center text-sm text-gray-500">
|
||||
Not a member?
|
||||
<a href="{{ route('login') }}" class="font-semibold leading-6 text-indigo-600 hover:text-indigo-500">Sign in to your account</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,71 @@
|
||||
@if(flashMessages.has('success'))
|
||||
<div class="flash-success">
|
||||
{{ flashMessages.get('success') }}
|
||||
</div>
|
||||
@end
|
||||
|
||||
@if(flashMessages.has('error'))
|
||||
<div class="flash-error">
|
||||
{{ flashMessages.get('error') }}
|
||||
</div>
|
||||
@end
|
||||
|
||||
<style>
|
||||
.flash-success {
|
||||
color: #155724; /* Couleur du texte */
|
||||
background-color: #d4edda; /* Couleur de l'arrière-plan */
|
||||
border-color: #c3e6cb; /* Couleur de la bordure */
|
||||
|
||||
/* Style de la bordure */
|
||||
border: 1px solid transparent;
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.75rem 1.25rem; /* Espacement interne */
|
||||
|
||||
/* Styles supplémentaires pour le texte et les liens */
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
|
||||
/* Ombre légère */
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.flash-error {
|
||||
color: #721c24; /* Couleur du texte */
|
||||
background-color: #f8d7da; /* Couleur de l'arrière-plan */
|
||||
border-color: #f5c6cb; /* Couleur de la bordure */
|
||||
|
||||
/* Style de la bordure */
|
||||
border: 1px solid transparent;
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.75rem 1.25rem; /* Espacement interne */
|
||||
|
||||
/* Styles supplémentaires pour le texte et les liens */
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
|
||||
/* Ombre légère */
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
@if(flashMessages.has('errors.pseudo'))
|
||||
<div class="flash-error">
|
||||
{{ flashMessages.get('errors.pseudo') }}
|
||||
</div>
|
||||
@end
|
||||
|
||||
@if(flashMessages.has('errors.email'))
|
||||
<div class="flash-error">
|
||||
{{ flashMessages.get('errors.email') }}
|
||||
</div>
|
||||
@end
|
||||
|
||||
@if(flashMessages.has('errors.password'))
|
||||
<div class="flash-error">
|
||||
{{ flashMessages.get('errors.password') }}
|
||||
</div>
|
||||
@end
|
||||
@@ -0,0 +1,12 @@
|
||||
<button
|
||||
id="{{ name }}"
|
||||
name="{{ name }}"
|
||||
type="{{ type ? type : 'submit' }}"
|
||||
@if(style)
|
||||
class="{{ style }}"
|
||||
@else
|
||||
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50"
|
||||
@end
|
||||
>
|
||||
{{ text }}
|
||||
</button>
|
||||
@@ -0,0 +1,30 @@
|
||||
<div class="mb-4">
|
||||
<label for="{{ name }}" class="block text-gray-700 text-sm font-bold mb-2">{{ label }}</label>
|
||||
|
||||
@if(type === 'textarea')
|
||||
<textarea
|
||||
id="{{ name }}"
|
||||
name="{{ name }}"
|
||||
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
|
||||
@if(required)
|
||||
required
|
||||
@end
|
||||
@if(rows)
|
||||
rows="{{ rows }}"
|
||||
@end
|
||||
></textarea>
|
||||
@else
|
||||
<input
|
||||
id="{{ name }}"
|
||||
name="{{ name }}"
|
||||
type="{{ type ? type : 'text' }}"
|
||||
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
|
||||
@if(required)
|
||||
required
|
||||
@end
|
||||
@if(placeholder)
|
||||
placeholder="{{ placeholder }}"
|
||||
@end
|
||||
>
|
||||
@end
|
||||
</div>
|
||||
@@ -0,0 +1,7 @@
|
||||
<form method="{{ method }}" action="{{ action }}">
|
||||
@if(flash)
|
||||
@else
|
||||
@!component('components/flash')
|
||||
@end
|
||||
{{{ await $slots.main() }}}
|
||||
</form>
|
||||
@@ -0,0 +1,7 @@
|
||||
<li>
|
||||
<a href="{{ href }}" target="_blank">
|
||||
<div class="flex text-left items-center py-5 pl-5 my-3 w-full bg-gray-300 text-gray-600 rounded-lg font-bold hover:bg-gray-700 hover:text-gray-400 transition duration-300 ease-in-out">
|
||||
<img src="{{ img }}" alt="Logo" class="w-16 pr-4">{{ title }}
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
@@ -0,0 +1,3 @@
|
||||
<div class="h-72 w-72 m-1 transition-transform border-2 border-black rounded-xl hover:scale-125 overflow-hidden duration-500 bg-white hover:z-10">
|
||||
<a href="{{ href }}" target="_blank"><img src="{{ img }}" alt="Logo"></a>
|
||||
</div>
|
||||
@@ -0,0 +1,139 @@
|
||||
<div x-data="{ depli: false }">
|
||||
<button @click="depli = !depli" class="cursor-pointer rounded-full bg-none p-1.5 focus:ring-2 focus:ring-white">
|
||||
<span class="flex items-center">
|
||||
<svg x-cloak x-bind:class="localStorage.theme === 'dark' ? '' : 'hidden'" viewBox="0 0 24 24" fill="none"
|
||||
class="w-6 h-6">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M17.715 15.15A6.5 6.5 0 0 1 9 6.035C6.106 6.922 4 9.645 4 12.867c0 3.94 3.153 7.136 7.042 7.136 3.101 0 5.734-2.032 6.673-4.853Z"
|
||||
class="fill-sky-400/20"></path>
|
||||
<path
|
||||
d="m17.715 15.15.95.316a1 1 0 0 0-1.445-1.185l.495.869ZM9 6.035l.846.534a1 1 0 0 0-1.14-1.49L9 6.035Zm8.221 8.246a5.47 5.47 0 0 1-2.72.718v2a7.47 7.47 0 0 0 3.71-.98l-.99-1.738Zm-2.72.718A5.5 5.5 0 0 1 9 9.5H7a7.5 7.5 0 0 0 7.5 7.5v-2ZM9 9.5c0-1.079.31-2.082.845-2.93L8.153 5.5A7.47 7.47 0 0 0 7 9.5h2Zm-4 3.368C5 10.089 6.815 7.75 9.292 6.99L8.706 5.08C5.397 6.094 3 9.201 3 12.867h2Zm6.042 6.136C7.718 19.003 5 16.268 5 12.867H3c0 4.48 3.588 8.136 8.042 8.136v-2Zm5.725-4.17c-.81 2.433-3.074 4.17-5.725 4.17v2c3.552 0 6.553-2.327 7.622-5.537l-1.897-.632Z"
|
||||
class="fill-sky-500"></path>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M17 3a1 1 0 0 1 1 1 2 2 0 0 0 2 2 1 1 0 1 1 0 2 2 2 0 0 0-2 2 1 1 0 1 1-2 0 2 2 0 0 0-2-2 1 1 0 1 1 0-2 2 2 0 0 0 2-2 1 1 0 0 1 1-1Z"
|
||||
class="fill-sky-500"></path>
|
||||
</svg>
|
||||
<svg x-cloak x-bind:class="localStorage.theme === 'light' ? '' : 'hidden'" viewBox="0 0 24 24" fill="none"
|
||||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-6 h-6">
|
||||
<path d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" class="fill-sky-400/20 stroke-sky-500"></path>
|
||||
<path
|
||||
d="M12 4v1M17.66 6.344l-.828.828M20.005 12.004h-1M17.66 17.664l-.828-.828M12 20.01V19M6.34 17.664l.835-.836M3.995 12.004h1.01M6 6l.835.836"
|
||||
class="stroke-sky-500"></path>
|
||||
</svg>
|
||||
<svg x-cloak
|
||||
x-bind:class="localStorage.theme === 'systeme' && window.matchMedia('(prefers-color-scheme: dark)').matches ? '' : 'hidden'"
|
||||
viewBox="0 0 24 24" fill="none" class="w-6 h-6 ">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M17.715 15.15A6.5 6.5 0 0 1 9 6.035C6.106 6.922 4 9.645 4 12.867c0 3.94 3.153 7.136 7.042 7.136 3.101 0 5.734-2.032 6.673-4.853Z"
|
||||
class="fill-transparent"></path>
|
||||
<path
|
||||
d="m17.715 15.15.95.316a1 1 0 0 0-1.445-1.185l.495.869ZM9 6.035l.846.534a1 1 0 0 0-1.14-1.49L9 6.035Zm8.221 8.246a5.47 5.47 0 0 1-2.72.718v2a7.47 7.47 0 0 0 3.71-.98l-.99-1.738Zm-2.72.718A5.5 5.5 0 0 1 9 9.5H7a7.5 7.5 0 0 0 7.5 7.5v-2ZM9 9.5c0-1.079.31-2.082.845-2.93L8.153 5.5A7.47 7.47 0 0 0 7 9.5h2Zm-4 3.368C5 10.089 6.815 7.75 9.292 6.99L8.706 5.08C5.397 6.094 3 9.201 3 12.867h2Zm6.042 6.136C7.718 19.003 5 16.268 5 12.867H3c0 4.48 3.588 8.136 8.042 8.136v-2Zm5.725-4.17c-.81 2.433-3.074 4.17-5.725 4.17v2c3.552 0 6.553-2.327 7.622-5.537l-1.897-.632Z"
|
||||
class="fill-slate-400 dark:fill-slate-500"></path>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M17 3a1 1 0 0 1 1 1 2 2 0 0 0 2 2 1 1 0 1 1 0 2 2 2 0 0 0-2 2 1 1 0 1 1-2 0 2 2 0 0 0-2-2 1 1 0 1 1 0-2 2 2 0 0 0 2-2 1 1 0 0 1 1-1Z"
|
||||
class="fill-slate-400 dark:fill-slate-500"></path>
|
||||
</svg>
|
||||
<svg x-cloak
|
||||
x-bind:class="localStorage.theme === 'systeme' && window.matchMedia('(prefers-color-scheme: dark)').matches !== true ? '' : 'hidden'"
|
||||
viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="w-6 h-6">
|
||||
<path d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" class="stroke-slate-400 dark:stroke-slate-500"></path>
|
||||
<path
|
||||
d="M12 4v1M17.66 6.344l-.828.828M20.005 12.004h-1M17.66 17.664l-.828-.828M12 20.01V19M6.34 17.664l.835-.836M3.995 12.004h1.01M6 6l.835.836"
|
||||
class="stroke-slate-400 dark:stroke-slate-500"></path>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
<ul x-show="depli" @click.away="depli = false" x-cloak
|
||||
class="overflow-hidden absolute right-0 z-10 mt-1 rounded-md bg-white text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm"
|
||||
tabindex="-1" role="listbox" aria-labelledby="listbox-label" aria-activedescendant="listbox-option-3">
|
||||
|
||||
<li @click="
|
||||
depli = false;
|
||||
localStorage.theme = 'light';
|
||||
window.location.reload()"
|
||||
class="text-gray-900 relative cursor-default select-none py-2 pl-3 pr-9 hover:bg-gray-300" id="listbox-option-0"
|
||||
role="option">
|
||||
<div class="flex items-center">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="w-6 h-6 mr-2">
|
||||
<path d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" class="stroke-slate-400 dark:stroke-slate-500"></path>
|
||||
<path
|
||||
d="M12 4v1M17.66 6.344l-.828.828M20.005 12.004h-1M17.66 17.664l-.828-.828M12 20.01V19M6.34 17.664l.835-.836M3.995 12.004h1.01M6 6l.835.836"
|
||||
class="stroke-slate-400 dark:stroke-slate-500"></path>
|
||||
</svg>
|
||||
<!-- Selected: "font-semibold", Not Selected: "font-normal" -->
|
||||
<span class="font-normal ml-3 block truncate">Light</span>
|
||||
</div>
|
||||
|
||||
<span x-bind:class="localStorage.theme === 'light' ? '' : 'hidden'"
|
||||
class="text-indigo-600 absolute inset-y-0 right-0 flex items-center pr-4">
|
||||
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path fill-rule="evenodd"
|
||||
d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z"
|
||||
clip-rule="evenodd" />
|
||||
</svg>
|
||||
</span>
|
||||
</li>
|
||||
|
||||
<li @click="
|
||||
depli = false;
|
||||
localStorage.theme = 'dark';
|
||||
window.location.reload()"
|
||||
class="text-gray-900 relative cursor-default select-none py-2 pl-3 pr-9 hover:bg-gray-300" id="listbox-option-0"
|
||||
role="option">
|
||||
<div class="flex items-center">
|
||||
<svg viewBox="0 0 24 24" fill="none" class="w-6 h-6 mr-2">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M17.715 15.15A6.5 6.5 0 0 1 9 6.035C6.106 6.922 4 9.645 4 12.867c0 3.94 3.153 7.136 7.042 7.136 3.101 0 5.734-2.032 6.673-4.853Z"
|
||||
class="fill-transparent"></path>
|
||||
<path
|
||||
d="m17.715 15.15.95.316a1 1 0 0 0-1.445-1.185l.495.869ZM9 6.035l.846.534a1 1 0 0 0-1.14-1.49L9 6.035Zm8.221 8.246a5.47 5.47 0 0 1-2.72.718v2a7.47 7.47 0 0 0 3.71-.98l-.99-1.738Zm-2.72.718A5.5 5.5 0 0 1 9 9.5H7a7.5 7.5 0 0 0 7.5 7.5v-2ZM9 9.5c0-1.079.31-2.082.845-2.93L8.153 5.5A7.47 7.47 0 0 0 7 9.5h2Zm-4 3.368C5 10.089 6.815 7.75 9.292 6.99L8.706 5.08C5.397 6.094 3 9.201 3 12.867h2Zm6.042 6.136C7.718 19.003 5 16.268 5 12.867H3c0 4.48 3.588 8.136 8.042 8.136v-2Zm5.725-4.17c-.81 2.433-3.074 4.17-5.725 4.17v2c3.552 0 6.553-2.327 7.622-5.537l-1.897-.632Z"
|
||||
class="fill-slate-400 dark:fill-slate-500"></path>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M17 3a1 1 0 0 1 1 1 2 2 0 0 0 2 2 1 1 0 1 1 0 2 2 2 0 0 0-2 2 1 1 0 1 1-2 0 2 2 0 0 0-2-2 1 1 0 1 1 0-2 2 2 0 0 0 2-2 1 1 0 0 1 1-1Z"
|
||||
class="fill-slate-400 dark:fill-slate-500"></path>
|
||||
</svg>
|
||||
|
||||
<!-- Selected: "font-semibold", Not Selected: "font-normal" -->
|
||||
<span class="font-normal ml-3 block truncate">Dark</span>
|
||||
</div>
|
||||
|
||||
<span x-bind:class="localStorage.theme === 'dark' ? '' : 'hidden'"
|
||||
class="text-indigo-600 absolute inset-y-0 right-0 flex items-center pr-4">
|
||||
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path fill-rule="evenodd"
|
||||
d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z"
|
||||
clip-rule="evenodd" />
|
||||
</svg>
|
||||
</span>
|
||||
</li>
|
||||
|
||||
<li @click="
|
||||
depli = false;
|
||||
localStorage.theme = 'systeme';
|
||||
window.location.reload()"
|
||||
class="text-gray-900 relative cursor-default select-none py-2 pl-3 pr-9 hover:bg-gray-300" id="listbox-option-0"
|
||||
role="option">
|
||||
<div class="flex items-center">
|
||||
<svg viewBox="0 0 24 24" fill="none" class="w-6 h-6 mr-2">
|
||||
<path d="M4 6a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6Z" stroke-width="2"
|
||||
stroke-linejoin="round" class="stroke-slate-400 dark:stroke-slate-500"></path>
|
||||
<path d="M14 15c0 3 2 5 2 5H8s2-2 2-5" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="stroke-slate-400 dark:stroke-slate-500"></path>
|
||||
</svg>
|
||||
<!-- Selected: "font-semibold", Not Selected: "font-normal" -->
|
||||
<span class="font-normal ml-3 block truncate">Systeme</span>
|
||||
</div>
|
||||
|
||||
<span x-bind:class="localStorage.theme === 'systeme' ? '' : 'hidden'"
|
||||
class="text-indigo-600 absolute inset-y-0 right-0 flex items-center pr-4">
|
||||
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path fill-rule="evenodd"
|
||||
d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z"
|
||||
clip-rule="evenodd" />
|
||||
</svg>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -0,0 +1,102 @@
|
||||
@layout('layouts/main')
|
||||
@set('title', 'Compte')
|
||||
|
||||
@section('body')
|
||||
|
||||
<main class="m-24">
|
||||
|
||||
@!component('components/flash')
|
||||
|
||||
<h1 class="text-4xl font-bold mb-9">Welcome {{ auth.user.pseudo }}</h1>
|
||||
|
||||
<a href="{{ route('home') }}"
|
||||
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50"
|
||||
>return to home page</a>
|
||||
|
||||
<div>
|
||||
<h2 class="text-2xl font-bold mb-3 mt-9">Here is your personal information:</h2>
|
||||
<p>pseudo : {{ auth.user.pseudo }}</p>
|
||||
<p>email : {{ auth.user.email }}</p>
|
||||
<p>created at : <span id="formattedDate"></span></p>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const createdAt = "{{ auth.user.createdAt }}";
|
||||
const maDate = createdAt.substring(8, 10) + '/' + createdAt.substring(5, 7) + '/' + createdAt.substring(0, 4);
|
||||
document.getElementById('formattedDate').innerText = maDate;
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div id="settings">
|
||||
<h2 class="text-2xl font-bold mb-5 mt-9">You can modify your personal information:</h2>
|
||||
|
||||
@component('components/form/form', {
|
||||
'action': 'modifpseudo',
|
||||
'method': 'post',
|
||||
'flash': 'not',
|
||||
})
|
||||
@!component('components/form/field', {
|
||||
'label': 'Pseudo :',
|
||||
'name': 'pseudo',
|
||||
'type': 'text',
|
||||
'required': true,
|
||||
'placeholder': 'new pseudo',
|
||||
})
|
||||
@!component('components/form/button', {
|
||||
'type': 'submit',
|
||||
'text': 'Envoyer',
|
||||
})
|
||||
@end
|
||||
|
||||
<div class="mt-5"></div>
|
||||
|
||||
@component('components/form/form', {
|
||||
'action': 'modifemail',
|
||||
'method': 'post',
|
||||
'flash': 'not',
|
||||
})
|
||||
@!component('components/form/field', {
|
||||
'label': 'Email :',
|
||||
'name': 'email',
|
||||
'type': 'text',
|
||||
'required': true,
|
||||
'placeholder': 'new email',
|
||||
})
|
||||
@!component('components/form/button', {
|
||||
'type': 'submit',
|
||||
'text': 'Envoyer',
|
||||
})
|
||||
@end
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="mt-12">
|
||||
<img class="h-32 w-32 rounded-full" src="{{ auth.user.avatarUrl }}" alt="">
|
||||
|
||||
<form action="" method="post" enctype="multipart/form-data" class="mt-4">
|
||||
<label for="avatar">Avatar :</label>
|
||||
<input type="file" name="avatar" id="avatar">
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded mt-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50"
|
||||
>Valider
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="mt-12">
|
||||
<h2 class="text-2xl font-bold mb-3 mt-9">Delete your compte :</h2>
|
||||
<a href="{{ route('delete') }}"
|
||||
class="inline-block bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-opacity-50">
|
||||
Delete
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
</main>
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,17 @@
|
||||
@layout('layouts/main')
|
||||
@set('title', 'Arthur - Portfolio')
|
||||
|
||||
@section('body')
|
||||
|
||||
@include('partials/nav')
|
||||
@include('partials/header')
|
||||
|
||||
<main>
|
||||
@include('partials/main/about')
|
||||
@include('partials/main/projects')
|
||||
@include('partials/main/contact')
|
||||
</main>
|
||||
|
||||
@include('partials/footer')
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>{{ title }}</title>
|
||||
@entryPointStyles('app')
|
||||
@entryPointScripts('app')
|
||||
</head>
|
||||
<body class="bg-gray-100 dark:bg-slate-900 text-slate-900 dark:text-white">
|
||||
@!section('body')
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,22 @@
|
||||
<footer
|
||||
id="footer"
|
||||
class="font-semibold min-h-100 flex items-center mt-16 justify-between px-20 bg-gray-800 text-gray-400 px- h-28">
|
||||
<span>© <span id="year"></span> - Arthur Puechberty</span>
|
||||
|
||||
<a href="{{ route('terms') }}" target="_blank">Terms and Conditions</a>
|
||||
</footer>
|
||||
|
||||
|
||||
<script>
|
||||
var year = new Date().getFullYear();
|
||||
document.getElementById("year").innerHTML = year;
|
||||
|
||||
document.getElementById('myForm').addEventListener('submit', function(event) {
|
||||
var input = document.getElementById('myInput');
|
||||
if (input.value.trim() === '') {
|
||||
event.preventDefault();
|
||||
} else {
|
||||
this.action = "https://www.google.fr/search";
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,43 @@
|
||||
<header class="flex mt-36 mx-4 sm:mx-24">
|
||||
<div class="sm:mr-10">
|
||||
<h1 class="text-4xl font-bold mb-3">Hi! 👋🏻<br>I'm Arthur.</h1>
|
||||
<h2 class="text-2xl font-bold mb-3">Founder</h2>
|
||||
|
||||
<div class="pl-4 mb-3 border-l-8 border-solid border-gray-400">
|
||||
<p>I am a young Frenchman with a passion for development, I am a self-taught learner and my creativity knows no
|
||||
limits. Every pixel I edit tells a story. Passionate about transforming ideas into visually captivating
|
||||
experiences, I create projects that push the boundaries of design innovation.</p>
|
||||
</div>
|
||||
|
||||
<p class="italic text-gray-600">"In the middle of every difficulty lies opportunity."</p>
|
||||
<p class="italic text-gray-600 mb-10">Albert Einstein</p>
|
||||
|
||||
<ul>
|
||||
@!component('components/list_lien', {
|
||||
href: 'https://www.instagram.com/arthur.pbty/',
|
||||
img: '/logo insta.png',
|
||||
title: 'Instagram',
|
||||
})
|
||||
@!component('components/list_lien', {
|
||||
href: 'https://github.com/Tutur33',
|
||||
img: '/logo github.png',
|
||||
title: 'Github',
|
||||
})
|
||||
@!component('components/list_lien', {
|
||||
href: 'https://discord.gg/HxgaA44CPh',
|
||||
img: '/Logo Discord.png',
|
||||
title: 'Discord',
|
||||
})
|
||||
@!component('components/list_lien', {
|
||||
href: 'http://tuturp33.000webhostapp.com',
|
||||
img: '/other.png',
|
||||
title: 'Other...',
|
||||
})
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="ml-10 md:block hidden">
|
||||
<img src="/pp.jpg" alt="Profile picture" class="w-full max-w-5xl rounded-full">
|
||||
</div>
|
||||
</main>
|
||||
</header>
|
||||
@@ -0,0 +1,21 @@
|
||||
<section id="about" class="pt-32 mx-4 sm:mx-24">
|
||||
<h2 class="text-2xl font-bold mb-10">About</h2>
|
||||
<p>Hi ! I'm Arthur, a passionate developer based in France. My journey in the world of development is an inspiring adventure. Every line of code I write is a step toward creating unique and engaging experiences. I am driven by the desire to bring ideas to life and shape them into innovative designs.</p>
|
||||
|
||||
<h3 class="text-xl font-semibold mt-3">My background</h3>
|
||||
<p>I gained experience in web development working on various projects, ranging from front-end to back-end. I have a deep command of languages like HTML, CSS, JavaScript, and have worked with modern frameworks like Adonis with Node.js.</p>
|
||||
|
||||
<h3 class="text-xl font-semibold mt-3">My philosophy</h3>
|
||||
<p>I firmly believe that every difficulty is an opportunity to create something new and exciting. My approach is to combine functionality and aesthetics to deliver exceptional user experiences.</p>
|
||||
|
||||
<h3 class="text-xl font-semibold mt-3">My skills</h3>
|
||||
<p>Web development, web design, application development, project management.</p>
|
||||
|
||||
<h3 class="text-xl font-semibold mt-3">My interests</h3>
|
||||
<p>Outside of development, I love exploring new places, photography, and reading books about technology and creativity. And go sailing!</p>
|
||||
|
||||
<h3 class="text-xl font-semibold mt-3">My vision</h3>
|
||||
<p>My visionMy goal is to continue to learn, innovate and inspire through my projects. I want to help create a better, more engaging web for everyone.</p>
|
||||
|
||||
<p class="mt-9">Please feel free to contact me if you have any questions or would like to collaborate on an exciting project. You can reach me via [your email address] or follow me on social media using the links below.</p>
|
||||
</section>
|
||||
@@ -0,0 +1,35 @@
|
||||
<section id="contact" class="pt-32 mx-4 sm:mx-24">
|
||||
<h2 class="text-2xl font-bold mb-10">Contact</h2>
|
||||
|
||||
@component('components/form/form', {
|
||||
'action': '#',
|
||||
'method': 'post',
|
||||
})
|
||||
@!component('components/form/field', {
|
||||
'label': 'Nom :',
|
||||
'name': 'nom',
|
||||
'type': 'text',
|
||||
'required': true,
|
||||
'placeholder': 'nom',
|
||||
})
|
||||
@!component('components/form/field', {
|
||||
'label': 'E-mail :',
|
||||
'name': 'email',
|
||||
'type': 'email',
|
||||
'required': true,
|
||||
'placeholder': 'exemple@mail.com',
|
||||
})
|
||||
@!component('components/form/field', {
|
||||
'label': 'Message :',
|
||||
'name': 'message',
|
||||
'type': 'textarea',
|
||||
'rows': 4,
|
||||
'required': true,
|
||||
})
|
||||
@!component('components/form/button', {
|
||||
'type': 'submit',
|
||||
'text': 'Envoyer',
|
||||
})
|
||||
@end
|
||||
|
||||
</section>
|
||||
@@ -0,0 +1,18 @@
|
||||
<section id="projects" class="pt-32 mx-4 sm:mx-24">
|
||||
<h2 class="text-2xl font-bold mb-10">Projects</h2>
|
||||
|
||||
<div class="flex flex-wrap justify-center">
|
||||
@!component('components/project', {
|
||||
'href': '#',
|
||||
'img': '/projects/project-nups.png',
|
||||
})
|
||||
@!component('components/project', {
|
||||
'href': '#',
|
||||
'img': '/projects/my-networks.jpg',
|
||||
})
|
||||
@!component('components/project', {
|
||||
'href': '#',
|
||||
'img': '/projects/journal.avif',
|
||||
})
|
||||
</div>
|
||||
</section>
|
||||
@@ -0,0 +1,78 @@
|
||||
<nav
|
||||
x-data="{ mobileMenuOpen: false, profileMenuOpen: false }"
|
||||
class="bg-gray-800 fixed top-0 left-0 w-full z-50"
|
||||
>
|
||||
<div class="mx-auto max-w-7xl px-2 sm:px-6 lg:px-8">
|
||||
<div class="relative flex h-16 items-center justify-between">
|
||||
<!-- Mobile menu button-->
|
||||
<div class="absolute inset-y-0 left-0 flex items-center sm:hidden">
|
||||
<button
|
||||
@click="mobileMenuOpen = !mobileMenuOpen"
|
||||
type="button"
|
||||
class="relative inline-flex items-center justify-center rounded-md p-2 text-gray-400 hover:bg-gray-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white"
|
||||
>
|
||||
<!-- Mobile menu close -->
|
||||
<svg x-show="!mobileMenuOpen" class="block h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
|
||||
</svg>
|
||||
<!-- Mobile menu open -->
|
||||
<svg x-show="mobileMenuOpen" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-1 items-center justify-center sm:items-stretch sm:justify-start">
|
||||
<div class="flex flex-shrink-0 items-center">
|
||||
<img class="h-8 w-auto" src="/favicon.ico">
|
||||
</div>
|
||||
<div class="hidden sm:ml-6 sm:block">
|
||||
<div class="flex space-x-4">
|
||||
<!-- Current: "bg-gray-900 text-white", Default: "text-gray-300 hover:bg-gray-700 hover:text-white" -->
|
||||
<a href="#" class="bg-gray-900 text-white rounded-md px-3 py-2 text-sm font-medium">Accueil</a>
|
||||
<a href="#about" class="text-gray-300 hover:bg-gray-700 hover:text-white rounded-md px-3 py-2 text-sm font-medium transition duration-300">About</a>
|
||||
<a href="#projects" class="text-gray-300 hover:bg-gray-700 hover:text-white rounded-md px-3 py-2 text-sm font-medium transition duration-300">Projects</a>
|
||||
<a href="#contact" class="text-gray-300 hover:bg-gray-700 hover:text-white rounded-md px-3 py-2 text-sm font-medium transition duration-300">Contact</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="absolute inset-y-0 right-0 flex items-center pr-2 sm:static sm:inset-auto sm:ml-6 sm:pr-0">
|
||||
@!component('components/select_theme')
|
||||
|
||||
@if(auth.user)
|
||||
<!-- Profile dropdown -->
|
||||
<div @click="profileMenuOpen = !profileMenuOpen" class="relative ml-3">
|
||||
<div>
|
||||
<button type="button" class="relative flex rounded-full bg-gray-800 text-sm focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800" id="user-menu-button" aria-expanded="false" aria-haspopup="true">
|
||||
<span class="absolute -inset-1.5"></span>
|
||||
<span class="sr-only">Open user menu</span>
|
||||
<img class="h-8 w-8 rounded-full" src="{{ auth.user.avatarUrl }}" alt="">
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Dropdown menu -->
|
||||
<div x-show="profileMenuOpen" @click.away="profileMenuOpen = false" x-cloak class="absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none" role="menu" aria-orientation="vertical" aria-labelledby="user-menu-button" tabindex="-1">
|
||||
<a href="{{ route('compte') }}" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-200">Your Profile</a>
|
||||
<a href="{{ route('compte') }}#settings" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-200">Settings</a>
|
||||
<a href="{{ route('logout') }}" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-200">Sign out</a>
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<a href="{{ route('login') }}" class="mr-2 text-gray-300">Login</a>
|
||||
<a href="{{ route('signup') }}" class="text-gray-300">Signup</a>
|
||||
@end
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- Mobile menu -->
|
||||
<div x-show="mobileMenuOpen" @click.away="mobileMenuOpen = false" x-cloak class="sm:hidden space-y-1 px-2 pb-3 pt-2" id="mobile-menu">
|
||||
<a href="#" class="bg-gray-900 text-white block rounded-md px-3 py-2 text-base font-medium" aria-current="page">Accueil</a>
|
||||
<a href="#about" class="text-gray-300 hover:bg-gray-700 hover:text-white block rounded-md px-3 py-2 text-base font-medium">About</a>
|
||||
<a href="#projects" class="text-gray-300 hover:bg-gray-700 hover:text-white block rounded-md px-3 py-2 text-base font-medium">Projects</a>
|
||||
<a href="#contact" class="text-gray-300 hover:bg-gray-700 hover:text-white block rounded-md px-3 py-2 text-base font-medium">Contact</a>
|
||||
</div>
|
||||
</nav>
|
||||
@@ -0,0 +1,122 @@
|
||||
@layout('layouts/main')
|
||||
@set('title', 'Terms and Conditions')
|
||||
|
||||
@section('body')
|
||||
|
||||
<main class="mx-24 my-20">
|
||||
<h1 class="text-4xl font-bold my-10">Nups Terms and Conditions</h1>
|
||||
<p class="mb-3">Effective Date: Saturday, June 17, 2023</p>
|
||||
<p class="mb-3">Thank you for using Nups services! These Terms and Conditions govern your use of our services. Please
|
||||
read them carefully.</p>
|
||||
|
||||
<h2 class="text-2xl font-bold mt-8 mb-4">Acceptance of Terms and Conditions</h2>
|
||||
<p class="mb-3">1.1 Acceptance of Terms. By using Nups services, you agree to be bound by these Terms and Conditions.
|
||||
If you do not accept these Terms, you cannot use our services.</p>
|
||||
|
||||
<h2 class="text-2xl font-bold mt-8 mb-4">Use of Our Services</h2>
|
||||
<p class="mb-3">2.1 User Account. To use certain Nups services, you will need to create a user account. You are
|
||||
responsible for the confidentiality of your login credentials and all activities related to your account.</p>
|
||||
<p class="mb-3">2.2 Authorized Use. You agree to use Nups services in accordance with these Terms and Conditions and
|
||||
all applicable laws. You may not use our services in a way that could infringe on Nups' rights or the rights of
|
||||
others.</p>
|
||||
<p class="mb-3">2.3 Usage Restrictions. You agree not to access Nups services in an unauthorized manner, attempt to
|
||||
gain unauthorized access to accounts or computer systems, and not to disrupt or harm Nups services.</p>
|
||||
|
||||
<h2 class="text-2xl font-bold mt-8 mb-4">User Content</h2>
|
||||
<p class="mb-3">3.1 Content Ownership. You retain ownership of any content you submit, post, or display on Nups
|
||||
services. By submitting, posting, or displaying content, you grant Nups a worldwide, non-exclusive, transferable,
|
||||
free, and royalty-free license to use, reproduce, modify, adapt, publish, translate, distribute, display, and create
|
||||
derivative works from that content.</p>
|
||||
<p class="mb-3">3.2 Content Responsibility. You are responsible for the content you submit, post, or display on Nups
|
||||
services. You warrant that you have all necessary rights to publish this content, and it does not violate the rights
|
||||
of others.</p>
|
||||
<p class="mb-3">3.3 Respect for Intellectual Property Rights. You agree not to violate the intellectual property
|
||||
rights of Nups or third parties when using Nups services. You may not copy, modify, distribute, or access
|
||||
copyrighted content or other intellectual property items without authorization.</p>
|
||||
|
||||
<h2 class="text-2xl font-bold mt-8 mb-4">Intellectual Property</h2>
|
||||
<p class="mb-3">4.1 Nups' Intellectual Property Rights. All intellectual property rights related to Nups services
|
||||
(except user content) are owned by Nups. You do not acquire any ownership rights to Nups services or the content you
|
||||
access.</p>
|
||||
<p class="mb-3">4.2 Authorized Use. Subject to compliance with these Terms and Conditions, Nups grants you a limited,
|
||||
non-exclusive, revocable, non-transferable license to use Nups services for personal and non-commercial purposes.
|
||||
</p>
|
||||
|
||||
<h2 class="text-2xl font-bold mt-8 mb-4">Privacy</h2>
|
||||
<p class="mb-3">5.1 Data Collection. Nups collects and uses your information in accordance with its Privacy Policy. By
|
||||
using Nups services, you consent to the collection and use of your information as outlined in this policy.</p>
|
||||
<p class="mb-3">5.2 Cookies. Nups services may use cookies and similar technologies to facilitate your site usage and
|
||||
personalize your experience.</p>
|
||||
<p class="mb-3">5.3 Data Security. Nups implements appropriate security measures to protect your information from
|
||||
unauthorized access, disclosure, or misuse.</p>
|
||||
|
||||
<h2 class="text-2xl font-bold mt-8 mb-4">Changes to Services</h2>
|
||||
<p class="mb-3">6.1 Changes to Terms and Conditions. Nups reserves the right to modify these Terms and Conditions at
|
||||
any time. Changes take effect upon their publication on the Nups website. Your continued use of Nups services after
|
||||
such changes constitutes your acceptance of the amended Terms and Conditions.</p>
|
||||
<p class="mb-3">6.2 Changes to Services. Nups also reserves the right to modify, suspend, or temporarily or
|
||||
permanently terminate any aspect of its services, including access to certain features, without notice or liability
|
||||
to you. You acknowledge that Nups will not be liable to you or any third party for any changes, suspensions, or
|
||||
interruptions of its services.</p>
|
||||
|
||||
<h2 class="text-2xl font-bold mt-8 mb-4">Responsibilities and Limitations</h2>
|
||||
<p class="mb-3">7.1 Disclaimer of Warranties. Nups services are provided "as is" and "as available," without any
|
||||
warranties, express or implied. Nups does not guarantee the accuracy, completeness, reliability, or availability of
|
||||
the services. You use Nups services at your own risk.</p>
|
||||
<p class="mb-3">7.2 Limitation of Liability. To the fullest extent permitted by law, Nups will not be liable for
|
||||
direct, indirect, incidental, special, consequential, or punitive damages arising from your use or inability to use
|
||||
Nups services.</p>
|
||||
|
||||
<h2 class="text-2xl font-bold mt-8 mb-4">Termination</h2>
|
||||
<p class="mb-3">8.1 Termination by You. You may terminate your user account and stop using Nups services at any time.
|
||||
</p>
|
||||
<p class="mb-3">8.2 Termination by Nups. Nups reserves the right to terminate your user account and terminate your use
|
||||
of the services, in whole or in part, if you violate these Terms and Conditions or if your use of the services is
|
||||
detrimental to Nups or other users.</p>
|
||||
|
||||
<h2 class="text-2xl font-bold mt-8 mb-4">General Provisions</h2>
|
||||
<p class="mb-3">9.1 Entire Agreement. These Terms and Conditions constitute the entire agreement between you and Nups
|
||||
regarding the use of Nups services and supersede all prior or contemporaneous agreements between you and Nups.</p>
|
||||
<p class="mb-3">9.2 Applicable Law. These Terms and Conditions are governed and interpreted in accordance with the
|
||||
laws of the country where Nups is headquartered.</p>
|
||||
<p class="mb-3">9.3 Dispute Resolution. Any dispute arising from these Terms and Conditions shall be subject to the
|
||||
exclusive jurisdiction of the courts of the country where Nups is headquartered.</p>
|
||||
<p class="mb-3">9.4 Severability. If any provision of these Terms and Conditions is found to be invalid, illegal, or
|
||||
unenforceable by a competent court, such provision shall be modified to the minimum extent necessary to make it
|
||||
valid, legal, and enforceable, and the other provisions shall remain in full force.</p>
|
||||
|
||||
<h2 class="text-2xl font-bold mt-8 mb-4">Communications</h2>
|
||||
<p class="mb-3">10.1 Nups Communications. By using Nups services, you consent to receive communications from Nups,
|
||||
including announcements, updates, promotional offers, and service-related messages.</p>
|
||||
<p class="mb-3">10.2 User Communications. If you choose to contact Nups, you agree that Nups may respond to you using
|
||||
the contact information you have provided.</p>
|
||||
|
||||
<h2 class="text-2xl font-bold mt-8 mb-4">Indemnification</h2>
|
||||
<p class="mb-3">11.1 Indemnification. You agree to indemnify, defend, and hold Nups, its officers, directors,
|
||||
employees, agents, and representatives harmless from any claim, liability, loss, damage, cost, or expense, including
|
||||
reasonable attorney's fees, arising from your use of Nups services or your violation of these Terms and Conditions.
|
||||
</p>
|
||||
|
||||
<h2 class="text-2xl font-bold mt-8 mb-4">Copyright Infringement Notifications</h2>
|
||||
<p class="mb-3">12.1 Copyright Infringement Notifications. Nups respects the intellectual property rights of others.
|
||||
If you believe that any content available on Nups services violates your copyrights, please submit a copyright
|
||||
infringement notification in accordance with applicable law.</p>
|
||||
|
||||
<h2 class="text-2xl font-bold mt-8 mb-4">Severability of Provisions</h2>
|
||||
<p class="mb-3">13.1 Severability of Provisions. If any provision of these Terms and Conditions is found invalid,
|
||||
illegal, or unenforceable by a competent court, such provision shall be modified to the minimum extent necessary to
|
||||
make it valid, legal, and enforceable, and the other provisions shall remain in full force.</p>
|
||||
|
||||
<h2 class="text-2xl font-bold mt-8 mb-4">Language</h2>
|
||||
<p class="mb-3">14.1 Language of the Terms. In case of any discrepancy between the language versions of these Terms
|
||||
and Conditions, the French version shall prevail.</p>
|
||||
|
||||
<h2 class="text-2xl font-bold mt-8 mb-4">Contact Us</h2>
|
||||
<p class="mb-3">15.1 Contact. If you have questions, concerns, or comments about these Terms and Conditions, please
|
||||
contact us at the following address:</p>
|
||||
<p class="mb-3">Nups Inc.<br>Address: [Address]<br>Email: [Email]<br>Phone: [Phone Number]</p>
|
||||
|
||||
<p class="mb-3">Thank you for reading our Terms and Conditions! We hope you enjoy using Nups services.</p>
|
||||
</main>
|
||||
|
||||
@end
|
||||