From a5820eb3253042f6012f4aa6d32b74b1a24cd0ff Mon Sep 17 00:00:00 2001 From: vaibhavantil2 <88091026+vaibhavantil2@users.noreply.github.com> Date: Wed, 28 Jul 2021 21:43:21 +0530 Subject: [PATCH 01/96] Update constants.dart --- lib/constants.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/constants.dart b/lib/constants.dart index 24d627b7..d39e340a 100644 --- a/lib/constants.dart +++ b/lib/constants.dart @@ -32,7 +32,7 @@ const String kShortPassError = "Password is too short"; const String kMatchPassError = "Passwords don't match"; const String kNamelNullError = "Please Enter your name"; const String kPhoneNumberNullError = "Please Enter your phone number"; -const String kAddressNullError = "Please Enter your address"; +const String kShippingAddressNullError = "Please Enter your address"; final otpInputDecoration = InputDecoration( contentPadding: From ea05db4b8a2902257311b0946cfb967ee6e6e36f Mon Sep 17 00:00:00 2001 From: vaibhavantil2 <88091026+vaibhavantil2@users.noreply.github.com> Date: Wed, 28 Jul 2021 21:45:28 +0530 Subject: [PATCH 02/96] Update special_offers.dart --- lib/screens/home/components/special_offers.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/screens/home/components/special_offers.dart b/lib/screens/home/components/special_offers.dart index 29e1bb4d..2a6b92f0 100644 --- a/lib/screens/home/components/special_offers.dart +++ b/lib/screens/home/components/special_offers.dart @@ -6,7 +6,7 @@ import 'section_title.dart'; class SpecialOffers extends StatelessWidget { const SpecialOffers({ Key key, - }) : super(key: key); + }) : super(key: "location"); @override Widget build(BuildContext context) { From a4a8fd9d5d11d046464bcd5d738aaf238013f851 Mon Sep 17 00:00:00 2001 From: vaibhavantil2 <88091026+vaibhavantil2@users.noreply.github.com> Date: Wed, 28 Jul 2021 21:50:13 +0530 Subject: [PATCH 03/96] Update complete_profile_form.dart --- .../components/complete_profile_form.dart | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/screens/complete_profile/components/complete_profile_form.dart b/lib/screens/complete_profile/components/complete_profile_form.dart index 89165a3f..42eca938 100644 --- a/lib/screens/complete_profile/components/complete_profile_form.dart +++ b/lib/screens/complete_profile/components/complete_profile_form.dart @@ -33,6 +33,14 @@ class _CompleteProfileFormState extends State { errors.remove(error); }); } + + void addLocation({String { long , lat }}) { + if (long.len() && lat.length()) + setState(() { + longitude: long, + lattitude: lat + }); + } @override Widget build(BuildContext context) { From f0a61ba041c8870ac3aeb9a6a41d199f30686ec9 Mon Sep 17 00:00:00 2001 From: Vishesh Kumar Date: Wed, 4 Aug 2021 09:46:35 +0530 Subject: [PATCH 04/96] some added feature --- revised | 1 + 1 file changed, 1 insertion(+) create mode 160000 revised diff --git a/revised b/revised new file mode 160000 index 00000000..a14e4e2a --- /dev/null +++ b/revised @@ -0,0 +1 @@ +Subproject commit a14e4e2a15e8948c993e45f67519b38b03a4d552 From 6e11344886d1ad0996b37cf29fccaa2c59167efe Mon Sep 17 00:00:00 2001 From: Vishesh Kumar Date: Wed, 4 Aug 2021 09:59:58 +0530 Subject: [PATCH 05/96] v --- apis/.gitignore | 4 + apis/README.md | 45 + apis/app.js | 138 ++ apis/bin/www | 90 ++ apis/package.json | 27 + apis/public/images/loading.gif | Bin 0 -> 4251 bytes apis/public/images/logo.png | Bin 0 -> 62977 bytes apis/public/javascripts/app.js | 575 ++++++++ apis/public/javascripts/global.js | 75 + apis/public/javascripts/jquery.form.js | 1277 +++++++++++++++++ .../libraries/imageviewer/imageviewer.css | 226 +++ .../libraries/imageviewer/imageviewer.min.js | 8 + apis/public/libraries/lobibox/lobibox.min.css | 1 + apis/public/libraries/lobibox/lobibox.min.js | 1 + apis/public/stylesheets/style.css | 112 ++ apis/routes/index.js | 13 + apis/routes/product.js | 232 +++ apis/routes/user.js | 182 +++ apis/routes/user_product.js | 436 ++++++ apis/views/error.jade | 7 + apis/views/front/index.jade | 96 ++ apis/views/front/products-single.jade | 67 + apis/views/front/products.jade | 31 + apis/views/layout.jade | 6 + apis/views/partials/footer.jade | 40 + apis/views/partials/header.jade | 48 + apis/views/user/account.jade | 55 + apis/views/user/login.jade | 21 + apis/views/user/products-add.jade | 44 + apis/views/user/products-edit.jade | 69 + apis/views/user/products.jade | 39 + apis/views/user/register.jade | 42 + 32 files changed, 4007 insertions(+) create mode 100644 apis/.gitignore create mode 100644 apis/README.md create mode 100644 apis/app.js create mode 100644 apis/bin/www create mode 100644 apis/package.json create mode 100644 apis/public/images/loading.gif create mode 100644 apis/public/images/logo.png create mode 100644 apis/public/javascripts/app.js create mode 100644 apis/public/javascripts/global.js create mode 100644 apis/public/javascripts/jquery.form.js create mode 100644 apis/public/libraries/imageviewer/imageviewer.css create mode 100644 apis/public/libraries/imageviewer/imageviewer.min.js create mode 100644 apis/public/libraries/lobibox/lobibox.min.css create mode 100644 apis/public/libraries/lobibox/lobibox.min.js create mode 100644 apis/public/stylesheets/style.css create mode 100644 apis/routes/index.js create mode 100644 apis/routes/product.js create mode 100644 apis/routes/user.js create mode 100644 apis/routes/user_product.js create mode 100644 apis/views/error.jade create mode 100644 apis/views/front/index.jade create mode 100644 apis/views/front/products-single.jade create mode 100644 apis/views/front/products.jade create mode 100644 apis/views/layout.jade create mode 100644 apis/views/partials/footer.jade create mode 100644 apis/views/partials/header.jade create mode 100644 apis/views/user/account.jade create mode 100644 apis/views/user/login.jade create mode 100644 apis/views/user/products-add.jade create mode 100644 apis/views/user/products-edit.jade create mode 100644 apis/views/user/products.jade create mode 100644 apis/views/user/register.jade diff --git a/apis/.gitignore b/apis/.gitignore new file mode 100644 index 00000000..b8684af4 --- /dev/null +++ b/apis/.gitignore @@ -0,0 +1,4 @@ +/data/ +/node_modules/ +/public/images/uploads/ + diff --git a/apis/README.md b/apis/README.md new file mode 100644 index 00000000..ea7b0b19 --- /dev/null +++ b/apis/README.md @@ -0,0 +1,45 @@ +# Node.js E-commerce +Companies nowadays are now turning their businesses online to provide their customers a better experience. One of the most popular e-commerce website we hear often is Ebay – an American multinational company running on Node.js . A lot of folks are suggesting that Node.js might be the future of web development. Node.js is a single-threaded event-driven system that runs fast even when handling lots of requests at once, it is also simple compared to traditional multi-threaded frameworks. Node.js is well suited for real-time applications: online games, collaboration tools, chat rooms, or anything where what one user (or robot?) does with the application needs to be seen by other users immediately, without a page refresh. Using a technique known as “long-polling”, you can write an application that sends updates to the user in real time. + +## Demo +This simple e-commerce application demonstrates CRUD operations using mongoDB and a simple implementation of a session based user authentication using Passport.js. It also utilizes real time update front-end products using socket.io. This web app is 100% free to use, you can customize it to build a more sophisticated e-commerce web application. Feel free to submit an issue on GitHub if you found any bug or even better – submit a pull request. + +This web application is currently hosted on Heroku, [click here](https://nodejs-ecommerce.herokuapp.com/) to view the demo. Heroku is for testing only - it does not support file uploads as the filesystem is readonly. Although you can still test the image upload functionality but all images will automatically be deleted after a couple of minutes. + +## Modules Used ++ async ++ connect-flash ++ cookie-parser ++ crypto-md5 ++ express ++ express-session ++ jade ++ mongodb ++ monk ++ multer ++ passport ++ passport-local ++ socket.io + +## How do I get setup? +1. Create a folder called "data" in the root directory of our nodejs project. This is where MongoDB documents will be stored. +2. Go to MongoDB installation directory and under the bin folder run this command: `mongod --dbpath C:\Users\Carl\Documents\nodejs-ecommerce\data` This will start the MongoDB server. Leave this CLI instance open and start another CLI instance. +3. In the new CLI, navigate to where you pulled this repository, ex. `C:\Users\Carl\Documents\nodejs-ecommerce`, then type-in: npm install then wait till it finishes installing all the modules required to run our Node.js Web Application. +4. Once the installation is completed, type in the following command to run our Web Application: npm start Make sure to keep the CLI opened. +5. Now go to [http://127.0.0.1:3100/](http://127.0.0.1:3100/) using your favorite browser. + +## Contribution guidelines ++ ALWAYS start a new branch before making changes to the codes ++ Pull requests directly to the master branch will be ignored! ++ Use a git client, preferably Source Tree or you can use git commands from your terminal, your choice! ++ Many smaller commits are better than one large commit. Edit your file(s), if the edit does not break the code with things like syntax errors, commit. It is easier to reconcile many smaller commits than one large commit. ++ When your feature or bug fix is ready, perform a pull request and notify carl.fontanos@gmail.com that your code is ready for review on Github. + +## Author +### Carl Victor C. Fontanos ++ Website: [carlofontanos.com](http://www.carlofontanos.com) ++ Linkedin: [ph.linkedin.com/in/carlfontanos](http://ph.linkedin.com/in/carlfontanos) ++ Facebook: [facebook.com/carlo.fontanos](http://facebook.com/carlo.fontanos) ++ Twitter: [twitter.com/carlofontanos](http://twitter.com/carlofontanos) ++ Google+: [plus.google.com/u/0/107219338853998242780/about](https://plus.google.com/u/0/107219338853998242780/about) ++ GitHub: [github.com/carlo-fontanos](https://github.com/carlo-fontanos) \ No newline at end of file diff --git a/apis/app.js b/apis/app.js new file mode 100644 index 00000000..b7434753 --- /dev/null +++ b/apis/app.js @@ -0,0 +1,138 @@ +var express = require('express'); +var session = require('express-session'); +var path = require('path'); +var favicon = require('serve-favicon'); +var logger = require('morgan'); +var cookieParser = require('cookie-parser'); +var bodyParser = require('body-parser'); +var passport = require('passport'); +var LocalStrategy = require('passport-local').Strategy; +var flash = require('connect-flash'); +var md5 = require('crypto-md5'); + +/* MongoDB connection */ +var mongo = require('mongodb'); +var monk = require('monk'); +var db = monk('localhost:27017/nodetest1'); // 27017 is the default port for our MongoDB instance. +var users = db.get('users'); + +var routes = require('./routes/index'); + +var app = express(); + +/* Setup socket.io and express to run on same port (3100) */ +var server = require('http').Server(app); +var io = require('socket.io')(server); + +server.listen(3100); + +/* Realtime trigger */ +io.sockets.on('connection', function (socket) { + socket.on('send', function (data) { + io.sockets.emit('message', data); + }); +}); + +/* Define some globals that will be made accessible all through out the application */ +global.root_dir = path.resolve(__dirname); +global.uploads_dir = root_dir + '/public/images/uploads/'; + +/* view engine setup */ +app.set('views', path.join(__dirname, 'views')); +app.set('view engine', 'jade'); + +/* Make the response uncompressed */ +app.locals.pretty = true; + +/* uncomment after placing your favicon in /public */ +/* app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); */ +app.use(logger('dev')); +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({ extended: false })); +app.use(cookieParser()); +app.use(express.static(path.join(__dirname, 'public'))); +app.use(flash()); +app.use(session({ + secret: 'secret cat', + resave: true, + saveUninitialized: true +})); +app.use(passport.initialize()); +app.use(passport.session()); + +passport.use(new LocalStrategy({ + /* Define custom fields for passport */ + usernameField : 'email', + passwordField : 'password' + }, + function(email, password, done) { + /* validate email and password */ + users.findOne({email: email}, function(err, user) { + if (err) { return done(err); } + if (!user) { + return done(null, false, {message: 'Incorrect username.'}); + } + if (user.password != md5(password)) { + return done(null, false, {message: 'Incorrect password.'}); + } + /* if everything is correct, let's pass our user object to the passport.serializeUser */ + return done(null, user); + }); + } +)); + +passport.serializeUser(function(user, done) { + /* Attach to the session as req.session.passport.user = { email: 'test@test.com' } */ + /* The email key will be later used in our passport.deserializeUser function */ + done(null, user.email); +}); + +passport.deserializeUser(function(email, done) { + users.findOne({email: email}, function(err, user) { + /* The fetched "user" object will be attached to the request object as req.user */ + done(err, user); + }); +}); + + +app.use(function(req, res, next){ + req.db = db; /* Make our db accessible to our router */ + res.locals.user = req.user; /* Make our user object accessible in all our templates. */ + next(); +}); + +app.use('/', routes); + +/* catch 404 and forward to error handler */ +app.use(function(req, res, next) { + var err = new Error('Not Found'); + err.status = 404; + next(err); +}); + +/* error handlers */ + +/* development error handler */ +/* will print stacktrace */ +if (app.get('env') === 'development') { + app.use(function(err, req, res, next) { + res.status(err.status || 500); + res.render('error', { + message: err.message, + error: err + }); + }); +} + +/* production error handler */ +/* no stacktraces leaked to user */ +app.use(function(err, req, res, next) { + res.status(err.status || 500); + res.render('error', { + message: err.message, + error: {} + }); +}); + + +module.exports = app; \ No newline at end of file diff --git a/apis/bin/www b/apis/bin/www new file mode 100644 index 00000000..9e87e211 --- /dev/null +++ b/apis/bin/www @@ -0,0 +1,90 @@ +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var app = require('../app'); +var debug = require('debug')('nodetest1:server'); +var http = require('http'); + +/** + * Get port from environment and store in Express. + */ + +var port = normalizePort(process.env.PORT || '3000'); +app.set('port', port); + +/** + * Create HTTP server. + */ + +var server = http.createServer(app); + +/** + * Listen on provided port, on all network interfaces. + */ + +server.listen(port); +server.on('error', onError); +server.on('listening', onListening); + +/** + * Normalize a port into a number, string, or false. + */ + +function normalizePort(val) { + var port = parseInt(val, 10); + + if (isNaN(port)) { + // named pipe + return val; + } + + if (port >= 0) { + // port number + return port; + } + + return false; +} + +/** + * Event listener for HTTP server "error" event. + */ + +function onError(error) { + if (error.syscall !== 'listen') { + throw error; + } + + var bind = typeof port === 'string' + ? 'Pipe ' + port + : 'Port ' + port; + + // handle specific listen errors with friendly messages + switch (error.code) { + case 'EACCES': + console.error(bind + ' requires elevated privileges'); + process.exit(1); + break; + case 'EADDRINUSE': + console.error(bind + ' is already in use'); + process.exit(1); + break; + default: + throw error; + } +} + +/** + * Event listener for HTTP server "listening" event. + */ + +function onListening() { + var addr = server.address(); + var bind = typeof addr === 'string' + ? 'pipe ' + addr + : 'port ' + addr.port; + debug('Listening on ' + bind); +} diff --git a/apis/package.json b/apis/package.json new file mode 100644 index 00000000..016eefce --- /dev/null +++ b/apis/package.json @@ -0,0 +1,27 @@ +{ + "name": "nodetest1", + "version": "0.0.0", + "private": true, + "scripts": { + "start": "node ./bin/www" + }, + "dependencies": { + "async": "^2.0.1", + "body-parser": "~1.12.4", + "connect-flash": "^0.1.1", + "cookie-parser": "~1.3.5", + "crypto-md5": "^1.0.0", + "debug": "~2.2.0", + "express": "~4.12.4", + "express-session": "^1.14.1", + "jade": "~1.9.2", + "mongodb": "^1.4.4", + "monk": "^1.0.1", + "morgan": "~1.5.3", + "multer": "^1.2.0", + "passport": "^0.3.2", + "passport-local": "^1.0.0", + "serve-favicon": "~2.2.1", + "socket.io": "^1.4.8" + } +} diff --git a/apis/public/images/loading.gif b/apis/public/images/loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..cef73226b8b05b85d9c7590f877503351669962a GIT binary patch literal 4251 zcmb8yXHe7G!pHF>1V|u|LPzw{iy{Jxf`TqhL_kCV3t}h&QUU}B(o5(qA&`Jn38D9n zfYi{Wij5{J0(Qj4vbxLaJ;+_x*=OfIbMuPHWO$M9=l?q=$Br9m9duBFNJ5q&kmft< z_nxhH&abb0*j!oL?3`X-c(pk&zur6z-rro^*c^DY{`Kou$e%B%ue|0*tt<`nERL$H zsB%ET`%<6bNF)RWQQrE@*1v_oztBdGS9NK$$cW;;8&$K)Fg(zy2@vijs23-VI6O zuNKy#wN(s8^07lXT)60hvWSOS+5{QudvOK@`Ql7y-T^rwm(Hf6xT7v2{XColh(VUl zvh20l=%ls3QJ*ZXn4F5iqN&J<|IUQky zvEoVgC%`|ZEf4cOtc+AAk2VWnKHQ8^m2DwivX4AT)-?+jw8vGBjpyRL@p-C?&rZPQ zqj+|jG?(8lGN$Jw{P`^k{`D=!NCYobPj1yQq^@iS(n(qXfj}nZs09!Rl(N0H0%FOA zFMR8`X_dM1f0J!x`KK4>7fDH~u5P|-WoE8d*K-6*2r|%CfdwL$uXg75S0{$T2?XtgOg@JiaVGsJW^IJTfsSt}-b_kQ(Lg!cd6FkBAlY zZAxYqWu{rt-D;z6#HaR9659Ju9)@4d#`r`QjW;BumT0TC3Pz+>3y!judtWrCUv|3} zJ+0u|H{ZyD_aDDg+o6aVKC+*8$UN?b$vgg=%Y$!(6iHc~gIa^Bw(6HzaIX+63nML4 zj1c|;7w^g1&`{4nrm^$;e+}u$?Qo1T8a&C4?ZVCRW*9GZXZ$e=MTrSG4j*w7G|Sy^ zxeLt{7tt}!NTMiZC~)nZ?GREpdq}`S@KdmEAKB(G>yt6^=w7Ol^}-kX+%qb)E1qu} zA@;q!ke(;&YjRSo+C@RBKLd;ZQ(&u{m94b%>mVMeOR8J}nGMrdzGnuFLmOAO8-wHk z#QJZW;E5&Gu9{`8Xv8i2?J3>P&H05XMdd2V7h%@kdf81(!ISdaW@O*sZjbiPa*_iv za+(Ztb((#6U%AVt@*}jir)x?X_-gCw^!C^*&Q?`{9faQ|`}9ubJAKTXN|J1RtZB;? z78+`2?{UzH!&?D{K~kywD%`ZxR5u6z1RdKH3_p{fGhKmE$i(=@<#-;pfFb$Cm__u0 zrY2}C>3l%GIEC5N&|1ci$vRt|nB3dI9w@=Iu`2wsyYlMp7Pj0eY`STGw)l$EL_M4J zl+je!F*7>ntkU;z^?KuQrTf!_6G`|%-{&WyE4-G@O!Qm6rFXk>wYM7xpVV(h)=V9y zbG~PGLpJLvx2G*0AG)xXXz_+;x$b@)Y3kj}F^fnRJ8fMjTlodn+Ss=%N7boW&EQxf zlSI*G_&hMrenr^uBj28Bg&~df2#`X^nd)h;9FGs`Nr0$>d)681J|SHQh0mXCl(z&-ikG z#g7F~H=}!Xd}$rT2Vqw~Y!XVh6cmqsTjRA&P`G$#)rqwNB5zyBW3O&K@~kZ#>tLDZ z*BR_pu+l&TSOZ`OzyUPCXaE|UUp4`m|DxlcCgFd0kLycsI?-6!`T(b_uNn$^&Ek}g ziJY(DEcC#Xj#GCwwRyKJ(%6OM@WM4lE6+myj)XIpo!WWPHp4GisHlMimsGqIpU6df z4)i4_=q@;Y7dBd-KQ4ifq%Ub4W z;Dxa4%U$X8vRjKR%8oO&nfqa{)*C)*zPza8!*-mjI9mfh6ef(TAB*LY+(X711VS%O zN$dLy3!nMW`bw&vR=CC(h)*l%iKt?CIT?Of7#|5$`u(LZ!Z)WpN#w2@A&zcw+rjSL z_+~pb_h(iumr3!npDs?g&~;v+3ay>g{C*AJE!a`@^zJ#CkEFpihC^kZx3f@glDgt> z>r`W0O7aGCCQQG7Nr+(OH6Nqr-H1Y^m01-C;$)e$z3(rUrTlz?M4&`*O_nOD=I1HB zB{#{LKJ~pmde*hg*7J$uBKi7kry6C>F*1_u!-bW#c!X>z+l!ehGEmU4*N-k&eLdII zqCk#+yU3|Qo+|7o^UE0f*qt0eG8A5w!J+>-!)5;Flf63rXdRp>z$d^7h;I2DS_R&K zN#Jw)<^Wa-$OQI)N#G6e18BjKv~3$$B~)&mN6FV6kiVR01Mn=%y`ehaHEMna?W>Awe8ZP=kRC*%)MuxO# z_dP$RebEqP{=oyp;;jsUuAIdC{j+Z}_!cBS$XkdHy9?Bxn@mWsZ}d7}Y%#Iby2Xi!GQx#J4$ zm5f7d=gN|wb6H~J^6M3pes>U?4?6Xm&W}qLz|AOhxgZmR-am+GCcr+VN zXCvS+_EP3fojdWbXX}0!SKULle3&+Q4rBaina;y~K;m4FPG^XYW$|~P5`X!O*^)N8 zbp-;)CJ+Un0+0Y9unJZY3?RU{Z58Y!KnP}bYZ%uy?=7tZegH7oOyCyC1QQBm{_O|_ zw<86rliRfta*c9acl~DwiEp66g7BbwZxQ#3u9m2G+l-`-8y-itkJc@brk8PZVD%(5 z#NApDeJrjEYnr=pRAl71zIi~R{ElNs_94_e@Ztms4ohop3_=)?X(-%J9NybA!K?_RJ5C0+fDV$yyQdSt8L1T@O@c2y1(#H^x*C%n=VsYlu3p^?VGN) z|8-H)cKX&uEqj~F`ys?sS(Vt5U}#MFP>EjlsH+QUro5;=NGe1=xPF)%8(Vt%&>xEL z1{6Zg#C3FVm;*$&&*7s`jX5xN- zx~SW4JAhRTR`+8GE&BQ&%Ph2wD#?jzCitklUxdjWKeazq{!}DR&QzF+KYyaI_07B< zL}RuqWW!w)2O}YMCHmejf4^mk{s3j`lzp@gSO60s^R^fu156Jf0w@3kzz0}2;OReS z>eANlpDiojegXkEf5Y+P_y8#KTTs9?n((@ELdaJAk4Ms+$~x%9>jP|QNtjL@yNv`86#_-3Cv?m+S}0yf~Agv0_0f0|3EG}0;4HQ}O< zHw9&fZWN^!my{iibWOz93?z!61evU2dRvFNYhHIvUH3rBP;*i1XvM=jQ(Z~-DZ=i) z*G0o`z$Sa*C+`twJYONze2u0=i0nh31$_D>atRw*ix)DGS!(CrE@nkrtqAs+=JTAF zmG>%CJ4HxHf0BOF3^EudjgQrsBi=KxoX-?8n?1@lP8nFtkI~>+>dO3Wp6{p6y1NeK zZQR7n9UOm-$d1W6V&cYlDuA!kYWWG1$zOhWj9+)6=n5H^ zGD^CsKO(4wgO&HH+8EYF^(rpL=!+cIeWI!YVI`BCY)%wkMb?x{1@1%GpIW2^>fdsA zBS;6By7^r2it{>*LgHa4SfG0}4xSY6iz9hsQ=}2xr%u8ydzqZEib0z3CIrJOVrBS3 z!y^2zW!7Co@+Fc34|9i`Uku~G$3q94&FzqZS_BO;d7Y??SPDNGWy1aY( zl7sR>hsxqSo{c9j;B33!uu7({%yqB%WXn-3q5JrUICEx7vvrS}@O%hac{`!*SpZMp zH+rFTlX wMgAqj?KK%vhK5Y7JFW=~9z!cdt*Slig>u<>ChRnAt)6Rgy<6FWg+a9c4Lf0%)&Kwi literal 0 HcmV?d00001 diff --git a/apis/public/images/logo.png b/apis/public/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..ac39411b65cfa3465b225e3fde989657bf0ac56f GIT binary patch literal 62977 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

SBe#Dq%tp1EHVGub}~VbS^=qgk@uJ_nf3 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

' + + '' + + '' + + '' + + '
' + ); + }); + } + wave_box('off'); + } + }); + } + + /** + * Submit new product data via ajax using jquery form plugin + */ + this.add_post = function(){ + $('.create-product').ajaxForm({ + beforeSubmit: function(arr, $form, options) { + var proceed = true; + + $('input.required').each(function(index) { + if($(this).val() == ''){ + Lobibox.notify('error', {msg: 'Please fill-up the required fields', size: 'mini', sound: false}); + proceed = false; + return false; + } + }); + + return proceed; + }, + beforeSerialize: function() { + update_ckeditor_instances(); + }, + success: function(response, textStatus, xhr, form) { + if(response == 0){ + Lobibox.notify('error', {msg: 'Failed to create the product, please try again', size: 'mini', sound: false}); + } else { + window.location.href = '/user/products/edit/' + response + '?status=created'; + } + } + }); + + if(get_url_value('status') == 'created'){ + Lobibox.notify('success', {msg: 'Item successfully created, you may continue editing this product.', size: 'mini', sound: false}); + } + } + + /** + * Handles the deletion of a single post + */ + this.delete_post = function(){ + $('body').on('click', '.delete-product', function(e) { + e.preventDefault(); + + var item = $(this); + var data = { + item_id: item.attr('item_id') + } + + $.ajax({ + url: '/user/products/delete', + type: 'POST', + data: data, + success: function (response) { + if(response == 0){ + Lobibox.notify('error', {msg: 'Delete failed, please try again', size: 'mini', sound: false}); + } else if(response == 1){ + item.parents('tr').css('background', '#add9ff').fadeOut('fast'); + Lobibox.notify('success', {msg: 'Deleted Successfully', size: 'mini', sound: false}); + } + } + }); + }); + + } + + /** + * Sends an AJAX request to delete the image. + */ + this.unset_image = function() { + $('body').on('click', '.unset-image', function(e) { + e.preventDefault(); + wave_box('on'); + + var parent_element = $(this).parent(); + + $.ajax({ + url: '/user/products/image/unset', + type: 'POST', + data: { + 'action': 'unset-image', + 'item_id': $('.item-edit').attr('id').split('-')[1], + 'image': this.id.split('-')[1] + }, + success: function (response) { + if(response.status == 1){ + parent_element.fadeOut(); + Lobibox.notify('success', {msg: response.message, size: 'mini', sound: false}); + } else { + Lobibox.notify('error', {msg: response.message, size: 'mini', sound: false}); + } + wave_box('off'); + } + }); + }); + } + + /** + * Sends an AJAX request to set the image as featured. + */ + this.set_featured_image = function() { + $('body').on('click', '.set-featured-image', function(e) { + e.preventDefault(); + wave_box('on'); + + var _this = this; + var image_featured_id = this.id.split('-')[1]; + + if( $(this).hasClass('glyphicon-star') ){ + Lobibox.notify('error', {msg: 'The image you clicked is already the featured image.', size: 'mini', sound: false}); + wave_box('off'); + + } else { + $.ajax({ + url: '/user/products/image/set-featured', + type: 'POST', + data: { + 'action': 'set-featured-image', + 'item_id': $('.item-edit').attr('id').split('-')[1], + 'image': image_featured_id + }, + datatype: 'JSON', + success: function (response) { + if(response.status == 1){ + if($('.images-section').find('span.glyphicon-star').switchClass('glyphicon-star', 'glyphicon-star-empty').removeAttr('style')){ + $(_this).switchClass('glyphicon-star-empty', 'glyphicon-star').css('color', '#E4C317'); + Lobibox.notify('success', {msg: response.message, size: 'mini', sound: false}); + } + } else { + Lobibox.notify('error', {msg: response.message, size: 'mini', sound: false}); + } + + socket.emit('send', { message: { featured: image_featured_id, id: $('.item-edit').attr('id').split('-')[1] } } ); + + wave_box('off'); + } + }); + } + }); + } + + /** + * Load ImageViewer plugin + */ + this.get_imageviewer_image = function(images, curImageIdx, viewer, curSpan){ + var imgObj = images[curImageIdx - 1]; + + viewer.load(imgObj.small, imgObj.big); + curSpan.html(curImageIdx); + } + + /** + * Initialize imageviewer plugin + */ + this.set_imageviewer = function() { + + _this = this; + + if($('input.item-images-json').length){ + var images = JSON.parse($('input.item-images-json').val()); + var curImageIdx = 1, + total = images.length; + var wrapper = $('.imageviewer'), + curSpan = wrapper.find('.current'); + var viewer = ImageViewer(wrapper.find('.image-container')); + + /* display total count */ + wrapper.find('.total').html(total); + + wrapper.find('.next').click(function(){ + curImageIdx++; + if(curImageIdx > total) curImageIdx = 1; + _this.get_imageviewer_image(images, curImageIdx, viewer, curSpan); + }); + + wrapper.find('.prev').click(function(){ + curImageIdx--; + if(curImageIdx < 1) curImageIdx = total; + _this.get_imageviewer_image(images, curImageIdx, viewer, curSpan); + }); + + /* initially show image */ + _this.get_imageviewer_image(images, curImageIdx, viewer, curSpan); + } + } + }, + + User: function() { + this.init = function() { + this.create_account(); + this.update_account(); + } + + this.create_account = function(){ + $('.create-account').ajaxForm({ + beforeSerialize: function() { + wave_box('on'); + }, + success: function(response, textStatus, xhr, form) { + if(response.status == 0){ + Lobibox.notify('error', {msg: response.message, size: 'mini', sound: false}); + } + + if(response.status == 1){ + window.location.href = '/user/account'; + } + + wave_box('off'); + } + }); + } + + this.update_account = function(){ + $('.update-account').ajaxForm({ + beforeSerialize: function() { + update_ckeditor_instances(); + wave_box('on'); + }, + success: function(response, textStatus, xhr, form) { + if(response.status == 0){ + Lobibox.notify('error', {msg: response.message, size: 'mini', sound: false}); + } + + if(response.status == 1){ + Lobibox.notify('success', {msg: response.message, size: 'mini', sound: false}); + } + + wave_box('off'); + } + }); + } + + }, + + /** + * Global + */ + Global: function () { + + /** + * This method contains the list of functions that needs to be loaded + * when the "Global" object is instantiated. + * + */ + this.init = function() { + this.set_ckeditor(); + this.set_datepicker(); + } + + /** + * Load CKEditor plugin + */ + this.set_ckeditor = function() { + if($('#ck-editor-area').length){ + load_ckeditor('ck-editor-area', 300); + } + } + + /** + * Load CKEditor plugin + */ + this.set_datepicker = function() { + if('.datepicker'){ + $('.datepicker').datetimepicker({ + format: 'YYYY-MM-DD HH:mm:ss' + }); + } + } + } +} + +/** + * When the document has been loaded... + * + */ +jQuery(document).ready( function () { + + global = new app.Global(); /* Instantiate the Global Class */ + global.init(); /* Load Global class methods */ + + posts = new app.Posts(); /* Instantiate the Posts Class */ + posts.init(); /* Load Posts class methods */ + + user = new app.User(); /* Instantiate the User Class */ + user.init(); /* Load User class methods */ + + /* Update item data via real time */ + socket.on('message', function(data) { + var data = data.message; + var item_id = '.item-' + data.id; + for (var key in data) { + if (data.hasOwnProperty(key)) { + if(key == 'featured'){ + $(item_id + ' .item-featured').attr('src', '/images/uploads/' + data[key]); + } else if(key == 'price') { + $(item_id + ' .item-price').html(parseFloat(data[key]).toFixed(2)); + } else { + $(item_id + ' .item-' + key).html(data[key]); + } + } + } + }); + +}); \ No newline at end of file diff --git a/apis/public/javascripts/global.js b/apis/public/javascripts/global.js new file mode 100644 index 00000000..aed50331 --- /dev/null +++ b/apis/public/javascripts/global.js @@ -0,0 +1,75 @@ +/** + * Helper function to get append the loading image to message container when submitting via AJAX + * + * @param textarea, height + */ +function load_ckeditor( textarea, height ) { + CKEDITOR.config.allowedContent = true; + CKEDITOR.replace( textarea, { + toolbar: null, + toolbarGroups: null, + height: height + }); +} + +/** + * Helper function to command CKEditor to update the instancnes before performing the AJAX call. + * This will populate the hidden textfields with the proper values coming from the CKEditor + * + */ +function update_ckeditor_instances() { + for ( instance in CKEDITOR.instances ) { + CKEDITOR.instances[instance].updateElement(); + } +} + +/** + * Provides a nice wave animation effect + * + */ +function wave_box_animate(){ + if( $('.wave-box-effect').length ){ + jQuery( ".wave-box-effect" ).css( "left", "0px" ); + jQuery( ".wave-box-effect" ).animate( { 'left':"99%" }, 1000, wave_box_animate ); + } +} + +function wave_box(option) { + if($('.wave-box-wrapper').length){ + if(option == 'on'){ + if($(".wave-box-wrapper .wave-box").html('
').show()){ + wave_box_animate(); + } + } else if(option == 'off') { + $(".wave-box-wrapper .wave-box").html('').fadeOut(); + } + } +} + +/* Used for getting the parameter of a URL */ +function get_url_value(variable) { + var query = window.location.search.substring(1); + var vars = query.split("&"); + for (var i=0;i").get(0).files !== undefined; +feature.formdata = window.FormData !== undefined; + +var hasProp = !!$.fn.prop; + +// attr2 uses prop when it can but checks the return type for +// an expected string. this accounts for the case where a form +// contains inputs with names like "action" or "method"; in those +// cases "prop" returns the element +$.fn.attr2 = function() { + if ( ! hasProp ) { + return this.attr.apply(this, arguments); + } + var val = this.prop.apply(this, arguments); + if ( ( val && val.jquery ) || typeof val === 'string' ) { + return val; + } + return this.attr.apply(this, arguments); +}; + +/** + * ajaxSubmit() provides a mechanism for immediately submitting + * an HTML form using AJAX. + */ +$.fn.ajaxSubmit = function(options) { + /*jshint scripturl:true */ + + // fast fail if nothing selected (http://dev.jquery.com/ticket/2752) + if (!this.length) { + log('ajaxSubmit: skipping submit process - no element selected'); + return this; + } + + var method, action, url, $form = this; + + if (typeof options == 'function') { + options = { success: options }; + } + else if ( options === undefined ) { + options = {}; + } + + method = options.type || this.attr2('method'); + action = options.url || this.attr2('action'); + + url = (typeof action === 'string') ? $.trim(action) : ''; + url = url || window.location.href || ''; + if (url) { + // clean url (don't include hash vaue) + url = (url.match(/^([^#]+)/)||[])[1]; + } + + options = $.extend(true, { + url: url, + success: $.ajaxSettings.success, + type: method || $.ajaxSettings.type, + iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank' + }, options); + + // hook for manipulating the form data before it is extracted; + // convenient for use with rich editors like tinyMCE or FCKEditor + var veto = {}; + this.trigger('form-pre-serialize', [this, options, veto]); + if (veto.veto) { + log('ajaxSubmit: submit vetoed via form-pre-serialize trigger'); + return this; + } + + // provide opportunity to alter form data before it is serialized + if (options.beforeSerialize && options.beforeSerialize(this, options) === false) { + log('ajaxSubmit: submit aborted via beforeSerialize callback'); + return this; + } + + var traditional = options.traditional; + if ( traditional === undefined ) { + traditional = $.ajaxSettings.traditional; + } + + var elements = []; + var qx, a = this.formToArray(options.semantic, elements); + if (options.data) { + options.extraData = options.data; + qx = $.param(options.data, traditional); + } + + // give pre-submit callback an opportunity to abort the submit + if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) { + log('ajaxSubmit: submit aborted via beforeSubmit callback'); + return this; + } + + // fire vetoable 'validate' event + this.trigger('form-submit-validate', [a, this, options, veto]); + if (veto.veto) { + log('ajaxSubmit: submit vetoed via form-submit-validate trigger'); + return this; + } + + var q = $.param(a, traditional); + if (qx) { + q = ( q ? (q + '&' + qx) : qx ); + } + if (options.type.toUpperCase() == 'GET') { + options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q; + options.data = null; // data is null for 'get' + } + else { + options.data = q; // data is the query string for 'post' + } + + var callbacks = []; + if (options.resetForm) { + callbacks.push(function() { $form.resetForm(); }); + } + if (options.clearForm) { + callbacks.push(function() { $form.clearForm(options.includeHidden); }); + } + + // perform a load on the target only if dataType is not provided + if (!options.dataType && options.target) { + var oldSuccess = options.success || function(){}; + callbacks.push(function(data) { + var fn = options.replaceTarget ? 'replaceWith' : 'html'; + $(options.target)[fn](data).each(oldSuccess, arguments); + }); + } + else if (options.success) { + callbacks.push(options.success); + } + + options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg + var context = options.context || this ; // jQuery 1.4+ supports scope context + for (var i=0, max=callbacks.length; i < max; i++) { + callbacks[i].apply(context, [data, status, xhr || $form, $form]); + } + }; + + if (options.error) { + var oldError = options.error; + options.error = function(xhr, status, error) { + var context = options.context || this; + oldError.apply(context, [xhr, status, error, $form]); + }; + } + + if (options.complete) { + var oldComplete = options.complete; + options.complete = function(xhr, status) { + var context = options.context || this; + oldComplete.apply(context, [xhr, status, $form]); + }; + } + + // are there files to upload? + + // [value] (issue #113), also see comment: + // https://github.com/malsup/form/commit/588306aedba1de01388032d5f42a60159eea9228#commitcomment-2180219 + var fileInputs = $('input[type=file]:enabled', this).filter(function() { return $(this).val() !== ''; }); + + var hasFileInputs = fileInputs.length > 0; + var mp = 'multipart/form-data'; + var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp); + + var fileAPI = feature.fileapi && feature.formdata; + log("fileAPI :" + fileAPI); + var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI; + + var jqxhr; + + // options.iframe allows user to force iframe mode + // 06-NOV-09: now defaulting to iframe mode if file input is detected + if (options.iframe !== false && (options.iframe || shouldUseFrame)) { + // hack to fix Safari hang (thanks to Tim Molendijk for this) + // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d + if (options.closeKeepAlive) { + $.get(options.closeKeepAlive, function() { + jqxhr = fileUploadIframe(a); + }); + } + else { + jqxhr = fileUploadIframe(a); + } + } + else if ((hasFileInputs || multipart) && fileAPI) { + jqxhr = fileUploadXhr(a); + } + else { + jqxhr = $.ajax(options); + } + + $form.removeData('jqxhr').data('jqxhr', jqxhr); + + // clear element array + for (var k=0; k < elements.length; k++) { + elements[k] = null; + } + + // fire 'notify' event + this.trigger('form-submit-notify', [this, options]); + return this; + + // utility fn for deep serialization + function deepSerialize(extraData){ + var serialized = $.param(extraData, options.traditional).split('&'); + var len = serialized.length; + var result = []; + var i, part; + for (i=0; i < len; i++) { + // #252; undo param space replacement + serialized[i] = serialized[i].replace(/\+/g,' '); + part = serialized[i].split('='); + // #278; use array instead of object storage, favoring array serializations + result.push([decodeURIComponent(part[0]), decodeURIComponent(part[1])]); + } + return result; + } + + // XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz) + function fileUploadXhr(a) { + var formdata = new FormData(); + + for (var i=0; i < a.length; i++) { + formdata.append(a[i].name, a[i].value); + } + + if (options.extraData) { + var serializedData = deepSerialize(options.extraData); + for (i=0; i < serializedData.length; i++) { + if (serializedData[i]) { + formdata.append(serializedData[i][0], serializedData[i][1]); + } + } + } + + options.data = null; + + var s = $.extend(true, {}, $.ajaxSettings, options, { + contentType: false, + processData: false, + cache: false, + type: method || 'POST' + }); + + if (options.uploadProgress) { + // workaround because jqXHR does not expose upload property + s.xhr = function() { + var xhr = $.ajaxSettings.xhr(); + if (xhr.upload) { + xhr.upload.addEventListener('progress', function(event) { + var percent = 0; + var position = event.loaded || event.position; /*event.position is deprecated*/ + var total = event.total; + if (event.lengthComputable) { + percent = Math.ceil(position / total * 100); + } + options.uploadProgress(event, position, total, percent); + }, false); + } + return xhr; + }; + } + + s.data = null; + var beforeSend = s.beforeSend; + s.beforeSend = function(xhr, o) { + //Send FormData() provided by user + if (options.formData) { + o.data = options.formData; + } + else { + o.data = formdata; + } + if(beforeSend) { + beforeSend.call(this, xhr, o); + } + }; + return $.ajax(s); + } + + // private function for handling file uploads (hat tip to YAHOO!) + function fileUploadIframe(a) { + var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle; + var deferred = $.Deferred(); + + // #341 + deferred.abort = function(status) { + xhr.abort(status); + }; + + if (a) { + // ensure that every serialized input is still enabled + for (i=0; i < elements.length; i++) { + el = $(elements[i]); + if ( hasProp ) { + el.prop('disabled', false); + } + else { + el.removeAttr('disabled'); + } + } + } + + s = $.extend(true, {}, $.ajaxSettings, options); + s.context = s.context || s; + id = 'jqFormIO' + (new Date().getTime()); + if (s.iframeTarget) { + $io = $(s.iframeTarget); + n = $io.attr2('name'); + if (!n) { + $io.attr2('name', id); + } + else { + id = n; + } + } + else { + $io = $('